匿名数据集
获取匿名数据集的快速方法
什么是匿名化?
我们今天收集的许多数据可以很容易地与个人、家庭或实体联系起来。然而,使用数据而不注意保护数据所有者的身份会导致许多问题和潜在的诉讼。数据匿名化简单地说,就是确保我们不能通过查看数据来判断实际的数据所有者。
作者照片
在开始任何命名练习之前,理解数据集的最终目标是很重要的。数据集的目标告诉我们如何使用它。例如,为分析项目准备数据集不同于为应用程序开发准备数据。为了简单起见,我们将关注分析性和非分析性目标。
本文将带我们了解不同类型的数据集和几种匿名化它们的方法。它还讨论了如何在分析环境中应用匿名化方法,并以一些我们可能需要匿名化的数据集的实际例子结束。
数据集的类型
常用的数据集有三种类型。具有组合键的数据集、具有非组合键的数据集和具有可重复 id 的数据集。包含从数据集组件创建的键的数据集(组合键)应该与键与任何列都没有关系的数据集(非组合键)区别对待。同样,具有重复键的数据集应该与具有唯一 id 的数据集区别对待。
示例 1:
两种表格
示例 1 中的表 A 有一个由表中的一些列组成的键,而表 B 是一个键与其余数据无关的示例。匿名表 A 应该不同于 b。
可能使用复合 id 的真实情况包括但不限于
一些医院系统使用客户年龄和姓名的组合来创建标识符。
公司电子邮件通常是员工姓名的某种组合
车辆或贷款编号通常基于一些车辆或贷款信息等
重复的 id 通常出现在收集和存储使用或访问数据的系统中。也就是说,有几种方法可以匿名化这些数据集。
匿名化数据集的主要方法
1。更换钥匙
在某些情况下,移除密钥并用随机数替换它就足够了。但是,必须注意适应数据的组成。
简单情况:非复合唯一键
在上面给出的简单例子中,请注意该表与示例 1 中的表 B 相同。在这里,密钥可以很容易地用随机数或身份生成器来替换。
C oding 提示:您可以使用 spark 中的‘单调递增 id’函数或 python 中的‘uuid’包或 R 中的‘ids’包或 SQL 中的‘NewId’函数来创建一个随机 id。
数据完整性案例:重复键
考虑到表的组成,我们可能会发现 id 是重复的,但重复的是我们想要保留的有效数据点。在这种情况下,我们希望每次都用相同的随机数替换相同的密钥。
C oding 提示:为此,I)创建一个具有唯一 id 的子集 ii)添加一个具有随机数的新列,然后 iii)将其加入到初始数据集中,iv)删除旧的键列。这里可以使用“删除”、“连接”和“选择”或“子集”功能。
表 E 和表 D
2.当移除识别键还不够时
如果用随机密钥替换密钥还不够,我们可以采取其他方法,例如:
2A。哈希:
一、散列一些列:
散列是使用固定长度代码来表示数据列的最广为人知的方法之一。哈希将数据转换为固定大小的字母数字或数字代码,这种代码不容易被逆转(如果有逆转的话)。请注意,这不同于加密。
哈希的两个关键特性:
这在技术上是可行的,但实际上是不可能逆转的,即使是最简单的散列,即你可以从 A 到散列(A ),但不能从散列(A)到 A。
散列相同的值每次应该提供相同的输出,并且没有两个输入应该得到相同的散列输出(冲突)。
Coding 提示:在大多数语言中,‘sha’或‘hash’函数可以实现这个功能,例如:spark、hive 中的‘sha()’或 python 中的 hash 或 R(需要 hash 包)或 SQL 中的‘hash bytes’。还记得数据完整性案例吗?是的,我们可以用这种方法来代替 ids!😄
二。创建基于密钥的代码:
这是一个类似于哈希的概念。假设您有一个数据集,其中的键是一些列的组合。出于某种原因,您决定不使用哈希函数,而是希望对数据进行系统化和可重复的处理,并允许您使用相同的键连接到其他数据集。常见的方法是从键列(和/或复合列)中删除或替换特定位置的字符。
使用实施例 1 中的表 A:
表 A
删除密钥的第三个字符:
或者替换密钥的第三个字符:
在表 H 中,所有第三个字符都被替换为“m”。你可以变得更复杂,做一个映射,第一行得到一个 m,然后下一行得到一个 n …等等。
当处理这样的数据集时,我建议也进行部分编码、散列或删除其中一个组合列。
C oding 提示:这里可以使用 python 中的切片或者 spark、hive、R 或者 SQL 中的’ substring ‘(或者’ substr ')函数。
2B。随机混合:
在某些情况下,我们可能需要与实际数据集具有相同结构和特征的数据。假设我们需要开发一个应用程序,但是团队还没有开发出一种安全的数据传输方式。一个快速的解决方案是使用现有数据创建假数据,而不是暂停开发直到解决这个问题。
一种方法是随机混合每一列中的数据。
Ex —回想一下示例 1 中的复合表?
我们可以这样混合它:
简单混合
二世。现在你可能会说,如果有人知道键是一些列的组合,他仍然可以从这些信息中猜出正确的数据所有者。有两件事你可以快速完成:
a)创建完全伪造的数据行并添加到数据集,在混合之前删除一些实际的数据行。
现在我们混合:
丢弃的数据混合
b)替换某些列中的某些字符。
你想对有意义的列这样做。替换城市或语言列中的字符(如果有)实际上不起作用,因为这可能被视为输入错误,很容易纠正。此外,在数字列中用字符串替换数字可能会导致错误,因为这会改变列的数据类型或被视为坏数据。这可能会误导应用程序开发或分析产品开发。
我们可以这样修改上面的表 I:
在上表中,请注意在某些情况下会添加一个字符或完全替换一个名称。表 J 是 II a)和 II b)的组合
3.为分析或类似工作准备数据:
有很多时候,我们需要数据进行分析或一些类似的目的,但不能分享敏感信息。
I .与上述情况类似,我们可以混合数据,并在混合前替换或添加行。然而,随机混合或改变数据可能会导致趋势丢失,而这在数据分析中是很重要的。如果您决定混合或添加数据,必须注意保持相同的模式、频率、范围、数据结构等,以免扭曲数据模式或引入异常值。在这种情况下,组内混合可以工作,尽管这稍微复杂一些。
二。散列和混合也是可行的,但是如上所述,如果组被认为对分析项目很重要,则必须注意在组内混合。
三。聚合数据—对于某些数据,我们可以创建聚合,这些聚合可以提供分析用途的信息,但不够精细,无法追溯到数据所有者。例如,代替电话号码,我们可以使用区号或创建区域标志。
四。一种首选的方法是对数据集中的敏感信息进行哈希运算,并根据其意义进行分组。通过对列进行分组和散列,可以在隐藏实际数据的同时维护模式。
对于所有必须匿名的数据集,重要的是删除数据中任何唯一的和/或个人可识别的信息,如电话号码、社会安全号码、银行号码等。唯一数据的一个例子是,关于汽车的数据集中有一辆粉红色的野马,关于房屋的数据集中有一座紫色的大厦,关于畸形的数据集中有一个象人,等等。
现实生活中的例子
一些需要匿名化数据的情况包括但不限于-
1.使用数据创建数据产品。构建机器学习模型、开发应用程序、呈现汇总统计数据等
2.同一公司但不同项目组的人员,其中一个组不允许查看数据
3.创建公共数据集
4.需要数据,但由于数据传输安全或隐私原因而无法共享实际数据的任何情况。
5.GDPR 或隐私法适用的任何情况
感谢您的阅读!😃
匿名数据集第 2 部分
从数据中删除电子邮件、敏感号码、伊正和地址
由作者使用 Unsplash 的照片创建(照片由:Tarun Anand、Franck V .、宝琳娜·加西亚、Markus Spiske 提供)
回来的时候,一个同事让我帮忙匿名处理一些数据。他提供的数据集激起了我的兴趣,并引出了我们今天要讨论的一些内容。
当我们谈到匿名数据时,我们指的是删除个人信息或任何可用于识别或跟踪个人的信息。在某些情况下,这被称为个人身份信息(pii)。这些信息可能包括但不限于:姓名、电子邮件、地址、电话号码、地理位置、社会保险号(ssn)、车辆识别号、账号、身份证号、信用卡信息等
本文将向您介绍如何构建 python 查询,从数据集中提取这些项目。就范围而言,本文档采用正则表达式方法来识别和替换数据集或字符串中的电子邮件、敏感数字、vin 和地址。
电子邮件
电子邮件非常普遍,几乎在每个应用程序中都有使用。事实上,当大多数人发出电子邮件时,他们并没有意识到他们发出了大量的信息。虽然电子邮件可能对数据科学家有用,但为了赚钱或其他需要消除数据身份的目的,我们可能需要删除电子邮件数据,同时保留其余数据。使用简单的正则表达式函数可以帮助解决这个问题。
例如:
电子邮件示例 1,由作者创建
Note that in this case the regex is case insensitive. However, a space in the email such as *snubholic @yahoo.com* would change the results.
Code: *re.findall("\S+@\S+", dn)*
要用“xxx”替换字符串 dn 中出现的所有电子邮件地址,我们可以如下操作:
电子邮件示例 2,由作者创建
*Code: dn2 = re.sub(“\S+@\S+”, r’xxx’, dn)*
敏感数字
本节展示了如何从数据帧中移除敏感数字。这里使用的 regex 函数不包括电话号码、ssn、经度和纬度坐标、一些邮政编码等。
演示:~
*Creating the data set:**dat = {‘number’: [“1231451469”, “42.2”, “123 145 1469”, “123.145.1469”, “(123) 145.1469”, “(123) 145 1469”, “(123) 145–1469”, “123–145–1469”, “+1(123) 145–1469 “, “1234567890999111”, “123HELLO56”, “-123”, “04/04/1998”, “it’s015–96–0342 you know my number call me”, “+123–145–1469”, “48236–123”, “I live close to (42.293564, -83.638916)”], ‘name’: [“MJ”, “Hermann”, “Mary”, “Jane”, “Smith”, “John”, “Jeremy”,”Sam”, “CJ”, “JJ”, “Mimi”, “Yule”, “Siri”, “Mima”, “ilian”,”Alfred”, “Grid”]}**df = pd.DataFrame(dat)*
Df 看起来像:
作者创建的数字数据框架
要查找上述所有敏感号码,请使用下面的函数:
def patterner(x):
mm = re.findall(r'[\+\(]?\d[\d .\-\(\)]{6,}', x)
return mm
要查找数据帧中的所有敏感数字并替换为 xxx,我们可以创建如下函数:
def patterner2(x):
mm = re.sub(r'[\+\(]?\d[\d .\-\(\)]{6,}',r'xxx', x)
return mm
要在数据集中创建一个新的列来替换所有敏感的数字,我们可以这样做:
df['number2']= df['number'].apply(patterner2)
这个查询的输出如下:
替换列中的数字,由作者创建
关于上面的函数需要注意一些事情:它删除了数据帧中的所有电话号码格式——国内和国际,并删除了 latlong 坐标以及第 14 行(Mima 的行)上的 ssn 和第 15 行(Alfred 的行)上的 zipcode。但是,它不会删除小于 6 位的数字,但会删除所有大于 5 位的数字。
车辆识别号:
T 车辆识别号很敏感,因为一旦你买了一辆车,这个车辆识别号就和你的个人联系在一起了。当绑定到适当的数据时,它不仅可以用来跟踪你的移动模式,还可以跟踪你的家庭地址、注册和电话号码等。随着美国等发达国家越来越多的人(和组织)获得车辆以方便移动,并作为 covid 时代的一种预防措施,vin 号码变得越来越重要。我们可以从数据中删除 vin 号,如下所示。
演示:~
stringphrase = "hi, do you know whose is vin 1FA6P8CFGL5386177 and whose is MNAAXXMAWALE27598?"m = re.findall('[A-Za-z0-9]{1}[A-Za-z]{2}[A-Za-z0-9]{9}[\d+]{5}', stringphrase)
x= re.sub('[A-Za-z0-9]{1}[A-Za-z]{2}[A-Za-z0-9]{9}[\d+]{5}', r'xxx', stringphrase)
这给出了输出:
*“hi, do you know whose is vin xxx and whose is xxx?”*
地址:
对于许多企业来说,从数据帧中移除或替换地址是相当棘手的问题。这里,通过将正则表达式与列表理解和一些映射函数结合起来,我们能够从数据集中识别和删除几种不同的地址格式。
演示:~
创建您的数据集
data = {'addresstext': ["I had an ok experience and I live close by 2000 Vernier rd grosse pointe woods MI 48236\. I had a good time at 2999 vernier", "I used to know someone who lived at, 2025 magna rd grosse pointe MI 48237 they loved it and told us many cool stories about the lake","I liked their services 22000 moross rd, detroit MI 48236", "lots of diverse life experiences at 6233 orlina st, apt 1001, detroit MI 48217", "2013 1st ambonstreet", "245e ousterkade 9", "oh yeah, I had a great time at 20225 Liverni a really really good time" ], 'name': ["MJ", "Mary", "Killian", "Liroy","Alex", "Sammy", "Peter"]}
dff = pd.DataFrame(data)
创建的数据集如下所示:
示例地址数据框,由作者创建
要识别地址,我们可以使用以下两个函数:艾迪和艾迪 2。第一个函数 addy 标识了地址,但也添加了额外的文本。第二个函数 addy2 清除 addy 并限制被标识为地址一部分的附加数据。
def addy(x): ###returns addresses with a few extra characters
mi = re.findall(r'\d+?[A-Za-z\-\,\ \d+]{4,}', x)
return mi
第二个功能:
def addy2(w):
gm = re.sub(r'(\d\w+\b)\s+\b(\w+)\b\s+(\w+)\s+\b\D+$', r'\1 \2 \3', w)
return gm
将这两个函数应用于数据集,如下所示:
dff['addressadd'] = dff['addresstext'].apply(addy)
dff['addressadd2']= dff['addressadd'].map(lambda x:[addy2(i) for i in x])
这会产生输出:
应用作者创建的 addy 函数
要替换数据集中的地址,使用下面的查询(注意列表理解和映射函数的使用消除了显式创建循环的需要并提高了速度) :
dff['testing2'] = dff.apply(lambda x: reduce(lambda a,r: a.replace(*r), list(product(x['addressadd2'], ['xxx'])), x['addresstext']), axis=1)
输出如下所示:
由作者创建的地址被替换时的输出
注意,这些查询正确地替换了 dataframe 列中的所有地址,包括第一行中的两个地址。有一些小的数据丢失,因为一些额外的字也被替换为地址的一部分。在第 1 行中,“他们爱”和第 6 行中的“a”被捕获,并随后被替换为地址的一部分。然而,在这些大计划中,这些都是次要的,特别是考虑到留下地址的选择,以及潜在的诉讼或侵犯个人隐私。
把所有的东西放在一起
A 在分别查看了每种类型的 pii 后,您可以将开发的功能转换成一个转换,并将其一次性应用于数据集。请记住,如果在具有数字列的数据集中包含要删除敏感数字的部分,则在应用函数或转换之前,应该排除数字列。同样在这里,我们创建了几个新列。当实现上面的查询时,不要忘记删除最终数据集中的初始列,以便它真正不包含个人身份数据。最后,在处理大型数据集时,直接使用 pyspark(或 scala)或将数据帧转换为 pyspark 数据帧并执行转换可能会更容易(您可能需要将大多数函数创建为 UDF)。
**鸣谢 **
这项工作是在 python 的https://regex101.com、excel 和 jupyter 笔记本的帮助下完成的。它还参考了几篇 stackoverflow 文章,包括https://stack overflow . com/questions/34773317/python-pandas-removal-substring-using-other-column
Python 中的匿名函数
Lambda 表达式简介
定义函数是软件编程的一个重要部分。定义简单函数的一种方法是匿名使用 lambda 表达式。例如,计算单个表达式的函数,如加法,可以用 lambda 表达式替换。在这篇文章中,我们将讨论如何使用 lambda 表达式定义匿名/内联函数。
我们开始吧!
假设我们有一个单行函数,它返回两个输入整数值之间的差:
def subtract(x, y):
return x - y
如果我们用 x= 10 和 y =7 调用这个函数,并打印我们得到的返回值:
print("Difference:",subtract(10, 7))
由于这是一个简单的函数,它只对单个表达式“x-y”求值,因此可以用 lambda 表达式替换它:
subtract_value = lambda x, y: x - y
lambda 表达式包含关键字“lambda”、输入 x 和 y、一个冒号以及我们想要计算的表达式。如果我们回头看看我们最初的函数定义:
def subtract(x, y):
return x - y
我们看到这些表达看起来非常相似。最大的区别是在我们的 lambda 表达式中没有“def”关键字、“return”关键字和函数名。
让我们打印 x = 10 和 y = 7 作为输入的函数:
print("Difference:",subtract_value(10,7))
您可以将 lambda 表达式应用于更有趣的操作,如排序和数据简化。让我们考虑下面的编程语言创造者列表:
names = [**'**Guido van Rossum**',** 'Bjarne Stroustrup', 'James Gosling', 'Rasmus Lerdorf']
我们可以使用’ sorted()'方法和 lambda 表达式,按照姓氏的字母顺序返回列表:
print(sorted(names, key = lambda name : name.split()[-1].lower()))
值得注意的是 lambda 表达式的局限性。因为我们只能计算单个表达式,所以像迭代、异常处理和条件这样的特性是无法指定的。尽管如此,lambda 表达式在代替评估单个表达式的单行函数时非常有用。
我们可以考虑的另一件事是如何在匿名函数中捕获变量。让我们定义一个整数 x = 5,并定义一个匿名函数,将 x 和另一个输入整数 y 相加:
x = 5
add = lambda y: x + y
让我们调用 y = 24 的函数:
print("Addition:", add(24))
如果我们改变下一行中 x 的值并调用我们的函数,我们得到:
x = 5
add = lambda y: x + y
print("Addition:", add(24))
x= 10
print("Addition:", add(24))
因为 lambda 表达式中使用的 x 是运行时绑定的自由变量,所以 x 的值是运行时的值。要让匿名函数在定义时捕获一个值,在本例中捕获 x = 5,我们必须包含 x 作为默认值:
x = 5
add = lambda y,x=x: x + y
print("Addition:", add(24))
x= 10
print("Addition:", add(24))
我们得到了我们想要的行为。我就讲到这里,但是我鼓励你自己去研究代码。
结论
总之,在这篇文章中,我们讨论了如何使用 lambda 表达式在 python 中定义匿名函数。如果您有一个包含许多计算单行表达式的函数的 python 脚本,那么用 lambda 表达式替换这些函数通常会更容易。此外,我们讨论了如何在 lambda 表达式中设置默认值,这允许我们在定义时捕获变量的值。如果你希望学习更多关于匿名函数的知识,我推荐你阅读 Python 食谱。我希望你觉得这篇文章有趣/有用。这篇文章中的代码可以在 GitHub 上找到。感谢您的阅读!
面向 2022 年的深度学习硬件指南
理解大数据
什么是 GPU?为什么重要?我需要多少内存?你想更好地理解这些术语,甚至把它们用上吗?请继续阅读。
图片: Pixabay
这是截至 2022 年 3 月 1 日的最新数据
介绍
这是你们都知道和喜爱的旧版本的一个巨大的修改版本。本指南的几乎每一部分都被彻底重写。最初的指南已经更新了 6 年,所以我决定是时候基本上(几乎)从头开始写了。这一次,我试着让它变得更全面、更普遍。我会继续更新这个,但我也想确保我的读者能理解这个话题,即使有一天我不再这样做了。
所以,你决定要买一台专门训练机器学习模型的机器。或者,更确切地说,你在一个本指南的术语不断被抛出的组织中工作,你只是想知道更多关于它们的含义。这不是一个非常简单的话题,所以我决定写这篇指南。您可以从不同的角度讨论这些术语,本指南将解决其中一个问题。
本文中各种表格的注释;我制作了它们,获得所有需要的信息花了一些时间。没有我的同意,请不要使用它们。
我是谁?
我是 Nir Ben-Zvi,是一名深度学习研究人员,也是一名硬件爱好者,从初中时代开始,我会在朋友们打篮球的时候拆电脑(我也试过,很快又回到了硬件上)。
在过去的几年里,我为一些组织提供关于构建深度学习机器的建议,并最终决定将这些知识纳入指南。
今天,我是一名计算机视觉顾问,与各种公司和初创公司合作开发基于图像的产品。本指南的许多知识来自为我的各种客户构建深度学习机器的决策。
我如何维护本指南
我最初是在大约 5-6 年前用希伯来语写的这个指南(但是谁在数呢),从那时起我就确保它是最新的。这次我决定重写大部分内容。请注意,有些部分几乎没有改变一点,原因是我觉得他们仍然是相关的。
令人惊讶的是,在过去的 4-5 年里,硬件几乎没有什么变化。例如,在 2018 年 11 月至 2020 年 4 月期间,NVIDIA 根本没有更新其消费显卡(GeForce)系列*。另一方面,英特尔已经更新了两次桌面产品线*。另一件最终相当反气候的事情是 amd 新的消费级和服务器级处理器系列(我已经看到这是一个非常微妙的话题,所以以后会有更多的讨论)。**
那么,为什么这份指南仍然有意义,是什么让它在一年后仍然有意义呢?嗯,首先,我会试着不时更新它,事实上,当一些特殊的事情影响到市场时,我会这样做。此外,我还删除了一些我认为过于针对特定代的部分。例如,英特尔刚刚宣布了其第 12 代硅胶,但我不太确定这是否会使构建 DL 机器与构建基于当前第 11 代的机器有太大不同,所以我试图使 CPU 讨论更加通用。如果几代人之间发生了剧烈的变化,我自然会做出必要的改变。
GPU-笔记本电脑超出了本文的范围。图片:维基媒体
关于 GPU 笔记本电脑的几句话
****本指南不是用来选择笔记本电脑的。在我看来,深度学习笔记本电脑已经不存在了,至少对于计算机视觉任务来说是这样。现代的 DL 型号太大了,不适合这种笔记本电脑,这种笔记本电脑通常配有针对游戏玩家的显卡(或者偶尔用于渲染任务或给 Photoshop 增添一些活力)。即使是最强大的游戏笔记本电脑,那些通常被称为“台式机替代品”(或 DTR)的笔记本电脑,也可能不足以在合理的时间范围内实际训练(甚至微调)基于 ResNet-101 的模型。
在谷歌提供基于 T4 和 P100 的 Colab 环境的日子里,我看不出有什么理由为 DL 购买一台强大的笔记本电脑。
你仍然希望你的笔记本电脑坚固;至少 16GB 内存和 4 个以上内核。但是它主要是一台运行终端到远程实例的机器。那些 16GBs 是给 Chrome 用的。顺便说一下,我用的是苹果电脑。
如果你还想要一台同样便携的 GPU 笔记本电脑,我会买刀片。讨论结束。你可以寻找其他面向游戏的钻机,但这将是我最喜欢的选择。
便携显卡呢?
我承认我对这个领域不太熟悉,也没见过那些被用于非游戏目的的。它仍然是一个单一的显卡,从长远来看可能是不够的。
那么,这本指南里有什么呢?
首先,我将选项分成四个“类别”:
- 一台带有单个 GPU 的台式机
- 一台与#1 相同的机器,但是具有 2 个 GPU 或者支持将来增加一个 GPU
- 带有 4 个 GPU 的“重型”DL 台式机
- 一台带有 8 个 GPU 的机架安装型机器(请参阅更多注释;您可能不会自己构建这一个)
机架安装通常安装在服务器机房中。图片: Pixabay
在 8 GPU 机器和机架安装上
拥有 8 个以上 GPU 的机器可能最好从一些 OEM (Lambda Labs、Supermicro、HP、Gigabyte 等)购买预组装的。)因为建造它们很快就会变得昂贵和复杂,它们的维护也是如此。请注意,它们可能还需要在您的办公室中建立一个适度的服务器机房,并配备适当的冷却设备(以及用于所述冷却的故障安全设备)。这些东西非常非常吵,不应该放在人类附近。
理论上你可以自己建造一个——我见过这样做的——但在我看来,这里的金钱收益太微不足道了。我要指出的是,我们位于以色列,很难获得此类机器的部件(特别是 PSU 和机箱),需要从美国运输。由于这是英文指南,我会注意到,也许在你居住的地方建造这样一台机器会更容易、更便宜(如果你经常访问新蛋的话)。
不建立一个额外的原因是原始设备制造商通常会给你一个非常需要的现场支持包。
因为最终这些很少是自建的,所以我不打算进一步讨论它们。
我要哪个显卡?
TL;博士:你想要一个 3080/3080ti/3090 。它们属于 NVIDIA 的系列(或一代)30 的卡。
不过,没那么快;由于持续的芯片短缺,实际上很难拿到卡。出于本指南的考虑,我假设你能,但实际上你可能不得不用可用的而不是最好的来建造你的装备。
图片:由英伟达提供
NVIDIA 系列 3 讨论
NVIDIA 基于安培的系列 30 现在已经上市大约一年了,3060ti 和 3080ti 随后出现。让我们首先浏览这些部分,比较我认为重要的事情:
消费级卡与 A100 级数据中心的对比。图片:我。
好吧,我迷路了!
那么我们这里有什么?最低端的部分,3070 应该以旧型号市场价的一半带来 2080ti 同等的性能。对于某些训练任务来说,较低的内存容量可能是一个问题。对于一个相当小的价格升级,3080 将提供明显更高的性能——NVIDIA 声称某些任务的两倍。
3080
在 NVIDIA 最初发布后,当与 3090 抗衡时,3080 似乎是一个物有所值的选择(在 MSRP)。只需 700 美元,您就可以将 2080ti 的性能提高近一倍。它确实提供了更少的内存,但更高的速度应该仍然使它伟大。我的旧观点没有改变。
3080ti
当最初宣布系列-30 时,大多数 DL 爱好者不得不在 3080 和 3090 之间进行选择。两者都有很多优点,并且在价格上有很大的差异,这使得它们非常适合不同的用户。此后,NVIDIA 宣布了介于两者之间且备受期待的 3080ti 。“ti”部分是否像前几代产品一样做出了显而易见的选择?我很快就会谈到这一点。
与 3090 相比,3080ti 基本上以略低的价格给几乎相同的性能,而内存只有一半。官方的 3090 规格要求您的主板上有三个插槽,但这一点自发布以来有所改变,使得这一限制不太相关。
3090
就性价比而言,3090 应该是这一系列中最有趣的一款,但 350W 的功率有点挑战功率。当我最初写它的时候,我提到过双槽解决方案将会被强制采用。从那时起,技嘉,华硕和 EVGA 已经这样做了。我仍然反对购买(可能更便宜的)三插槽解决方案。350 瓦的功率仍然使使用这一部分很困难,但硬件支持在过去一年中有所改善。
记忆
时代错误是可怕的;一年前我写道:
“24GB 内存很有意思,但如果在同一个机箱中安装 5 个 3090 而不是 8 个 3080,我认为系统制造商会选择后者,更便宜的卡。”
嗯,对于 3090 的两个插槽鼓风机解决方案,如果钱不是问题,您现在可以将 8 个 3090 放在同一个机箱中,在单台机器中获得令人难以置信的 192 GB GPU 内存。
另一件令人兴奋的事情是为更昂贵的变体选择的极快的 GDDR6X(从 GDDR6 开始)。这些是 3080、3080ti 和 3090。
我无法从新闻稿中获得内存带宽的数字,但这些卡将有惊人的快速内存接口,这可能会超过它们与 20 系列卡相比更低的内存大小。这听起来可能违反直觉,但如果卡可以从其内存中获取数据并足够快地处理它,那么对于类似的吞吐量(如果我们是为了训练或推断而测量每秒图像数),它需要的内存就可以更少。
那么我应该买哪一个呢?
先做最重要的事情;如果你想为了学习如何深度学习而买便宜的东西,我会买 3070。但这不是本指南的内容。
对于一家初创公司(或更大的公司)来说,为其渴望权力的研究人员构建严肃的深度学习机器,我会尽可能多地塞满 3090。双内存数字字面上的意思是你可以用一半的时间训练模型,这简直是物有所值。这也适用于构建单 GPU 或双 GPU 机器的人。如果你以此为生,3090 是一个惊人的价值。“只”少 300 美元,我看不出 3080 蒂适合那里。双内存是一件大的事情。
然而,如果 3080ti 已经超出了您的预算,那么它也是物有所值。
最后,最初的 3080 的建议零售价为 699 美元,对于那些最大限度地利用预算购买单个 GPU 平台的人来说,仍然是一个非常高的性价比——明白了吧。会很棒的。
从另一个角度来看。如果您选择 3080ti 还是 3080,并且预算不多,那么 3080 绝对物超所值,非常适合您。
MSRP 制定计划,上帝笑了
我所有的建议都是基于 MSRPss 的,MSRP 有时会根据供求关系变化很多,尤其是在全球芯片短缺持续的时候。例如,如果 3090 的价格接近 2000 美元,那么 3080ti 马上就变得物超所值了。
我应该从 20 系列升级吗?
不。不像从帕斯卡到图灵(1080ti 到 2080ti)的跳跃——这一代,至少在目前,提供了一个适度的减速带。三年前从 1080tis 移动到 2080tis 获得了非常好的性能提升,这是由于使用了混合精度训练或 FP16 推理——这要归功于他们新颖的 TensorCores。这一次,我们获得了通常的大约 30%的性能提升(当然,这取决于任务),但除此之外别无其他。
在这一点上,我看不出有什么理由去买一个基于 2080ti 的系统,除非你能买到非常便宜的东西。
我们来谈谈显卡
卡代和系列
NVIDIA 通常区分消费级卡(称为 GeForce)和针对专业用户的专业卡。
向夸德罗和特斯拉说再见
以前 NVIDIA 对 pro 级卡还有一个区分;Quadro 负责计算机图形任务,Tesla 负责深度学习。随着第 30 代的出现,这种情况发生了变化,NVIDIA 简单地使用前缀“A”来表示我们正在处理专业级卡(如 A100)。曾经的 Quadro 现在被简单地称为“Nvidia 工作站 GPU”,Teslas 是“Nvidia 数据中心 GPU”。面向 GCI 的 GPU 使用 Axxxx 名称,如 A6000,而深度学习的 GPU 使用 Axx 和 Axxx。
那么我们为什么不仅仅讨论那些“专业级”的 GPU 呢?嗯,它们非常昂贵,而且对于开发(和学习)来说也不太合理。数据中心目标卡的额定运行 24/7 多年,具有全球内部支持,有时还提供被动冷却解决方案——所有这些都是您肯定希望在您的最终产品中实现的,也是您没有看到 GCP 或 AWS 使用 GeForce 硬件的原因。嗯,这一点以及英伟达的 EULA 明确禁止这一事实。
目前这两个系列的性能领导者是 GeForce 3090 和 A100。还有 A40 和最近公布的 A10 、 A16 和 A30 。虽然 A16 和 A40 不是为 DL 机器设计的,但 A10 和 A30 很有趣,我将在下面讨论它们。
面向推理的卡片
一个直到最近才出现的美丽新世界。目前(不出所料)由英伟达(NVIDIA)用他们的 T4(图灵的“T”,意思是老一代)卡主导,有残缺的训练能力,但完全合理的推理速度。它仍然比 GeForce 2080ti/3080/3080ti/3090 贵,但如果你需要专业级的快速推理(被动冷却、强大的国际支持、鲁棒性等),它是唯一的游戏。如果这不是你需要的东西,你现在可能已经知道了。对于 30 系列,NVIDIA 用 A30 取代了这一部分,但这不是一个确切的替代,因为它的价格更高,相对来说更强大。请参见下表,并将它们与其相关的顶级数据中心产品进行比较。
英伟达的推断——针对的部分。图片:我。
图形/渲染卡
如上所述,“NVIDIA 工作站 GPU”(之前为 Quadro)是 Nvidia 的渲染目标级别的卡。理论上,它们不应该属于这里,但它们有时可以在更昂贵的数据中心卡(以前是特斯拉)和消费卡之间提供一个最佳性价比点。与消费级 GeForce 卡相比,它们对高强度负载的适应能力更强,但成本仍低于数据中心部件。我对它们不太熟悉,但我要指出,出于培训目的,我看不出有什么吸引力。对于推理任务,它们可以提供一个可行的替代方案,但同样,如果你去那里,你需要完全理解你在做什么,因为它们被“调整”以在渲染图形时达到最佳性能,而不是运行深度学习模型。
对于这一代(安培),NVIDIA 已经宣布了几个部分——最初是 A40 和 A6000,接下来是 A4000 和 A5000。看起来 A40 和 A6000 在规格上几乎是一样的,最大的区别是 A40 将是被动冷却的。
除此之外,没有发布太多信息,但它们的目标是需要强大 GPU 处理渲染任务的数据中心,而不是 DL。如果它们最终比同等的 A100 更便宜,将来可能会有更多的理由讨论它们。下表将它们与上一代类似卡以及面向 DL 的同类产品 V100 和 A100 进行了比较。
NVIDIA 的面向渲染的显卡。图片:我。
FP16 和张量核心
从之前的(20)系列卡开始,NVIDIA 的所有部件都有 TensorCores 以及 CUDA 核心。这些内核是用来运行单精度推理的。当最初引入时,这只是爆炸,因为性能似乎没有受到影响,而推理速度有时会翻倍(训练也变得更快)。
从第 30 代开始,这在某种程度上是一种规范,NVIDIA 在其营销材料中甚至没有提到不同张量核心的数量。
接下来的几代(图灵,有点像“第 20 代半”)也增加了对 8 位和 4 位推理的支持,但这些都需要仔细校准。
关于 INT8 的更多信息
INT8 是一个复杂的问题,您的组织内部应该非常了解它。与迁移到几乎没有麻烦的半精度/FP16 不同,迁移到 INT8 可能会严重影响性能,应该将其视为一项新的研究任务,而不是一个快速的加速工程解决方案。
NVLINK 将卡片连接在一起
NVLINK 是 NVIDIA 的一种硬件协议,允许连接他们的卡(两张或更多)并形成一个统一的内存池,这使他们可以在不“通过”CPU 内存的情况下进行通信。这实际上加速了许多计算,因此非常酷,但不幸的是,对于连接两个以上卡的 GeForce (ala 消费级)卡,它也被禁用。如果你只有两张卡,你仍然可以使用它(在消费级版本中称为 still 但如果超过两张,我真的不会介意。你的基于 2080ti/30XX 的 8 GPU 机器不支持 NVLINK,这有多糟糕?不太糟糕。对于需要 GPU 之间快速连接的应用(考虑同步批处理规范化),这可能会提供不错的速度提升,但对于一般用途,您可以不使用它。
云实例是构建实例的替代方法,但是要知道成本。图片: Pixabay
那么云实例呢?
谷歌和亚马逊都在其云中提供 A100 和 V100 部件。微软还在一些地方添加了 V100 实例,但实际上在让人们在 8-GPU 设置中使用它们方面有极大的限制(我不再使用 Azure,如果有变化,请告诉我)。谷歌还提供 P100 basd 实例,这些实例非常物有所值。谷歌也提供他们自己的 TPU,速度非常快,如果你使用 TensorFlow,这是一个很好的解决方案。
尽管如此,快速数学将表明,如果你打算在大量 GPU 上训练模型,并且经常这样做(这意味着这样的机器几乎在所有时间都将被充分利用)——从长远来看,购买顶级训练机器将更具成本效益。相反,如果您可能偶尔而不是一直训练模型,那么云实例肯定是更明智的选择。**
或许最好的办法是尝试使用云实例几周,然后再做决定。另请注意,即使拥有大量内部实例的组织偶尔也会在高峰期使用基于云的实例。还需要注意的是,本地实例意味着您需要一个非常精通维护的人。损失 2-3 名数据科学家一天的工作可能比购买深度学习机器节省的钱要多得多。**
CPU 和 PCI-E 通道上的一点
我需要多少个 CPU 内核?什么是 PCI-E 通道?
既然我们已经完成了图形卡的主题,我们可以转移到下一个部分——制造中的训练机器——中央处理器,或 CPU。
GPU 通常需要 16 个 PCI-Express 通道。PCI-Express 是 CPU 和 GPU 之间的主要连接。幸运的是,英特尔的大多数现成器件都支持这一点。
它连接两张通常会出现问题的卡,因为这需要 32 条通道——这是大多数廉价消费卡所缺乏的。转向 4 卡,我们将完全依赖昂贵的至强系列(针对服务器)卡。
我真的需要那么多车道吗?
好吧,简单回答?不完全是。尽管我刚才说过,我们实际上通常可以用每个 GPU 个通道来进行训练和推理。据说,速度极其受限的任务(如低延迟交易)肯定需要所有 16 条受支持的通道。另请注意,如果您的卡支持的话,前面提到的 NVLINK 也消除了一些这种要求。
作为一般的经验法则,每个 GPU 不要低于 8 个通道。另一个需要注意的重要事项是需要 PCI-E 通道的其他部分,例如基于超高速 NMVe 的 SSD 驱动器。
图片:维基媒体
现在让我们选择一个 CPU
英特尔酷睿系列 CPU
在本指南的第一次迭代中,英特尔以极具竞争力的价格提供了一些具有 28、40 和 44 个 PCI-E 通道的部件(这是第 8 代)。从那时起,更多代进入市场(12,阿尔德湖,刚刚宣布),这些零件已被更昂贵的面向发烧友的“X 系列”零件所取代。反过来,这些部件现在是深度学习硬件的卫冕冠军,因为它们的速度和 PCI-E 通道丰富。
如果您计划构建一台具有单个 GPU 的机器,第 11 代的大多数 i7/i9 部件都有 20 个通道,将非常适合您。第 10 代仍然物有所值,它们都有 16 条车道。
如果你需要更多的 cowbell(或通道),X 指定的部分有 48 个通道——足以容纳 4 个 GPU,每个 8 个通道,甚至还剩下一些能量用于一对基于 NVMe 的 SSD 驱动器。不过,到目前为止,它们只存在于第 10 代(冰湖)。最便宜的部分, 10900X ,拥有 48 个通道和 10 个内核,随后是 12、16 和 18 个内核部分。英特尔似乎无意为其当前的第 11 代(Rocket Lake)CPU 引入 X 系列。
英特尔 Ice Lake CPUs 也为在 CPU 上运行深度模型提供了广泛的硬件支持。如果你对这类东西感兴趣,我建议你多读一些,了解它是否有益。
在继续之前,请确保您完全了解 CPU 插座是如何工作的。我假设读者在这个阶段知道这意味着什么。x 系列部件使用更复杂的插座排列,这反过来需要更昂贵的主板。因为我们一开始就在讨论非常昂贵的机器,所以这在实践中不会有很大的不同。
至强系列 CPU
前面简单提到的至强CPU 是英特尔用于服务器和数据中心的系列 CPU(与用于台式机的内核不同)。由于讨论之外的各种原因,它们更贵。除此之外,它们还支持多 CPU 设置,这反过来可以为您可能想要和需要的每个 GPU 提供完整的 16 个 PCI-E 通道(因为您可以组合几个 CPU 及其各自的通道)。同样重要的是,这些 CPU 的弹性要高得多,类似于 NVIDIA 的数据中心系列 GPU 和消费级 GeForce GPUs,应该能够长期承受更高的计算负载。
同样值得注意的是,至强处理器会因为几个不同的原因增加系统的整体价格:
- Xeons 需要 ECC(纠错码)内存,比较贵。
- 支持 Xeons 的内存、主板和机箱往往更贵(但更有弹性)。
- 与同等的酷睿 i7/i9 部件相比,至强部件本身要贵得多。
尽管如此,如果您关心在 24/7 极端负载下运行的多 CPU 系统,您可能需要基于至强的机器。基于至强处理器的机器在过去实际上更受欢迎,但从那时起,英特尔添加了前面提到的 i9-X CPU,具有大量 PCI-E 通道,可满足大多数消费者/发烧友的需求。在继续之前,我必须承认,我在构建基于至强处理器的机器方面知识不足,无法推荐一款物有所值的 CPU。最重要的是,至强处理器有许多不同的选择。比消费级 CPU 多得多。大幅提高其价格的一个因素是支持的 CPU 连接数(一些支持双 CPU 系统,而另一些支持 4 和 8 CPU 配置,成本明显更高)。它们还具有更大的缓存大小,这实际上对各种任务有很大帮助,但这也超出了本文的范围。**
如果您正在构建一台 8 GPU 的机器,那么您将 100%依赖至强处理器来实现 8×8 PCI-E 通道(=总共 64 个)。除非你去 AMD,那是。
那么,AMD 在哪里?
这是自 2018 年 11 月以来没有更新过的,将保持原样。请不要杀我,AMD 粉丝们!
更新:现在确实好像有人在用 AMD CPUs 造 DL 机;如果需求上升,我可能真的要重写这个。
好吧,AMD 提供的东西——至少在纸面上——本应该彻底改变整个行业,但实际上并没有。那就是它的 Epyc 命名的面向服务器的 CPU 系列,以及附带的名为 Threadripper 的消费级部件。这两者分别提供了 128 和 64 个 PCI-E 通道——有可能将英特尔打得落花流水。这些处理器还拥有大量内核(多达 32 个),比同等价格的英特尔 CPU 多得多。那么,为什么这些产品没有风靡市场呢?
- 较低的单 CPU 性能(对于许多不喜欢并行化的任务来说很重要)
- 人们通常比较保守,不愿意采用不太受欢迎的公司的新硬件(在服务器领域;消费者领域,尤其是游戏玩家,对 AMD 非常熟悉,多年来一直如此)
- 大量科学计算库大量使用 MKL 加速;只有英特尔在其 CPU 中支持的东西;一个显著的例子是 OpenCV
- PCI-Express 通道丰富并不像听起来那么简单,我将解释:
因此,不像英特尔在 CPU 和主板之间有自己的专有连接,AMD 的 CPU 实际上使用 PCI-Express。这意味着一个 64 通道的 CPU 实际上只有 56 个可用通道。这反过来意味着,对于 4 张卡,你又剩下一个 16x/16x/8x/8x 配置。这仍然很棒,超过了英特尔所能提供的,但与英特尔的 i9 CPUs 相比,这不算什么问题。此外,当建造一台价值数千美元的机器时,为一个更便宜的 CPU 节省 400-500 美元也许并不重要。
因此,事实证明,AMD 仍然主要与英特尔在游戏机方面竞争,或者与那些大量节省几百美元的人竞争。此外,对于构建双 GPU 机器,我可能会选择他们,因为与整体系统价格相比,2x16 PCI-E 和 CPU 的节省更大。
关于内存(RAM)的说明
即使某个 CPU 适合(物理上,插槽方面)特定的主板,而主板又支持大量内存(同样,物理上,通过大量插槽),CPU 本身仍然有可能不适合。CPU 之间的区别因素之一(就价格而言)是它们支持大量内存的能力。64+ GB 内存通常只有昂贵的 CPU 支持。
关于硬件的更多信息
由于内存和主板会随着硬件的更新而不断更新,因此要保持与时俱进有点困难。它们也(在我看来)不那么令人兴奋和有趣。
我给你的建议?在选择 CPU/GPU 之后,了解您的其他需求,并选择支持这些需求的好主板。仔细阅读小字,检查它是否支持您需要它支持的内容。一些常见的错误是:
- 购买显卡插槽数量不足的主板。
- 显卡插槽之间没有足够的空间(由于巨大的冷却解决方案,我们正在处理的 GPU 需要两个插槽)。
- 购买不支持我们想要购买的内存类型的主板。
底板
支持最新和最好的主板往往是相似的,价格也差不多。去一家领先的公司;微星,华硕,技嘉等等。正如多次提到的,确保它支持 CPU 插槽、内存数量和类型,以及所需的 PCI-E 插槽数量、间距和通道数量。关于通道的数量,请注意,一些主板具有 GPU 兼容插槽,实际上不允许完整的 8/16 PCI-E 通道通过(它们下面是 x4 通道)。避开那些。至于具体的品牌——请看下一个芯片组。请注意,大多数主板,除了最昂贵的版本,通常只支持 3 个 GPU。
在芯片组上
TLDR:你想购买的相关芯片组是用于最新英特尔 X 型号的 X299 系列和(巧合的是)用于 AMD CPUs 的 X399 系列。
像前面的 CPU 及其主板一样,芯片组是主板的重要组成部分,实际上是它支持各种 CPU 功能。领先品牌的旗舰主板通常会包含最新、最好的芯片组,从而支持您所需的一切。
CPU 制造商使用不同的“插座”将其 CPU 连接到主板。这些通常用“LGA2066”这样的术语来表示,这意味着处理器和插座之间的物理连接(引脚)数量。LGA 的意思是“陆地网格阵列”,意味着引脚实际上是主板的一部分,而不是 CPU 的一部分(过去是反过来的)。
英特尔第 10 代和第 11 代使用插座 LGA1200,取代了第 9 代之前使用的旧插座 LGA1151。对于 X-parts(也称为高端台式机的 HEDT ),由于其高功率要求,它使用了不同的插座配置——LGA 2066,它仍然存在,但应该会在不久的将来被取代。选择主板时要知道这些数字。
记忆
一般的经验法则是 CPU 内存是 GPU 内存的两倍。因此,对于四个 2080,我将得到 2x11x4 = 88GB 的内存。由于内存倾向于以 16GB 为增量,我们可能会有一个 96GB 的内存机器用于这样的配置。在我的头顶上统治着记忆制造者;海盗船(已经在上面好几年了!),HyperX,Patriot,G.Skill,还有 A-Data 在预算端的事情。
电源装置— PSU
你的电源应该能够承载你正在建造的机器的疯狂的电力需求。拥有两个以上 GPU 的机器通常会有两个独立的电源。因此,如果您计划在将来添加更多的卡,请确保您的盘柜支持第二个 PSU,以供以后使用。两台 GPU 机器可以满足于单个 1000W PSU。PSU 的优秀制造商有 Antec、CoolerMaster、Corsair、SeaSonic、EVGA 等。
冷却/外壳
假设这整个机器将在它自己的单独的、良好冷却的房间里,我们真的不需要专门的冷却解决方案。如果不行,你会想要一个足够安静的工作环境。
至于机箱,您会想要一个便于安装所有东西的机箱,并且偶尔会打开进行修复/硬件更换。还要注意,与附件捆绑在一起的 PSU 通常是垃圾——除非它们来自真正的公司。
硬盘驱动器
这归结为预算。便宜的选择是为当前使用的数据集提供良好、快速的 1TB SSD,为常规、较慢和较便宜的存储(模型检查点等)提供 4tb 以上的 SSD。
如果预算不成问题,当然最好只购买快速固态硬盘。由于价格往往会一直下降,如果你想挥霍,你肯定可以购买更多的固态硬盘。同样值得一提的是备份;如果您绝对不能承受数据丢失,那么考虑一个 RAID 解决方案(超出了本文的范围)。
结束语—游戏机
上面描述的一批硬件与流行的高端游戏机有很多共同点。除了非常夸张的 GPU 设置之外,大多数组件(主板、RAM、PSU 等)在高端游戏设置中都会感觉很舒服。如果你在谷歌搜索这里的所有信息时遇到了一些问题,将“深度学习”改为“游戏”,你就能找到答案了
祝你好运!
图片: YouTube/Nvidia
提升 Jupyter 笔记本体验的另一种方式
增强 jupyter 笔记本电脑的额外有用功能没有被充分提及
我已经写了一些将在我们的 Jupyter 笔记本上实现的最有用的特性这里,但是我想把它扩展成一些很少在 Jupyter 笔记本上实现的特性(或者至少在我的知识范围内)。这就是了。
丘比特主题
如果你不喜欢香草 jupyter 主题,或者只是厌倦了它,你实际上可以改变主题。虽然,我很少改变我的 Jupyter 笔记本主题,因为我更喜欢默认形式。作为初学者,需要先安装必备模块。
**# install jupyterthemes**
pip install jupyterthemes
如果你想访问所有的 jupyterthemes 文档,你可以在这里阅读。
要使用 jupyterthemes 修改我们的 jupyter 笔记本环境,我们可以使用 jupyter 笔记本或使用 CLI。让我们尝试查看所有可用的主题。在 CLI 中,我们使用 jt 命令访问 jupyterthemes。通过使用!在 jupyter 笔记本上,我们可以像在 CLI 中一样输入
**#accessing all the jupyter themes**!jt -l
jupyterthemes 中所有可用的主题
如果我们想改变我们的主题,我们可以使用下面的命令。
**#For example, I want to change it to chesterish theme**
!jt -t chesterish
切斯特主题
**#Or change it to gruvboxl theme**
!jt -t gruvboxl
Gruvboxl 主题
如果您想恢复到默认主题,您只需输入这一行。
**#Reset the change**
!jt -r
就这样,我们回到了最初的主题。我个人更喜欢默认的主题,因为颜色对我的眼睛很好,如果你意识到当我们改变主题;所有常用的快捷图标都不见了。我是那种喜欢使用图标而不是键盘快捷键的人,这就是为什么我更喜欢默认的那个。
自动导入
如果你懒得在 Jupyter 笔记本上输入每一个你会用到的重要库(比如 Pandas,Numpy,Matplotlib 等等。),我们实际上可以建立一个环境,在这个环境中,我们已经将所有这些库导入到我们的 Jupyter 笔记本中。从技术上讲,我将在这一部分解释的内容并不是任何可用扩展的一部分,但它仍然是提升我们 Jupyter 笔记本体验的一种方式。
这些步骤非常简单,它们是:
- 找到
~/.ipython/profile_default
文件夹,它通常在你的用户文件夹中 - 在文件夹中,如果没有名为“启动”的文件夹,请创建一个
- 在启动文件夹中,创建一个新的 python 文件(你可以给它起任何名字,但是我更喜欢把它命名为
start.py
- 在这个文件中写下你想要导入的库,每次你启动 Jupyter notebook 时,它都会自动导入
例如,在 start.py 中,我将这样编写我的自动导入库
当我启动我的笔记本时,我不需要导入上面的这些库,直接完成我的工作。
我的 jupyter 笔记本自动导入示例
如果您想确认库是否已经被加载,您可以通过使用 Jupyter 笔记本中的globals()
来检查环境。
Qgrid
Qgrid 是一个 Jupyter 笔记本部件,它改进了我们的熊猫数据框布局。这个小部件允许我们滚动、排序和过滤控件,以及通过双击单元格来编辑数据框。要启用 qgrid,我们需要先安装它。
pip install qgridjupyter nbextension enable --py --sys-prefix qgrid**# only for the first time if you have not enabled the ipywidgets nbextension**
jupyter nbextension enable --py --sys-prefix widgetsnbextension
下面是我们如何使用 qgrid 的一个例子。
仅仅通过使用 qgrid 中的函数show_grid
,我们已经有了一个不同于默认的 Dataframe 体验。在这里,我们可以更加灵活地对数据进行排序和过滤。
崛起
RISE 是一个插件,可以将我们的 Jupyter Cell 笔记本创建和编辑成交互式幻灯片。如果你意识到我们可以在我们的 Jupyter 笔记本中创建一个幻灯片,它位于视图->单元格工具栏->幻灯片。这种方法的缺点是,我们需要在单独的屏幕上运行额外的命令来创建幻灯片,并且单元格不可调整。
这就是 RISE 的用武之地,通过使用这个插件,我们可以在我们的 Jupyter 笔记本上创建一个交互式幻灯片。首先,我们需要安装并启用所有重要的东西。
**#Installing using conda**
conda install -c damianavila82 rise**#or using pip**
pip install rise**#enable the nbextension:**
jupyter-nbextension install rise --py --sys-prefixjupyter-nbextension enable rise --py --sys-prefix
现在我们准备使用 RISE 来创建我们的幻灯片。这是它的工作原理。
如何创建幻灯片
下面是我们创建完幻灯片并使用上升后的样子。使用 RISE 的最大好处是,我们可以在幻灯片放映期间编辑代码。
结论
在这里,我向您展示了一些在 Jupyter Notebook 中很少使用但实际上在我们的日常数据科学工作中非常有用的功能。希望有帮助!
如果你喜欢我的内容,并想获得更多关于数据或作为数据科学家的日常生活的深入知识,请考虑在这里订阅我的时事通讯。
如果您没有订阅为中等会员,请考虑通过我的推荐订阅。
ANOVA(方差分析)-解释
详细的解释和一个 R 的例子
亨利·洛伦扎托在 Unsplash 上拍摄的照片
ANOVA 代表方差分析,顾名思义,它帮助我们理解和比较不同组之间的方差。在详细讨论方差分析之前,让我们记住统计学中的几个术语:
- 表示:所有数值的平均值。
- 方差:值之间变化的度量。计算方法是将每个值和平均值的平方差相加,然后将总和除以样本数。
- 标准差:方差的平方根。
为了理解方差分析或其他一些统计检验背后的动机,我们应该学习两个简单的术语:总体和样本。
群体是一个群体中的所有元素。举个例子,
- 美国大学生是指包括美国所有大学生在内的人口。
- 欧洲的 25 岁人群包括了所有符合描述的人。
对人口进行分析并不总是可行或可能的,因为我们无法收集人口的所有数据。因此,我们使用样本。
样本是总体的子集。举个例子,
- 美国 1000 名大学生是“美国大学生”人口的一个子集。
进行统计测试是为了观察使用样本计算的结果是否适用于整个人群。
当我们比较两个样本(或组)时,可以用 t 检验来看组的均值是否有差异。当我们有两个以上的组时,t-test 不是最优选择,因为我们需要分别对成对进行 t-test。假设我们有 A 组、B 组和 C 组。为了能够比较平均值,我们需要对 A-B、A-C 组和 B-C 组进行 t 检验。随着组数的增加,这变得更加难以管理。
在比较三组或更多组的情况下,ANOVA 是优选的。方差分析有两个要素:
- 各组内的差异
- 组间差异
ANOVA 测试结果基于 F 比率,即组间差异与组内差异的比率。
f 比率表明总变异有多少来自组间变异,有多少来自组内变异。如果大部分差异来自组间的差异,则更有可能是组的平均值不同。然而,如果大多数的变化来自于组内的变化,那么我们可以得出结论,一个组中的元素是不同的,而不是整个组。F 比率越大,各组的均值越有可能不同。
让我们看一个例子。假设我们有 3 组 8 个观察值:
我们想进行方差分析测试,看看这些组是否不同。我将使用 R,但也可以在任何软件包上随意使用。我们从创建组开始:
然后合并各组:
然后将组堆叠在框架中:
然后用一行代码执行 ANOVA:
让我们回顾一下结果:
- f 值为 7.89,表明各组不同。大于 1 的 f 值表示至少一个组不同于其他组。
- p 值非常小,表明结果具有统计学意义(即不是由于随机机会产生的)。通常,p 值小于 0.05 的结果被认为具有统计学意义。
- Df 是自由度。第一行是组间差异,第二行是组内差异,计算如下:
共有 3 组,共 24 个观察值。所以第一行是 2,第二行是 22。我们可以将结果表示为:
到目前为止,我们所做的是一个单向 ANOVA 测试,它基于一个独立变量比较三个或更多组的平均值。还有一个双向 ANOVA 测试,根据两个独立变量比较三组或更多组。
考虑一个营养师想要分析三个不同组的减肥情况。他/她准备了三种不同的饮食,每组喂食不同的饮食。在这种情况下,如果各组中的平均体重减轻不同,则单向 ANOVA 测试适于检查平均体重减轻。如果营养学家也想知道一组中男性和女性的平均体重减轻是否不同,那么双向方差分析测试是合适的。性别和饮食类型是这个双向方差分析测试的因素。
减肥的单向与双向方差分析
感谢您的阅读。如果您有任何反馈,请告诉我。
ANOVA 在单身女郎电视节目中向初学者解释
又名如何自娱自乐与统计在疫情
杰里·克莱恩在 Unsplash 上的照片
单向 ANOVA(方差分析)是一种参数检验,用于检验 3 个或更多组之间结果的统计显著性差异。ANOVA 测试总体差异,即至少一个组在统计上显著不同于其他组。然而,如果方差分析是显著的,你不能告诉哪组是不同的。你需要事后比较来确定。
我想看看不同季的未婚女子和参赛者之间的年龄差距,看看不同季之间的年龄差距是否有统计学上的显著差异。在这个非常重要的分析中,我将向您介绍:
- 数据
- 假设检验
- 单向 ANOVA 检验
- 事后分析
数据
我在 Kaggle 上发现了这个非常孤独的数据🌹。经过一些清理和合并,它看起来像这样:
一些人已经调查了参赛者主要来自哪里,所以我想还有什么值得探索的🤔。我决定调查未婚女子和参赛者之间的年龄差距,看看这个节目是否随着时间的推移而改变,或者他们是否试图在每一季保持相同的年龄差距!重要的东西!!
这里快速看一下每个赛季的参赛选手数量(样本大小)和平均年龄差距。不幸的是,《单身女郎时代》在某些季中缺失了,留给我们的只有七个组合(第 1、5、6、9、10、11 和 12 季)。
假设检验
我们需要检查三个假设,以使用非参数统计检验,如 Welch 的 ANOVA 或 Kruskal-Wallis ANOVA:
**1。独立性:**这意味着所有的群体都是相互排斥的,即一个个体只能属于一个群体。此外,数据不是重复测量的(不是通过时间收集的)。在这个例子中,满足了这个条件。
**2。正态性:**对于方差分析或回归模型,我们可以通过查看模型残差来检验这一点。每个残差是输入值和该组所有值的平均值之间的差值。我们将使用图形方法,概率图。
**3。方差的同质性:**我们需要确保所有组都有相等的方差。检验这一假设的一种方法是 Levene 的方差齐性检验。
正态—概率图
概率图根据理论分布绘制有序数据。有序数据与理论分布拟合得越好,与位于图表中间的拟合线的偏差就越小。根据该图,在给定大样本量(n>30)的情况下,有理由声明满足正态性假设。然而,查看绘制的概率图和剩余结构,转换数据进行分析,或使用非参数统计检验,如 Welch 的 ANOVA 或 Kruskal-Wallis ANOVA,也是合理的。
方差齐性——Levene 检验
使用 Levene 检验,我们得到(统计值=0.9092,p 值=0.4895)。p 值大于 0.05,这表明各组的变异性无统计学显著差异。同样,也有必要从视觉上检查这个假设。
方差齐性的图形检验支持统计检验结果,即各组具有相等的方差。
默认情况下,箱形图显示中值(上图中的橙色线)。绿色三角形是每组的平均值。
单向方差分析
让我们从定义零假设和替代假设开始。在这个例子中,零假设是平均年龄差距在所有季节都是相同的,而另一个假设是至少一个季节的平均年龄差距在统计上显著不同于其他季节。
然后,我们需要继续计算一些统计数据,包括 F 统计、F 临界、样本间平方和(SSB)、样本内平方和(SSW)、样本间均方(MSB)、样本内均方(MSW)。
在我们的单身女子的例子中,我们有 7 个季节。所以我们的 k=7,总共有 182 个参赛者,这意味着 n = 182。你可以得到
查看源代码,逐步手动计算这些统计数据。对于本故事的其余部分,我将使用 statsmodel ANOVA 测试和汇总统计的输出。
我们拒绝零假设,H0,如果计算的 F-static 大于临界 F-statistic。临界 F 统计量由自由度(k-1=6,n-k=175)和α决定,我选择α=0.05。你可以使用一个在线 F 分布计算器来得到 F 临界,这里是 2.15。从 stats.f_oneway,我们得到 F _ one way result(statistic = 10.0375,pvalue=1.5990495398830284e-09)。您可以看到计算出的 F 统计值大于 F 临界,因此我们拒绝零假设,这意味着这些季节中至少有一个季节的平均年龄差距明显不同于其他季节。
在 Unsplash 上 Pablo Heimplatz 拍摄的照片
事后分析
现在让我们看看哪些季节不同,哪些季节大同小异!
Tukey 诚实显著差异(HSD)
tukey truly Significant Difference(HSD)测试所有成对组比较,同时控制多重比较,以保护家族误差率,避免出现 I 型错误。
使用剔除列可以很容易地阅读表格。例如,在第一季和第五季之间,我们无法拒绝零假设,这意味着在这两季中年龄差异之间没有统计学上的显著差异。然而,在第一季和第六季之间,情况正好相反。
和往常一样,我喜欢做一个图形比较来总结这个非常有趣的分析😃
我希望你喜欢看这篇文章,下次玫瑰典礼再见!!🥂
回归方差分析
总和平方和、回归平方和及误差平方和。
在 Unsplash 上由 Tachina Lee 拍摄的照片
ANOVA ( 方差分析)是一个构成显著性检验基础的框架&提供关于回归模型中可变性水平的知识。它与线性回归相同,但主要区别之一是回归用于根据一个或多个连续预测变量预测连续结果。鉴于, ANOVA 用于预测基于一个或多个分类预测变量的连续结果。
在实现线性回归时,我们经常会遇到诸如 SST (总和平方和) SSR (回归平方和) SSE (误差平方和)之类的术语,并想知道它们实际上是什么意思?在本帖中,我们将涵盖这些主题,并实现一个示例来更好地理解这个主题。
SST(总平方和)
总和平方和是观察因变量与其**平均值(均值)**之间的平方差。这里需要注意的一点是,我们总是将线性回归最佳拟合线与因变量斜率的平均值(表示为 y ̅)进行比较。
由 Rahul Pathak 在媒体上拍摄的照片
SSR(回归平方和)
回归平方和是预测值和因变量均值之间的差值之和。
由 Rahul Pathak 在媒体上拍摄的照片
SSE(误差平方和)
误差平方的 Sum是观察值和预测值之间的差值。
由 Rahul Pathak 在介质上拍摄的照片
为了理解这些平方和的使用流程,让我们手动浏览一个简单线性回归的例子。假设约翰是加州的酒店的服务员,他有个人的总账单,并且他还收到该订单的小费* 。我们希望根据收到的总账单来预测下一笔小费是多少。让我们用(x)表示总账单,用(y)表示小费金额。*
由 Rahul Pathak 在媒体上拍摄的照片
y=α+βx 将给出预测值,而我们根据上述公式计算α & β的值,其中β是斜率,α是 y 截距。简单线性回归的目标是创建一个最小化残差平方和(误差)的线性模型。
关于线性回归的一个有趣的事实是,它是由两个统计概念方差分析和相关性组成的。
线性回归=相关+方差分析 回到正题…
SST,SSR & SSE 是怎么联系起来的?
SST = SSR + SSE
在上表中,我们可以看到之前误差平方和为 120,后来减少到 30.075,即我们使用线性回归将误差值从 120 减少到 30.075。以前,最佳拟合线是因变量斜率的平均值,后来变为最佳最佳拟合线。
120 =?+ 30.075 因此 SSR 的值为 89.925
为什么我们需要平方和?
答案是确定拟合优度。可以使用决定系数来确定,也称为**R。**R 将比率量化为百分比。此外,R 经常与“R”混淆,其中 R 是决定系数,而 R 是相关系数。相关性测量两个变量 X 和 y 之间的线性相关性。其范围从值 -1 到 1 ,其中接近 1 的值为正相关,接近-1 的值为负相关。例如,在上表中,我们得到的值 r 为 0.8656 ,它更接近于 1,因此描绘了一个正关系。
最终拍板
要记住的重要公式:——
- R = SSR/SST
- R = 1-(SSE/SST)
- SSE =σ(实际-预测)
- SST =σ(实际平均值)
- SSR =σ(预测平均值)
我希望我能帮助你回答与这个主题相关的问题。请随时查询我的联系 id:——拉胡尔·帕塔克。
非常感谢!😃
R 中的方差分析
了解如何在 R 中执行方差分析(ANOVA)来比较 3 组或更多组。另请参见如何解释结果和执行事后测试
照片由 Battlecreek 咖啡烘焙师拍摄
介绍
NOVA(方差分析)是一种统计测试,用于确定两个或多个总体均值是否不同。换句话说,它用于比较两个或更多组,以查看它们是否显著不同。
然而,实际上:
- 学生 t 检验 用于比较 2 组;
- ANOVA 将 t 检验推广到 2 组以上,因此用于比较 3 组或更多组。
注意,ANOVA 有几种版本(例如,单向 ANOVA、双向 ANOVA、混合 ANOVA、重复测量 ANOVA 等。).在本文中,我们只给出最简单的形式——单向 ANOVA**1——在本文的剩余部分我们称之为 ANOVA。**
虽然 ANOVA 是用来对不同组的表示进行推断的,但这种方法叫做“分析 方差 ”。之所以这么叫,是因为它比较了“之间”方差(不同组之间的方差)和“内”方差(每组内的方差)。如果组间方差明显大于组内方差,则说明组均值不同。否则,我们无法得出这样或那样的结论。通过取比值(方差之间/方差之内),然后将该比值与费希尔概率分布中的阈值(基于特定显著性水平的阈值,通常为 5%)进行比较,将两个方差相互比较。
这是关于方差分析方法的足够的理论。在本文的剩余部分,我们将从更实际的角度来讨论它,特别是,我们将涵盖以下几点:
- 方差分析的目的、何时使用以及无效/替代假设
- 方差分析的基本假设以及如何检查它们
- 如何在 R 中进行方差分析
- 如何解释方差分析的结果
- 理解事后测试的概念并解释结果
- 如何可视化方差分析和事后检验的结果
数据
本文的数据是penguins
数据集(众所周知的iris
数据集的替代),可通过[{palmerpenguins}](https://github.com/allisonhorst/palmerpenguins)
包访问:
# install.packages("palmerpenguins")
library(palmerpenguins)
该数据集包含 3 个不同物种(阿德利企鹅、下巴颏企鹅和巴布亚企鹅)的 344 只企鹅的数据。数据集包含 8 个变量,但我们只关注本文中的鳍肢长度和物种,所以我们只保留这 2 个变量:
library(tidyverse)dat <- penguins %>%
select(species, flipper_length_mm)
(如果不熟悉管道操作符(%>%
),也可以用penguins[, c("species", "flipper_length_mm")]
选择变量。在关于数据操作的文章中了解更多选择变量的方法。)
下面是一些基本的描述性统计数据和我们数据集的一个图(用[{ggplot2}](https://www.statsandr.com/blog/graphics-in-r-with-ggplot2/)
包制作),然后我们继续进行方差分析的目标:
summary(dat)## species flipper_length_mm
## Adelie :152 Min. :172.0
## Chinstrap: 68 1st Qu.:190.0
## Gentoo :124 Median :197.0
## Mean :200.9
## 3rd Qu.:213.0
## Max. :231.0
## NA's :2
鳍状肢的长度从 172 毫米到 231 毫米不等,平均长度为 200.9 毫米。阿德利企鹅、下颚带企鹅和巴布亚企鹅分别有 152 只、68 只和 124 只。
library(ggplot2)ggplot(dat) +
aes(x = species, y = flipper_length_mm, color = species) +
geom_jitter() +
theme(legend.position = "none")
这里,因子是species
变量,包含 3 个模态或组(Adelie、Chinstrap 和 Gentoo)。
方差分析的目的和假设
如引言中所述,ANOVA 用于比较各组(实际上是 3 组或更多组)。更一般地说,它用于:
在这种情况下,作为一个例子,我们将使用方差分析来帮助我们回答这个问题:“三种企鹅的鳍状肢长度不同吗?”。
方差分析的无效假设和替代假设是:
- H0:μ_ Adelie =μ_ Chinstrap =μ_ Gentoo(三个物种的鳍状肢长度相等)
- H1: 至少有一个平均值是不同的(至少有一个物种与其他两个物种的鳍长度不同)
注意另一个假设是 而不是 所有的方法都不同。所有平均数相等的反面(H0)是至少有一个平均数不同于其他平均数(H1)。在这个意义上,如果零假设被拒绝,这意味着至少有一个物种不同于其他 2,但不一定是所有 3 个物种彼此不同。可能阿德利物种的鳍状肢长度不同于下颚带和巴布亚,但是下颚带和巴布亚的鳍状肢长度相似。必须执行其他类型的测试(称为事后测试,包含在本部分中)来测试所有 3 个物种是否不同。
方差分析的基本假设
至于许多统计测试,为了能够解释结果,需要满足一些假设。当一个或几个假设不满足时,尽管技术上可以进行这些测试,但解释结果和相信结论是不正确的。
下面是方差分析的假设,如何测试它们,以及如果假设不满足,还有哪些测试:
- 变量类型 : ANOVA 需要混合一个连续定量因变量(对应于与问题相关的测量)和一个定性自变量(至少有 2 个水平,用于确定要比较的组)。
- 独立性:从总人口中随机选择的代表性部分收集的数据,在组间和组内应该是独立的。独立性的假设通常基于实验的设计和对实验条件的良好控制来验证,而不是通过正式的测试。如果你仍然不确定基于实验设计的独立性,问问自己一个观察是否与每个组内或组间的另一个观察相关(如果一个观察对另一个有影响)。如果没有,很可能你有独立的样本。如果样本之间的观察值(形成待比较的不同组)是相关的(例如,如果三个测量值是在相同的个体上收集的,这是医学研究中在测量(I)治疗前、(ii)治疗期间和(iii)治疗后的指标时经常出现的情况),那么重复测量值 ANOVA 应该是首选的,以便考虑样本之间的相关性。
- 正态:残差 2 应该近似遵循一个 正态分布 。正态性假设可以通过直方图和 QQ 图进行直观测试,和/或通过正态性测试进行正式测试,如夏皮罗-维尔克或科尔莫戈罗夫-斯米尔诺夫测试。如果,即使在对数据进行变换(例如,对数变换、平方根、Box-Cox 等)后,),残差仍然不符合近似正态分布,可以应用 Kruskal-Wallis 检验(R 中的
kruskal.test(variable ~ group, data = dat
)。这种非参数检验对非正态分布稳健,与 ANOVA 的目标相同—比较 3 个或更多组—但它使用样本中位数而不是样本均值来比较组。 - 方差相等:不同组的方差在总体中应该相等(这种假设被称为方差的同质性,或者有时被称为同方差,与方差在不同组之间不相等的异方差相对)。这种假设可以通过图形测试(例如通过比较箱线图或点线图中的离散度),或者更正式地通过 Levene 测试(
{car}
包中的leveneTest(variable ~ group)
)或 Bartlett 测试,等等。如果等方差假设被拒绝,可以使用 ANOVA 的另一个版本:Welch 检验(oneway.test(variable ~ group, var.equal = FALSE)
)。请注意,韦尔奇检验不要求方差齐性,但分布仍应近似遵循正态分布。请注意,Kruskal-Wallis 检验既不需要正态假设,也不需要方差的同方差假设。 3
根据假设是否满足来选择合适的测试可能会令人困惑,因此这里有一个简短的总结:
- 检查你的观察是否独立。
- 如果它们是独立的,检验残差的正态性:
- 如果假设正态性,检验方差的同质性:
- 如果差异相等,使用 ANOVA 。
- 如果差异不相等,使用韦尔奇测试**。**
- 如果没有假设正态性,使用克鲁斯卡尔-沃利斯检验**。**
既然我们已经看到了方差分析的基本假设,我们在应用适当版本的测试之前,专门为我们的数据集回顾它们。
可变类型
因变量flipper_length_mm
是一个定量变量,自变量species
是一个定性变量(3 个等级对应 3 个物种)。所以我们有两种变量的混合,这个假设是成立的。
独立性ˌ自立性
假设观察值是独立的,因为数据是从人群中随机选择的部分收集的,并且 3 个样本内部和之间的测量值是不相关的。
独立性假设通常是基于实验设计和对实验条件的良好控制来验证的,就像这里的情况一样。如果你真的想更正式地测试它,你可以通过一个统计测试来测试它——Durbin-Watson 测试(在 R: durbinWatsonTest(res_lm)
中,其中res_lm
是一个线性模型)。该检验的零假设指定自相关系数= 0,而替代假设指定自相关系数≠ 0。
常态
请记住,残差的正态性可以通过直方图和 QQ 图进行直观测试,和/或通过正态性测试(例如夏皮罗-维尔克测试)进行正式测试。
在检查正态性假设之前,我们首先需要计算方差分析(在部分中有更多相关信息)。然后我们将结果保存在res_aov
:
res_aov <- aov(flipper_length_mm ~ species,
data = dat
)
我们现在可以直观地检查正常性:
par(mfrow = c(1, 2)) # combine plots# histogram
hist(res_aov$residuals)# QQ-plot
library(car)
qqPlot(res_aov$residuals,
id = FALSE # id = FALSE to remove point identification
)
从上面的直方图和 QQ-plot,我们已经可以看到,正态性假设似乎得到了满足。事实上,直方图大致形成一条钟形曲线,表明残差遵循正态分布。此外,QQ 图中的点大致遵循直线,并且它们中的大多数都在置信带内,这也表明残差近似遵循正态分布。
一些研究人员就此打住,假设满足正态性,而其他人也通过正式的统计测试来检验这一假设。您可以选择(I)仅通过目测,(ii)仅通过正态性测试,或(iii)同时通过目测和正态性测试进行测试。但是,请记住以下两点:
- 方差分析对偏离正态分布的小偏差非常稳健。这意味着如果少量的点稍微偏离正态性(从 ANOVA 结果解释的角度来看),
- 正态性检验有时相当保守,这意味着正态性的零假设可能会由于与正态性的有限偏离而被拒绝。对于大样本来说尤其如此,因为测试的功效随着样本量的增加而增加。
实际上,我倾向于只选择(I)视觉方法,但是,这是一个个人选择的问题,也取决于分析的背景。
还是为了说明,我们现在也通过正态性检验来检验正态性假设。你可以使用夏皮罗-维尔克检验或者科尔莫戈罗夫-斯米尔诺夫检验等等。请记住,无效假设和替代假设是:
- H0:数据来自正态分布
- H1:数据做 不是 来自正态分布
在 R 中,借助于shapiro.test()
函数,我们可以用夏皮罗-维尔克检验来检验残差的正态性:
shapiro.test(res_aov$residuals)##
## Shapiro-Wilk normality test
##
## data: res_aov$residuals
## W = 0.99452, p-value = 0.2609
P-残差的夏皮罗-维尔克检验值大于通常的显著性水平α=5%,所以我们不拒绝残差服从正态分布的假设(P-值= 0.261)。
这个结果符合目测法。在我们的例子中,正态假设在视觉上和形式上都得到了满足。
边注:提醒 p 值是假设零假设为真,我们在样本中观察到的极端情况的概率。如果 p 值* < α (表示假设原假设为真,不太可能观察到我们在样本中拥有的数据),则拒绝原假设,否则不拒绝原假设。查看更多关于 p 值和显著性水平 如果你对那些重要的统计学概念不熟悉。***
请记住,如果没有达到正态假设,则需要对原始数据进行一些变换,希望残差能够更好地符合正态分布,或者您需要使用 ANOVA 的非参数版本—Kruskal-Wallis 检验。
正如一位读者所指出的(见文章最后的评论),正态性假设也可以在“原始”数据(即观察值)而不是残差上进行检验。但是,如果您测试原始数据的正态性假设,则必须单独测试每组数据,因为方差分析需要每组数据的正态性。**
对所有残差或每组观察值进行正态性检验是等效的,并且会给出相似的结果。的确,说“每组内 Y 的分布是正态分布”和说“残差是正态分布”是一样的。
请记住,残差是 Y 的实际值与特定 X 值的 Y 平均值之间的距离,因此在计算残差时会引入分组变量。
总之,在方差分析中,你实际上有两个检验正态性的选择:
- 分别检查每组“原始”数据(Y 值)的正态性
- 检查所有残差的正态性(但不是每个组)
在实践中,您会发现,只使用残差并一起检查它们通常会更容易,尤其是当您有许多组或每组的观察值很少时。
如果你仍然不相信:记住方差分析是线性模型的一个特例。假设你的自变量是一个连续变量(而不是一个分类变量),你剩下的唯一选择就是检查残差的正态性,这正是在线性回归模型中检验正态性所做的。
方差相等—同质性
假设残差服从正态分布,现在是时候检查物种之间的方差是否相等了。结果将会影响我们是否使用方差分析或韦尔奇检验。
这可以再次通过视觉验证——通过箱线图或点线图——或者更正式地通过统计测试(Levene 的测试,等等)。
视觉上,我们有:
*# Boxplot
boxplot(flipper_length_mm ~ species,
data = dat
)*
*# Dotplot
library("lattice")dotplot(flipper_length_mm ~ species,
data = dat
)*
箱线图和点图都显示了不同物种的相似方差。在箱线图中,这可以从以下事实中看出:对于所有物种来说,盒子和须状物具有可比较的大小。有几个异常值,如胡须外的点所示,但这不会改变不同物种之间的分散或多或少相同的事实。
在点图中,这可以通过所有 3 个物种的点具有或多或少相同的范围这一事实看出,这是离散的标志,因此方差是相似的。
与正态性假设一样,如果您觉得直观的方法不够充分,您可以使用 Levene 或 Bartlett 的测试来正式测试方差的相等性。请注意,Levene 检验对偏离正态分布的敏感度低于 Bartlett 检验。
两种检验的无效假设和替代假设是:
- H0:差异是相等的
- H1:至少有一个差异是不同的
在 R 中,Levene 的测试可以通过{car}
包中的leveneTest()
函数来执行:
*# Levene's test
library(car)leveneTest(flipper_length_mm ~ species,
data = dat
)## Levene's Test for Homogeneity of Variance (center = median)
## Df F value Pr(>F)
## group 2 0.3306 0.7188
## 339*
p-值大于 0.05 的显著性水平,我们不拒绝零假设,所以我们不能拒绝物种间方差相等的假设(p-值= 0.719)。
这个结果也符合视觉方法,所以方差的同质性在视觉上和形式上都得到满足。
检验正态性和同质性的另一种方法
供您参考,也可以通过plot()
功能直观地(同时)测试方差的同质性和残差的正态性:
*par(mfrow = c(1, 2)) # combine plots# 1\. Homogeneity of variances
plot(res_aov, which = 1)# 2\. Normality
plot(res_aov, which = 2)*
左侧的图显示残差和拟合值(每组的平均值)之间没有明显的关系,因此假设方差齐性。如果方差的同质性被破坏,红线就不会是平的。
右手边的图显示残差近似遵循正态分布,因此假设正态性。如果常态被破坏,点将持续偏离虚线。
方差分析
我们表明方差分析的所有假设都得到满足。因此,我们可以继续实施 R 中的方差分析,但首先,让我们做一些初步的分析,以更好地理解研究问题。
初步分析
在实际执行 R 中的 ANOVA 之前,一个好的做法是可视化与研究问题相关的数据*。最好的方法是绘制并比较每个物种的数量变量flipper_length_mm
的箱线图。***
这可以通过基数 R 中的boxplot()
函数来完成(与等方差的视觉检查代码相同):
*boxplot(flipper_length_mm ~ species,
data = dat
)*
或者用[{ggplot2}](https://www.statsandr.com/blog/graphics-in-r-with-ggplot2/)
包:
*library(ggplot2)ggplot(dat) +
aes(x = species, y = flipper_length_mm) +
geom_boxplot()*
上面的方框图显示,至少对我们的样本来说,Gentoo
企鹅似乎有最大的鳍状肢,而Adelie
企鹅的鳍状肢最小。
除了每个物种的箱线图外,计算一些描述性统计数据也是一个很好的做法,例如物种的平均值和标准差。例如,这可以通过aggregate()
功能来实现:
***aggregate(flipper_length_mm ~ species,
data = dat,
function(x) round(c(mean = mean(x), sd = sd(x)), 2)
)## species flipper_length_mm.mean flipper_length_mm.sd
## 1 Adelie 189.95 6.54
## 2 Chinstrap 195.82 7.13
## 3 Gentoo 217.19 6.48***
或者使用{dplyr}
组件中的summarise()
和group_by()
功能:
***library(dplyr)group_by(dat, species) %>%
summarise(
mean = mean(flipper_length_mm, na.rm = TRUE),
sd = sd(flipper_length_mm, na.rm = TRUE)
)## # A tibble: 3 x 3
## species mean sd
## <fct> <dbl> <dbl>
## 1 Adelie 190\. 6.54
## 2 Chinstrap 196\. 7.13
## 3 Gentoo 217\. 6.48***
平均值也是Adelie
最低,Gentoo
最高。然而,箱线图和描述性统计数据不足以得出结论,三个企鹅种群的鳍状肢有显著差异。
R 中的方差分析
正如你现在所猜测的,只有方差分析可以帮助我们根据手头的样本对种群做出推断,并帮助我们回答最初的研究问题“三种企鹅的鳍状肢长度不同吗?”。
R 中的方差分析可以用几种方法进行,下面介绍其中的两种方法:
- 使用
oneway.test()
功能:
***# 1st method:
oneway.test(flipper_length_mm ~ species,
data = dat,
var.equal = TRUE # assuming equal variances
)##
## One-way analysis of means
##
## data: flipper_length_mm and species
## F = 594.8, num df = 2, denom df = 339, p-value < 2.2e-16***
2.使用summary()
和aov()
功能:
***# 2nd method:
res_aov <- aov(flipper_length_mm ~ species,
data = dat
)summary(res_aov)## Df Sum Sq Mean Sq F value Pr(>F)
## species 2 52473 26237 594.8 <2e-16 ***
## Residuals 339 14953 44
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 2 observations deleted due to missingness***
从上面的两个输出可以看出,两种方法的检验统计量(F =
在第一种方法中,而F value
在第二种方法中)和p-值(p-value
在第一种方法中,而Pr(>F)
在第二种方法中)完全相同,这意味着在方差相等的情况下,结果和结论不会改变。
第一种方法的优点是很容易从 ANOVA(方差相等时使用)切换到 Welch 检验(方差不相等时使用)。这可以通过用var.equal = FALSE
替换var.equal = TRUE
来实现,如下所示:
***oneway.test(flipper_length_mm ~ species,
data = dat,
var.equal = FALSE # assuming unequal variances
)##
## One-way analysis of means (not assuming equal variances)
##
## data: flipper_length_mm and species
## F = 614.01, num df = 2.00, denom df = 172.76, p-value < 2.2e-16***
然而,第二种方法的优点是:
- 完整的 ANOVA 表(含自由度、均方差等。)打印出来,这在某些(理论上的)情况下可能是有意义的
- 方差分析(
res_aov
)的结果可以保存以备后用(对事后检验特别有用)
方差分析结果的解释
鉴于p-值小于 0.05,我们拒绝零假设,因此我们拒绝所有均值相等的假设。因此,我们可以断定至少有一个物种在脚蹼长度(p-value<2.2e-16)方面与其他物种不同。****
(为了便于说明,如果p-值大于 0.05:我们不能拒绝所有平均值相等的零假设,因此我们不能拒绝所考虑的三种企鹅的鳍长度相等的假设。)
在 R 中报告方差分析结果的一种简单而又好的方法是使用{report}
包中的report()
函数:
***# install.packages("remotes")
# remotes::install_github("easystats/report") # You only need to do that once
library("report") # Load the package every time you start Rreport(res_aov)## The ANOVA (formula: flipper_length_mm ~ species) suggests that:
##
## - The main effect of species is significant and large (F(2, 339) = 594.80, p < .001; Eta2 = 0.78, 90% CI [0.75, 0.80])
##
## Effect sizes were labelled following Field's (2013) recommendations.***
如您所见,该函数为您解释了结果,并显示了物种对鳍状肢长度的大而显著的主要影响(p-值【t 33.001】)。
注意report()
功能可用于其他分析。如果你觉得这个有用,请查看 R 中的更多提示和技巧。
下一步是什么?
如果零假设没有被拒绝 ( p -value ≥ 0.05),则说明我们没有拒绝所有组都相等的假设。方差分析差不多到此为止。当然,也可以进行其他类型的分析,但是——根据手头的数据——我们无法证明至少有一组是不同的,所以我们通常不会进一步进行方差分析。****
相反,如果零假设被拒绝(因为这是我们的情况,因为p-值< 0.05),我们证明至少有一组是不同的。如果我们只对检验所有物种的鳍状肢长度是否相等感兴趣,我们可以决定就此打住。****
但是大多数时候,当我们通过方差分析表明至少有一个群体是不同的时候,我们也有兴趣知道哪一个群体是不同的。然而,方差分析的结果是 而不是 告诉我们哪一组与其他组不同。
为了测试这一点,我们需要使用其他类型的测试,称为事后测试(在拉丁语中,“在此之后”,因此在获得具有统计意义的 ANOVA 结果之后)或多个成对比较测试。这一系列的统计测试是下面几节的主题。
事后测试
多重测试问题
为了看出哪一组与其他组不同,我们需要对两组进行比较。实际上,由于有 3 个物种,我们将按如下方式比较物种 2 和 2:****
- 下颚带对抗阿德利
- Gentoo 对 Adelie
- Gentoo vs. Chinstrap
理论上,我们可以通过 3 个学生的 t 检验来比较物种,因为我们需要比较两个组,在这种情况下 t 检验被精确地使用。
但是,如果执行了几个 t 测试,就会出现多重测试(也称为多重性)的问题。简而言之,当几个统计测试被执行时,一些会有p-值小于α纯属偶然,即使所有的无效假设事实上都是真的。****
为了演示这个问题,考虑我们的情况,我们有 3 个假设要测试,期望的显著性水平为 0.05。偶然观察到至少一个重要结果(至少一个p-值< 0.05)的概率为:
因此,只要考虑 3 个测试,我们就有 14.26%的机会观察到至少一个显著的结果,即使所有的测试实际上都不显著。
随着组数的增加,比较的次数也在增加,所以仅仅因为偶然而产生重要结果的概率也在增加。例如,对于 10 个组,我们需要进行 45 次比较,至少有一个重要结果的概率变成 1−(1−0.05)^45 = 90%。因此,当比较 10 组时,很可能只是偶然观察到显著的结果,而当我们有 14 组或更多组时,我们几乎肯定(99%)有假阳性!
事后检验考虑到进行了多次检验,并通过以某种方式调整α来处理问题,因此,由于偶然性而观察到至少一个显著结果的概率保持在我们期望的显著性水平以下。 4
R 中的事后检验及其解释
事后测试是一系列统计测试,所以有几种。最常用的是 Tukey HSD 和 Dunnett 的测试:
- Tukey HSD 用于比较所有组(因此所有可能的 2 组比较)。****
- Dunnett 用于与参照组进行比较。例如,考虑 2 个治疗组和 1 个对照组。如果您只想将 2 个治疗组与对照组进行比较,而不想将 2 个治疗组进行相互比较,则首选 Dunnett 检验。
请注意,假设两个测试的方差相等。它们将在下一节中介绍。如果方差不相等,可以使用 Games-Howell 检验等方法。
图基 HSD 试验
在我们的例子中,由于没有“参考”物种,我们对比较所有物种感兴趣,我们将使用 Tukey HSD 测试。
在 R 中,Tukey HSD 测试如下进行。这就是执行 ANOVA 的第二种方法派上用场的地方,因为结果(res_aov
)被重新用于事后检验:
***library(multcomp)# Tukey HSD test:
post_test <- glht(res_aov,
linfct = mcp(species = "Tukey")
)summary(post_test)##
## Simultaneous Tests for General Linear Hypotheses
##
## Multiple Comparisons of Means: Tukey Contrasts
##
##
## Fit: aov(formula = flipper_length_mm ~ species, data = dat)
##
## Linear Hypotheses:
## Estimate Std. Error t value Pr(>|t|)
## Chinstrap - Adelie == 0 5.8699 0.9699 6.052 <1e-08 ***
## Gentoo - Adelie == 0 27.2333 0.8067 33.760 <1e-08 ***
## Gentoo - Chinstrap == 0 21.3635 1.0036 21.286 <1e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## (Adjusted p values reported -- single-step method)***
在 Tukey HSD 测试的输出中,我们感兴趣的是在Linear Hypotheses:
之后显示的表格,更准确地说,是表格的第一列和最后一列。第一列显示已经进行的比较;最后一列(Pr(>|t|)
)显示每次比较的调整后的5p-值(零假设为两组相等,替代假设为两组不同)。
正是这些调整后的 p 值用于测试两组是否有显著差异,我们可以确信整个比较集合的误差率为 0.05。
在我们的示例中,我们测试了:
- 下颚带对抗阿德利(第
Chinstrap - Adelie == 0
行) - 巴布亚对阿德利(线
Gentoo - Adelie == 0
) - Gentoo vs. Chinstrap(第
Gentoo - Chinstrap == 0
行)
所有三个p-值都小于 0.05,因此我们拒绝所有比较的零假设,这意味着所有物种在鳍状肢长度方面都有显著差异。****
事后测试的结果可以通过plot()
功能可视化:
***par(mar = c(3, 8, 3, 3))
plot(post_test)***
我们看到置信区间没有越过零线,这表明所有组都有显著差异。
请注意,Tukey HSD 测试也可以在 R 中使用TukeyHSD()
功能完成:
***TukeyHSD(res_aov)## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = flipper_length_mm ~ species, data = dat)
##
## $species
## diff lwr upr p adj
## Chinstrap-Adelie 5.869887 3.586583 8.153191 0
## Gentoo-Adelie 27.233349 25.334376 29.132323 0
## Gentoo-Chinstrap 21.363462 19.000841 23.726084 0***
对于这个代码,我们感兴趣的是列p adj
(也是最后一列)。请注意,结论与上面的相同:所有物种的鳍状肢长度都有显著差异。
结果也可以通过plot()
功能可视化:
***plot(TukeyHSD(res_aov))***
邓尼特试验
我们在本部分中已经看到,随着组数的增加,比较的次数也在增加。随着比较次数的增加,事后分析必须进一步降低个体显著性水平,这导致较低的统计功效*(因此群体中组均值之间的差异不太可能被检测到)。*****
减轻这种情况并提高统计功效的一种方法是减少比较次数。这种减少允许后特设过程使用更大的个体错误率来实现期望的全局错误率。虽然用 Tukey HSD 试验比较所有可能的组是一种常见的方法,但许多研究有一个对照组和几个治疗组。对于这些研究,您可能只需要将治疗组与对照组进行比较,这样可以减少比较的次数。
邓尼特的测试恰恰做到了这一点——它只是将一个群体与所有其他群体进行比较,而不是将所有群体相互比较。
概括一下:
- Tukey HSD 测试允许比较所有组,但代价是*更少的功率*******
- 邓尼特测试只允许与参照组进行比较,但好处是更有力量********
现在,再次为了说明起见,考虑物种Adelie
是参照物种,我们只对参照物种与其他两个物种的比较感兴趣。在这种情况下,我们将使用邓尼特测试。
在 R 中,Dunnett 测试按如下方式进行(与 Tukey HSD 测试代码的唯一区别是在第linfct = mcp(species = "Dunnett")
行):
***library(multcomp)# Dunnett's test:
post_test <- glht(res_aov,
linfct = mcp(species = "Dunnett")
)summary(post_test)##
## Simultaneous Tests for General Linear Hypotheses
##
## Multiple Comparisons of Means: Dunnett Contrasts
##
##
## Fit: aov(formula = flipper_length_mm ~ species, data = dat)
##
## Linear Hypotheses:
## Estimate Std. Error t value Pr(>|t|)
## Chinstrap - Adelie == 0 5.8699 0.9699 6.052 7.59e-09 ***
## Gentoo - Adelie == 0 27.2333 0.8067 33.760 < 1e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## (Adjusted p values reported -- single-step method)***
解释与 Tukey HSD 试验相同,除了在 Dunett 试验中,我们只比较:
- 下颚带对抗阿德利(第
Chinstrap - Adelie == 0
行) - Gentoo vs. Adelie(第
Gentoo - Adelie == 0
行)
两个p-值(显示在最后一列)都低于 0.05,因此我们拒绝两个比较的零假设。这意味着物种下巴颏带和巴布亚企鹅在鳍状肢长度方面与参照物种阿德利有显著差异。(不过,关于 Chinstrap 和 Gentoo 之间的比较,没什么可说的。)**
同样,事后测试的结果可以通过plot()
功能可视化:
***par(mar = c(3, 8, 3, 3))
plot(post_test)***
我们看到置信区间没有越过零线,这表明 Gentoo 和 Chinstrap 两个物种都与参考物种 Adelie 显著不同。
注意,在 R 中,默认情况下,因子变量的参考类别是字母顺序中的第一个类别。这就是默认情况下参考物种是阿德利的原因。
可以用relevel()
功能(或用[{questionr}](https://www.statsandr.com/blog/rstudio-addins-or-how-to-make-your-coding-life-easier/#reordering-factors)
插件)改变参考类别。考虑到我们希望 Gentoo 而不是 Adelie 作为参考类别:
***# Change reference category:
dat$species <- relevel(dat$species, ref = "Gentoo")# Check that Gentoo is the reference category:
levels(dat$species)## [1] "Gentoo" "Adelie" "Chinstrap"***
Gentoo 现在是三个类别中的第一个,它确实被认为是参考级别。
为了使用新的参考值执行 Dunnett 检验,我们首先需要重新运行 ANOVA 以考虑新的参考值:
***res_aov2 <- aov(flipper_length_mm ~ species,
data = dat
)***
然后,我们可以使用方差分析的新结果运行 Dunett 检验:
***# Dunnett's test:
post_test <- glht(res_aov2,
linfct = mcp(species = "Dunnett")
)summary(post_test)##
## Simultaneous Tests for General Linear Hypotheses
##
## Multiple Comparisons of Means: Dunnett Contrasts
##
##
## Fit: aov(formula = flipper_length_mm ~ species, data = dat)
##
## Linear Hypotheses:
## Estimate Std. Error t value Pr(>|t|)
## Adelie - Gentoo == 0 -27.2333 0.8067 -33.76 <1e-10 ***
## Chinstrap - Gentoo == 0 -21.3635 1.0036 -21.29 <1e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## (Adjusted p values reported -- single-step method)par(mar = c(3, 8, 3, 3))
plot(post_test)***
根据以上结果,我们得出结论,阿德利和下巴颏物种在鳍状肢长度方面与巴布亚物种有显著差异(p-值< 1e-10)。
请注意,即使您的研究没有可以与其他组进行比较的参考组,进行由一些研究问题决定的多重比较通常也比进行所有成对测试要好。通过将事后比较的数量减少到必要的数量,你可以最大化统计能力。 6
其他 p 值校正方法
对于感兴趣的读者,请注意,通过使用pairwise.t.test()
功能,您可以使用其他 p 值调整方法:
***pairwise.t.test(dat$flipper_length_mm, dat$species,
p.adjust.method = "holm"
)##
## Pairwise comparisons using t tests with pooled SD
##
## data: dat$flipper_length_mm and dat$species
##
## Gentoo Adelie
## Adelie < 2e-16 -
## Chinstrap < 2e-16 3.8e-09
##
## P value adjustment method: holm***
默认情况下,将应用 Holm 方法,但也存在其他方法。参见?p.adjust
了解所有可用选项。
同一地块上方差分析和事后检验的可视化
如果你有兴趣在同一个图上(直接在箱线图上)包括方差分析和事后测试的结果,这里有一段你可能感兴趣的代码(我根据这篇文章中的代码编辑的):
***# Edit from here
x <- which(names(dat) == "species") # name of grouping variable
y <- which(
names(dat) == "flipper_length_mm" # names of variables to test
)
method1 <- "anova" # one of "anova" or "kruskal.test"
method2 <- "t.test" # one of "wilcox.test" or "t.test"
my_comparisons <- list(c("Chinstrap", "Adelie"), c("Gentoo", "Adelie"), c("Gentoo", "Chinstrap")) # comparisons for post-hoc tests
# Edit until here # Edit at your own risk
library(ggpubr)
for (i in y) {
for (j in x) {
p <- ggboxplot(dat,
x = colnames(dat[j]), y = colnames(dat[i]),
color = colnames(dat[j]),
legend = "none",
palette = "npg",
add = "jitter"
)
print(
p + stat_compare_means(aes(label = paste0(..method.., ", p-value = ", ..p.format..)),
method = method1, label.y = max(dat[, i], na.rm = TRUE)
)
+ stat_compare_means(comparisons = my_comparisons, method = method2, label = "p.format") # remove if p-value of ANOVA or Kruskal-Wallis test >= alpha
)
}
}***
正如你在上面的图上看到的,物种的箱线图与方差分析和事后检验的 p 值一起显示。
除了在同一个图上结合了可视化表示和结果的事实之外,这段代码还具有可以一次执行多个 ANOVA 测试的优点。更多信息请参见本文的部分。
摘要
在本文中,我们回顾了 ANOVA 的目标和假设,在能够信任结果之前需要验证哪些假设(即独立性、正态性和同质性),然后我们向展示了如何在 R 中进行 ANOVA,以及如何解释结果。
如果不讨论事后检验,特别是Tukey HSD——比较所有组——和 Dunnett 的检验——比较一个参照组和所有其他组,那么一篇关于方差分析的文章就不完整。
最后但同样重要的是,我们展示了如何在同一个图中可视化方差分析和事后检验的数据和结果。
感谢阅读。
和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。
- 请注意,它被称为单向或单因素* ANOVA,因为均值与单个自变量或因素的不同模态相关。 ↩︎***
- 残差(表示为ϵϵ)是因变量的观测值(y)和预测值(y hat)之间的差值。在 ANOVA 的上下文中,残差对应于观察值和该组所有值的平均值之间的差异。 ↩︎
- 只要你使用 Kruskal-Wallis 检验来比较各组,就不需要同质性。如果你想比较中位数,Kruskal-Wallis 检验需要同质性。在这篇文章中查看更多关于差异的信息。 ↩︎
- 注意,正如在文章末尾的评论中所讨论的,事后检验在某些情况下可以直接进行(不需要 ANOVA)。详见许( 1996 )的评论。 ↩︎
- 请注意,原则上您可以将 Bonferroni 校正应用于所有测试。例如,在上面的例子中,有 3 个测试和α = 0.05 的全局期望显著性水平,如果p-值小于 0.05 / 3 = 0.0167,我们将拒绝零假设。然而,已知这种方法相当保守,导致潜在的高假阴性率。 ↩︎**
- 调整p-值,将全局显著性水平保持在所需水平。 ↩︎**
- 感谢 Michael Friendly 的建议。 ↩︎
相关文章
- 一次比例和拟合优度检验(R 和手动)
- 如何手工进行单样本 t 检验,并对一个均值进行 R:检验
- R 中的 Wilcoxon 检验:如何在非正态假设下比较两组
- 如何在 R 中一次对多个变量进行 t 检验或方差分析
- 学生的 R 和手工 t 检验:如何在不同场景下比较两组
原载于 2020 年 10 月 12 日 https://statsandr.com。
Python 中的 ANOVA + Tukey 测试
使用 Python 中的统计测试方法开发在线广告策略(附代码)。
方案
我们的客户是一家刚起步的服装公司,在美国专门生产休闲服装。他们的营销团队想推出一个广告活动来增加其网站的在线流量,这有望带来更多的收入。为了更好地分配投放广告活动的时间和精力,并最大限度地让观众看到他们的广告,他们需要了解 3 件事。
消费者搜索最多的与运动休闲相关的关键词是什么?
哪个月消费者搜索休闲服装最多?
消费者使用最多的搜索平台是哪个?
目标
向 athleisure 初创公司提供建议,以确定投放广告的最佳关键词、最佳时机和最佳平台。
数据
为了收集这个案例研究的数据,我们将使用Wordtracker——一种用于搜索引擎优化(SEO)的付费数据库服务。搜索引擎优化本质上只是另一种说法:
“我想知道如何让我的网站成为给定搜索的首要结果。”
Wordtracker 帮助客户获得更多的网站流量,或者更好地了解消费者在搜索什么。Wordtracker 类似于 Google Keywords Planner 服务,但允许访问 Google 以外平台上的搜索数据。在提取数据时,Wordtracker 提供了 2018 年 6 月至 2019 年 5 月在谷歌、Youtube、亚马逊和易贝的 1 年代表性搜索数据样本。它提供了来自 106 个国家的 1800 万全球小组成员的超过 20 亿个独特的关键词。以下是 Wordtracker 数据库中与美国搜索量相关的所有数据的概要。
来源:Alex Cheng+Justin FleuryviaGitHub
但是我们如何决定在 Wordtracker 的搜索量查询中选择哪些与“运动休闲”相关的词呢?有很多方法,但是有什么比在网上购买运动休闲流行语更好的方法呢?我们可以在亚马逊上搜索术语**“运动休闲”**,并在结果中找到所有最频繁出现的术语。
来源:Alex Cheng+Justin FleuryviaGitHub
因此,在我们的研究中,我们可以通过以下约束条件从 Wordtracker 中提取数据:
- 70 多个与运动休闲相关的术语,在搜索“运动休闲”时使用顶级亚马逊关键词结果。
- 仅在美国搜索卷。
- 来自谷歌、YouTube 和亚马逊的搜索量数据。
根据搜索引擎杂志——谷歌、YouTube 和亚马逊是全球最受欢迎的三大搜索引擎。根据 2019 年的 Bluelist 统计,每年大约有 2 万亿次谷歌搜索。Wordtracker 在一年时间内提供了近 20 亿次谷歌搜索。我们假设 Wordtracker 提供了全世界整个 Google 搜索数据库的大约 1/1000 的代表性样本。
清理后的数据集可以下载 这里 为. csv 文件。关于如何从 Wordtracker 的 API 调用数据的完整代码,请参考这个 Jupyter 笔记本 这里 。有关如何清理数据的更多信息,请参考数据清理 Jupyter 笔记本 此处 。
探索性数据分析
Tableau 仪表板
一旦数据被提取和清理,我们就可以执行 探索性数据分析 ,简称 EDA。创建 Tableau 仪表板是在一个地方全面了解数据中的维度和度量之间的各种关系的好方法。下面显示了该仪表板的静态预览。完全互动的 Tableau 仪表盘可以在 这里 探索。
来源:Alex Cheng+Justin FleuryviaGitHub
单词云
一组词汇云提供了一种非技术性的、图形化的尺度感,来理解每个搜索引擎中搜索次数最多的休闲词汇。关键词在词云中出现的越大,那么与其他关键词相比,该关键词被搜索的次数就越多。
每月平均关键词搜索量—折线图
这个线形图显示了一年中每个月平均搜索 athleisure 关键字的频率。寒冷月份的搜索次数似乎比温暖月份多,高峰在 12 月。
来源:Alex Cheng+Justin FleuryviaGitHub
每个关键字的总搜索量—条形图
当我们在所有三个搜索引擎(Google + YouTube + Amazon)上汇总所有运动休闲相关关键词的搜索量时,我们注意到关键词“hoodie”是搜索次数最多的术语,有 130 万次搜索。其次是“运动衫”、“跑步”、“锻炼”和“flex”,都有几十万次搜索。在考虑的所有 77 个关键词中,平均搜索次数约为 100,000 次。
来源:Alex Cheng+Justin FleuryviaGitHub
每个引擎的总容量和“运动休闲”搜索比率—条形图
在观察每个搜索引擎的指标时,我们发现与谷歌相比,亚马逊和 YouTube 的总搜索量非常低。但是,尽管亚马逊的整体搜索量最低,但它的运动休闲相关词汇的比例却是最高的。亚马逊上超过 25%的搜索都与运动休闲关键词相关!相比之下,YouTube 上 5%的搜索与运动休闲关键词相关。谷歌上只有不到 1%的搜索与运动休闲关键词相关。这些发现表明,亚马逊和 Youtube 可能比谷歌更适合运行广告,因为人们显然更经常在这些平台上搜索休闲关键词。
在左边的柱状图中,我们可以看到谷歌的总搜索量接近 600,000,000,而亚马逊和 YouTube 的总搜索量不到 100,000,000。然而,在右边的柱状图中,我们可以看到与运动休闲相关的术语的搜索比率,与每个搜索引擎上的所有搜索相比。
来源:Alex Cheng+Justin FleuryviaGitHub
概率密度函数
下面的概率密度函数图显示,我们相当多的关键词的搜索量很小——与我们的其他关键词相比,接近于零。显然,有些关键词的搜索率比其他关键词高得多,而高搜索率的关键词很少。
来源:Alex Cheng+Justin FleuryviaGitHub
累积密度函数
下面的累积密度函数图显示,我们 90%的关键词的搜索量低于 200,000。再一次,这避免了我们的大量关键词具有低搜索量,并且只有少数高搜索关键词。这个 CDF 图似乎是对数性质的。
来源:Alex Cheng+Justin FleuryviaGitHub
统计测试
在我们进入变量的统计检验之前,下面是假设检验和我们将用来确定统计显著性的概念的简要概述。
假设检验
很简单地说——零假设(H0) 是声称变量之间不存在统计显著关系的假设,而替代假设(HA) 则声称变量之间存在统计显著关系。
阿尔法值
α值是当零假设为真时拒绝零假设的概率。这也称为假阳性或 I 型错误。我们在每个假设检验中选择α值。
较高的alpha 值意味着我们可以接受较高的错误概率,而较低的alpha 值意味着我们可以接受非常低的错误概率。当出现错误时没有大的后果时,较高的 alpha 值可能是可以的,而当出现错误时有可怕的后果时(如医疗诊断、刑事判决或任何危及生命的情况),应该使用较低的 alpha 值。****
Alpha 值通常介于小于 0.01 和 0.1 之间。对于我们的案例研究,我们可以使用一个既不太宽松也不太严格的α值。因此,我们将使用 0.05 的 alpha 值。
p 值
p 值 是反对零假设的“证据”。p 值越小,我们可以拒绝零假设的证据就越强。我们将 p 值与为统计测试设置的 alpha 值进行比较。
- 如果 p 值是< 0.05, then we reject the null hypothesis.
- If the p-value is > = 0.05,那么我们无法拒绝零假设。
方差分析
单向方差分析或 ANOVA 是我们选择的统计测试,因为我们要处理多个组。我们还将使用双因素方差分析来确定可能具有统计显著性的因素组合。
图基试验
ANOVA 的问题是它只比较组间的平均值,并确定这些平均值是否有统计学上的显著差异。简而言之:方差分析告诉我们结果是否显著,但没有告诉我们结果在哪里显著。
但是,为了指导我们的运动休闲广告策略,统计意义的可解释性是至关重要的。我们必须能够解释哪些关键词表现最好,哪个搜索引擎最好,或者哪个月最适合投放广告!
因此, Tukey 检验 允许我们解释 ANOVA 检验的统计意义,并找出哪些特定组的均值(相互比较)不同。因此,在进行每一轮方差分析后,我们应该使用 Tukey 检验来找出数据中出现统计显著性的地方。
单向 ANOVA + Tukey 检验
假设检验 1:关键词
问题:当考虑搜索量时,与 athleisure 相关的关键词有什么区别吗?
零假设(H0) —就平均搜索量而言,所有与运动休闲相关的关键词都是相同的。
替代假设(HA) —一些与运动休闲相关的关键词比其他关键词有更大的平均搜索量。
单因素方差分析结果:
p 值= 1.3293563590514185 e-119< 0.05 (This is nearly zero.)
We reject the null hypothesis that mean search volume is equal across all athleisure-related keywords. Keyword on its own, does indeed constitute a difference in average search volume for athleisure-related items.
Tukey 测试结果:
统计上与其他术语“最”不同的前 5 个术语是:
- “帽衫”
- “跑步”
- “运动衫”
- “锻炼”
- “弹性”
假设检验 2:月
问题:考虑搜索量时,月份之间有区别吗?
零假设(H0) —在任何给定的月份,人们搜索运动服相关词汇的可能性都是一样的。
替代假设(HA)——人们将更有可能根据月份搜索运动服相关的词汇。
单因素方差分析结果:
- p 值= 0.8831258135517717 > 0.05
- 我们无法拒绝所有月份的平均搜索量相等的无效假设。
- 月份本身并不构成运动休闲相关项目搜索量的差异。
Tukey 测试结果:
- 没有必要运行 Tukey 多重比较测试,因为我们在这里没有拒绝零假设。
假设检验 3:搜索引擎
当考虑搜索量时,搜索引擎之间有什么不同吗?
零假设(H0) —在任何平台上,运动服相关词汇的搜索量都是相等的。
替代假设(HA) —在一个特定的平台上,运动服相关术语的搜索量会更大。
单因素方差分析结果:
- p 值= 7.19196465389629e-18 < 0.05(这个几乎为零。)
- 我们拒绝所有搜索引擎的平均搜索量相等的无效假设。
- 搜索引擎本身,确实构成了运动休闲相关项目平均搜索量的差异。
Tukey 测试结果:
- 在所有情况下,拒绝零假设,即搜索引擎 1 与搜索引擎 2 在平均搜索量方面相等。
- 每个平台的搜索量都是不同的。
密码
下面是如何在 Python 中执行单向 ANOVA 和 Tukey 测试的代码片段示例。
对于单向 ANOVA,我们使用 SciPy 库(注意:也可以使用 Statsmodels 库)。我们将数据强制转换为字典,并将键提供给函数【scipy . stats . F _ one way(),该函数返回 F-statistic 和 p-value(这就是我们想要的)。
对于 Tukey 测试,我们为 pairwise_tukeyhsd() 函数分配一个变量,其中我们提供我们的响应变量(搜索量)、我们正在测试的组(在本例中是搜索引擎)和我们的 alpha 值(0.05)。然后,我们简单地打印结果。
多重方差分析+ Tukey 检验
所有三个因素之间的双因素方差分析将帮助我们了解这些因素的任何两个组合是否具有统计显著性。我们本质上想回答这个问题:
“我们能确定哪些特定的关键字/月份/搜索引擎的 2 因素组合产生最高的搜索量吗?”
组合 1:关键词+引擎
零假设(H0) —就平均搜索量而言,所有关键词/引擎组合都是相同的。
备选假设(HA) —一些关键词/引擎组合具有更大的平均搜索量。
双因素方差分析结果:
- p 值= 1.008919e-151 < 0.05 (This is nearly zero.)
- Reject the null hypothesis that the mean search volume is equal among all Keyword/Engine combinations. Tukey Test needed.
Tukey 测试结果:
- 有 10 个关键词/引擎组合在搜索量上有显著差异。
组合 2:关键字+月份
零假设(H0) —就平均搜索量而言,所有关键字/月份组合都是相同的。
备选假设(HA) —一些关键词/月份组合具有更大的平均搜索量。
双因素方差分析结果:
- p 值= 7.896266e-01 > 0.05
- 无法拒绝平均搜索量在关键字/月份组合中相等的无效假设。没有 Tukey 测试。
组合 3:引擎+月份
零假设(H0) —就平均搜索量而言,所有引擎/月份组合都是相同的。
替代假设(HA) —一些引擎/月份组合具有更大的平均搜索量。
双因素方差分析结果:
- p 值= 7.789742e-01 > 0.05
- 无法拒绝引擎/月份组合中平均搜索量相等的无效假设。没有 Tukey 测试。
密码
下面是如何在 Python 中执行双向 ANOVA 和 Tukey 测试的代码片段示例。
对于双向方差分析,我们提供了一个字符串“formula”来定义我们的组,如stats models . formula . API . ols()函数所要求的,将这个拟合的 ols()函数赋给一个变量,然后将该变量送入 sm.stats.anova_lm() 函数。在输出中,我们查看 PR( > F)列,它提供了我们的 p 值(这就是我们想要的)。
对于双向 ANOVA 之后的 Tukey 测试,我们将一个变量分配给pairwise _ tukeyhsd()函数,其中我们提供了我们的响应变量(搜索量)、我们正在测试的组(在本例中是关键字+搜索引擎的组合)以及我们的 alpha 值(0.05)。然后,我们将输出强制转换为数据帧,以便于分析和过滤,并添加一个“total_sum”列来合计每组中每个观察值的所有(真)零剔除。有非常多的组合,所以我们只显示前 20 个结果。
推荐
关键词
在所有平台和月份的测试中,有 5 个关键词优于任何其他与运动休闲相关的关键词。我们可能会建议广告活动使用这 5 个流行语:
- 【帽衫】
- “跑步”
- 《运动衫》
- “健身程序”
- 【flex】
发动机
广告不应该在谷歌上投放,因为它对运动休闲相关关键词的搜索量最低。如果搜索量是最重要的,那么我们会推荐 YouTube。如果市场份额是最重要的,那么我们会推荐亚马逊。
月
月份本身在统计上不足以作为一个提供可靠建议的因素。只有在与特定平台和一组关键字结合时,月份才应被视为一个因素。
关键词/引擎
以下是我们推荐给运动休闲服装创业公司的 10 大关键词/引擎组合,以帮助他们指导他们的在线广告工作。再次注意,谷歌不推荐作为一个平台来运行运动休闲广告。
改进+未来工作
丰富
- 我们可以确保作为休闲关键词测试的所有单词类型都是相似的。例如,使用所有名词,或所有形容词等…
- 我们可能会将结果限制在与服装明显相关的搜索上。例如,考虑将一个与“运动休闲”相关的形容词与一件衣服配对,例如:“透气连帽衫”、“透气短裤”、“条纹慢跑者”等
- 我们可能会确保所有被比较的平台在它们提供的服务上是相同的,以获得更好的准确性。例如,把谷歌比作必应,或者 YouTube 和 Vimeo,或者亚马逊和易贝。
未来的工作
- 我们可以探索每个引擎的搜索量统计数据,例如:年龄、性别或收入。
- 我们可以调查转换率——意思是谁在看完广告后真正购买了产品。
- 我们可以考虑在特定平台上投放广告的成本。例如,与亚马逊相比,谷歌上的广告成本是多少?
谢谢!
感谢您阅读这篇博客!我希望它是有用的,并使统计测试在当代、真实世界用例中的能力更加清晰。我愿意倾听您的想法和反馈!所有代码和数据都可以在我的 GitHub 资源库 找到。随时和我联系LinkedIn。
Python 和 SQL 的方差分析
理解为什么以及如何进行方差分析
T 方差分析(ANOVA)用于分析方差,包括评估两个变量之间的差异。这是一个有效的统计工具,用于分析财务或客户数据,有助于监控规划过程和成功管理项目。当您收集了一个分类自变量和一个数量因变量的数据时,应该使用单向 ANOVA。自变量应该至少有三个层次。这里,我们将使用 pyodbc 从 SQL 中获取一个临床试验数据集,在 Python 上运行 ANOVA 并解释结果。
ANOVA 是怎么来的?
在我们开始之前,先讲一点背景故事!在 ANOVA 之前,人们使用多重 t 检验来比较变量之间是否存在差异。随着世界的进步,数据变得更加庞大,群体的数量也在增加。做多重 t 检验是不可行的,因此 ANOVA 诞生了。请注意,如果您只想比较两组,请使用 t 检验
方差分析的步骤有哪些?
- 检查样本量,我们需要每组中相同数量的观察值。
- 计算每组的均方差。
- 计算均方误差。
- 通过将组间差异除以组内差异来计算 F 值。
- 使用 f 分布表确定零假设。
方差分析的假设有哪些?
- 夏皮罗-维尔克检验可用于检查残差的正态分布。零假设是数据来自正态分布。
- 巴特利特检验检查方差的同质性。零假设是来自方差相等的总体的样本。数据不是来自正态分布?尝试进行 Levene 测试。
数据是什么?
我们将使用的数据是临床试验数据。它显示了患者在三种不同药物下的记忆表现。为了从 SQL server 获取数据,我们将使用 Python 包 pyodbc。
输入所需的凭据后,我们通过执行以下命令获得所需的数据:
cursor.execute("SELECT Drug,(Mem_Score_After - Mem_Score_Before) as Diff FROM trials WHERE Drug IN ('A','S','T')")
获取数据后,我们可以将其传输到 pandas 进行进一步分析。如果我们通过药物描述和可视化目标变量值,我们得到:
药品描述
毒品箱线图
注:从箱线图和药物说明中可以看出,服用药物 A 的患者的记忆表现明显最好。
首先,需要对假设进行定义。
无效假设: 意思是不同药物的记忆表现是一样的。
交替假设: 意思是不同药物的记忆表现并不相同(可能是两种药物的意思相同,但不是全部)
现在让我们运行一个单向 ANOVA 测试,看看这些组是否确实不同。python 包统计数据用于这部分分析。
stats.f_oneway(df[‘Diff’][df[‘Drug’] == ‘A’],
df[‘Diff’][df[‘Drug’] == ‘S’],
df[‘Diff’][df[‘Drug’] == ‘T’])
方差分析得出的 P 值显著(P <0.05),
and therefore, we conclude that there are significant differences among treatments. The results show an F statistic of 22. If F value is bigger than F-critical, which is in our case, we reject the null hypothesis. If F value is smaller than F-critical, we accept the null hypothesis.
这有意义吗?让我们再想象一下。
药物直方图
我们可以看到,对于两个群体来说,他们之间的差异低于他们内部的差异。对于第三组,显示为蓝色,其分布似乎与其他两组完全不同。因此,我们的眼睛也告诉我们,蓝色显示的药物治疗与其他两种不同。
结论
我们做了一个基本的单向方差分析,看看是否有任何药物改善记忆表现。在获得显著结果和大于 F 临界值的 F 统计值后,我们得出结论,药物没有相同的效果。从直方图中我们可以看出,其中一种药物的性能比另外两种高得多。这是一个简单的数据集,如果它更复杂,我们将使用 Tukey HSD 测试来查看哪些组是不同的。
单因素方差分析是一种很好的方法,可以用来观察不同组之间是否存在差异,让它成为客户组、试验组或财务运营相关的实验组。我相信,如果你还没有将它们运用到你的工作中,你可以找到一种方法。
我欢迎反馈,如果您有问题,请告诉我。你可以在 LinkedIn 上找到我。
安斯科姆的四重奏,又名巨魔数据集
为什么你应该在下结论前绘制数据
马克·柯尼希在 Unsplash 上的照片
你有没有想过统计学家做什么是为了好玩?你可能会认为他们会喜欢去赌场,并通过告诉人们如何通过赌博来浪费金钱来破坏人们的夜晚。或者你可以想象一个人花一整天的时间掷硬币来测试它是公平的还是有偏见的。
但是你错了。事实上,当一个统计学家在寻找一点温和的娱乐时,他们会花时间*寻找有创意的方法来欺骗人们。*看看下面这个例子。
这是统计学家弗朗西斯·安斯科姆在 1973 年创建的数据集。我们这里有四个数据集(标为 I、II、III 和 IV,因为罗马数字很酷),每个数据集由 11 对 x 和 y 坐标组成。
(对于这个讨论来说,坐标实际代表什么量并不特别重要。如果你愿意,你可以自己做。x 可以是给定圣代冰淇淋的勺数,y 可以是我吃完所有冰淇淋所用的秒数。好吃。)
因为人类的大脑在从表格数据中收集信息方面是垃圾——即使对于这个小得可怜的数据集也是如此——让我们分别绘制出四个数据集并进行比较(如果您感兴趣,您可以查看 Python 代码来完成此操作这里)。
(为了便于比较,四个数据集的每一个都以相同的比例绘制在 x 轴和 y 轴上。)
你可能想知道我要说什么。这四个数据集似乎没有什么共同点——它们都显示出截然不同的趋势,只有傻瓜才会把它们混为一谈。
好吧,让我们看看当我们调用我们的老朋友线性回归时会发生什么。
啊哦…这是最适合他们所有人的同一系列!这是怎么发生的?
也许我们可以发现每组数据中 x 和 y 之间相关性的差异。
Correlation coefficient for:Dataset I: 0.81642051634484
Dataset II: 0.8162365060002428
Dataset III: 0.8162867394895982
Dataset IV: 0.8165214368885031
现在我们真的有麻烦了…相关系数基本上都是一样的!有什么方法可以将这些数据集与它们的汇总统计数据区分开来呢?
(Mean of x values, mean of y values) for:
Dataset I: (9.0, 7.5)
Dataset II: (9.0, 7.5)
Dataset III: (9.0, 7.5)
Dataset IV: (9.0, 7.5)
(Variance of x values, variance of y values) for:
Dataset I: (11.0, 4.13)
Dataset II: (11.0, 4.13)
Dataset III: (11.0, 4.12)
Dataset IV: (11.0, 4.12)
真是一场噩梦!尽管我们已经看到数据的形状和模式一点也不相似,但您可能想要用来描述每个数据集的大多数简单、直观的汇总统计数据对所有四个数据集来说都是相同的。
你可能会想,如果我们没有事先把数据绘制出来,会发生什么样的可怕事情。我们可能已经看到了相同的汇总统计数据,并假设所有四个数据集具有相同的分布。我们的结论——以及因此而采取的任何行动——都将是不切实际的。
因此,把这当作一个警示故事吧——尽管汇总统计数据肯定是有用的,可以为我们提供比我们仅仅盯着图表所能收集到的更精确的信息,但它们过于简单的本质也可能具有欺骗性。*在你的探索性数据分析中,永远不要跳过可视化数据:*以不同的方式绘制、重新绘制、再绘制,以尝试和揭示新的模式。
因为正如我们所看到的,冰冷、坚硬的数字可能在欺骗你。
学分和更多信息
Andrew Hetherington 是英国伦敦的一名见习精算师和数据爱好者。
数据集:Anscombe,F. J. (1973)。“统计分析中的图表”。美国统计学家。27 (1): 17–21.doi:10.1080/00031305.19478966。JSTOR 2682899。
Ansible —端口监控。
今天,我将向您展示 Ansible 如何简化我们在监控服务器间网络通信时可能面临的技术难题。
事实上,在像银行业这样高度敏感的行业中,港口受到严格的监管,只有必要的港口才允许 SecOps 开放。否则,不受监管的端口可能成为 DDOS 等网络攻击的诱人目标。
为了更容易地解释事情,让我们想象一组名为源的主机应该与另一组名为目标的主机通信,只通过授权的端口。
主机可以是 cloud、docker、VM、metal server……端口可以是任何(https 443、SMTP 25、PostgreSQL 5432、Ldap 389、elk 9200、Redis 6379 或任何其他定制端口)。
现在我们到了有趣的部分:)
众所周知,SRE/DevOps 最重要的职责是监控。那么,SRE 团队如何轻松有效地监控服务器间的端口通信,尤其是在大型库存上?
他们如何在每个网络修补程序后执行运行状况检查,以确认没有退化?
更重要的是,他们如何在服务中断期间快速可靠地检查问题是否来自主机网络内部通信问题?
编排前(Ansible,Terraform…),解决方案是创建一个 shell、PowerShell 或 python 脚本来 telnet 或 ping 任何目标主机。这种解决方案的最大缺点是必须在所有源服务器上一个接一个地手动启动脚本。
有了 Ansible,事情变得更加智能、自动化和简单。
事实上,我们可以创建一个任务(可以是 cron 作业),该任务将在所有源主机上执行,以通过定义的端口检查与所有目标主机的通信,并在出现问题时发送报告/警报。
现在让我们转到编码部分:)
我们将从创建 ansible 主任务开始:
roles/ansi ble-role-ports/tasks/main . yml
---
- name: Check global ports
wait_for:
host: "{{ item.name }}"
port: "{{ item.port }}"
state: started # Port should be open
delay: 0 # No wait before first check (sec)
timeout: 3 # Stop checking after timeout (sec)
ignore_errors: yes
with_items: "{{ server_to_test }}"
这是主要的 ansible 角色任务,指示将通过端口“item.port”从“item.name”远程登录到“server_to_test”中的主机列表。
现在让我们创建我们的游戏:
plays/ports/ports . yml
---
- name: check ports
hosts: "{{ host }}"
become: yes
become_user: root
roles:
- ansible-role-ports
这是一个可行的行动,它将使用清单中的源主机和目标主机来调用任务。
关于清单,它只是列出了主机(源和目标),每个主机都有一个 group_vars 参数,该参数指定了用于每组源服务器的目标主机和目标端口。
inventory/hosts-update . yml
source1:
hosts:
host1:
ansible_host: ip-source1-host1
host_name: source1-host1
host2:
ansible_host: ip-source1-host2
host_name: source1-host2
source2:
hosts:
host1:
ansible_host: ip-source2-host1
host_name: source2-host1
host2:
ansible_host: ip-source2-host2
host_name: source2-host2
target1:
hosts:
host1:
ansible_host: ip-target1-host1
host_name: target1-host1
host2:
ansible_host: ip-target1-host2
host_name: target1-host2
target2:
hosts:
host1:
ansible_host: ip-target2-host1
host_name: target2-host1
host2:
ansible_host: ip-target2-host2
host_name: target2-host2
最后是每组源主机的 group_vars:
inventory/group _ vars/source 1 . yml
---
server_to_test:
- {name: 'target1', port: 'port1'}#target1
- {name: 'target1', port: 'port2'}#target1
- {name: 'target2', port: 'port1'}#target2
- {name: 'target2', port: 'port2'}#target2
inventory/group _ vars/source 2 . yml
---
server_to_test:
- {name: 'target1', port: 'port3'}#target1
- {name: 'target1', port: 'port4'}#target1
该剧的用法如下:
---
ansible-playbook -i inventory/hosts-update.yml plays/ports/ports.yml — extra-vars ‘{“host”:”source1,source2”}’ -k -K -vv -u “USER”
Source1、source2 可由任何其他主机集更改。
我们结束了,所以一如既往,我希望你学到了新的东西。
再见:)
萨拉姆。