开始走数据科学之路(上) :熊猫系列
Photo by Jordan Rowland on Unsplash
既然我们已经迈出了数据科学的第一步,
我读到过学习的最好方法是写博客。因为我学习数据科学已经有一段时间了…
towardsdatascience.com](/first-step-in-data-science-with-python-numpy-5e99d6821953)
让我们继续沿着这条路走下去,探索周围的世界。在本帖中,我们将寻求解决更多的问题,这次使用的是熊猫。这将是一个两部分的系列,有趣的是,第一部分是关于系列。
熊猫?
Photo by Damian Patkowski on Unsplash
不,不是动物。虽然刚开始学的时候真的以为是以动物命名的。这并不奇怪,因为这种语言本身就是以一种蛇命名的。也许 Python 生态系统只是对动物有一种爱。后来我才知道,这种语言实际上是以巨蟒剧团的命名的,熊猫与功夫熊猫没有任何关系。尽管一旦你掌握了熊猫,你就可以在数据科学方面下功夫。
当我知道熊猫实际上是“盘”的意思时,我明白了很多。因为这就是我们在熊猫身上遇到的一切。我们有一些以表格结构排列的数据,我们使用不同的方法和属性来分析这些数据。如果你熟悉结构化查询语言(SQL),你会发现数据的组织方式有很多相似之处。如果没有,也不用担心。只是按行和列排列的数据。
根据文档,pandas 是一个 Python 包,它提供了快速、灵活和富有表现力的数据结构,旨在使处理“关系”或“标签”数据变得既简单又直观。Pandas 有两个主要的数据结构——一维的系列和二维的数据帧。在这一部分中,我们将查看系列,然后在下一部分中以此为基础来理解数据框架。
让我们编码
你可以在下面的链接中找到这篇文章的完整代码。
GitHub 是人们构建软件的地方。超过 2800 万人使用 GitHub 来发现、分享和贡献超过…
github.com](https://github.com/bajracharya-kshitij/pandas)
代码使用 Python3 和安装了 anaconda 的熊猫。见此处如何安装熊猫。
像往常一样,第一步是导入我们将要使用的包。所以,还是进口熊猫吧。
import pandas as pd
这里 pd 是 pandas 的别名,今后将用于访问 pandas 包中的方法和属性。
问题出在哪里?
随着 pandas 的安装和导入,我们已经准备好正式定义我们要在这里解决的问题。
问题
给你 5 个人的身高(英寸)和体重(磅),如下表所示:
+--------+--------------+-------------+
| Person | Height(inch) | Weight(lbs) |
+--------+--------------+-------------+
| A | 72 | 186 |
| B | 69 | 205 |
| C | 70 | 201 |
| D | 62 | 125 |
| E | 57 | 89 |
+--------+--------------+-------------+
后来发现,该表实际上遗漏了人 F 和 G 的条目,他们的身高分别是 65 英寸和 60 英寸,F 的体重是 121 磅,但是遗漏了 G 的体重数据。此外,发现所有高度的值都比它应有的值小 5 英寸,而所有重量的值都比它应有的值大 5 磅。如果可能的话,为每个人找到正确的体重指数(身体质量指数)。
解决办法
首先,我们从上表中创建一个身高的字典。字典的关键字是人名,值是相应的身高条目。
height_dictionary = {'A': 72, 'B': 69, 'C': 70, 'D': 62, 'E': 57}
现在,我们可以使用这个字典生成一个熊猫系列。
height_series = pd.Series(height_dictionary)
如果您现在打印height_series
,您将看到以下内容。
A 72
B 69
C 70
D 62
E 57
dtype: int64
该系列只是采用字典,并将键设置为索引,将值设置为相应的数据点。它与 NumPy 非常相似,因为我们可以使用整数索引来访问数据点。例如,如果我们打印height_series[1]
,它将打印出69
。但是 pandas 带来的好处是,现在我们也可以使用我们的自定义索引来访问数据点。所以,使用height['B']
也会生成相同的数字69
。
熊猫和 NumPy 关系密切,当我们和熊猫一起工作时,我们会经常看到 NumPy 的用法。接下来,让我们使用 NumPy 数组为权重创建一个熊猫系列。在此之前,我们需要导入 NumPy。
import numpy as np
当使用字典创建一个序列时,我们可以只传递一个参数,因为索引和数据点都是可用的。但是,为了使用 NumPy 数组创建序列,我们需要两个单独的数组——一个用于索引,另一个用于数据点。让我们创建这些数组。
weight_data = np.array([186, 205, 201, 125, 89])
weight_label = np.array(['A','B','C','D','E'])
接下来,我们提供这两个数组作为创建熊猫系列的参数。
weight_series = pd.Series(data=weight_data, index=weight_label)
weight_series
现在看起来如下:
A 186
B 205
C 201
D 125
E 89
dtype: int64
身高体重系列准备好了。但是现在我们发现表中缺少了一些数据。因此,我们为这些缺失的数据创建另一个系列。首先,我们将为缺失的高度创建一个系列。
missing_height = pd.Series([65,60],['F','G'])
这里,我们省略了数据和索引的显式定义,因为我们以默认顺序提供参数。此外,我们传递一个简单的 Python 列表,而不是 NumPy 数组,它也工作得很好。
missing_height
现在看起来如下:
F 65
G 60
dtype: int64
现在,我们对丢失的重量做同样的处理。这一次我们将改变索引和数据的顺序。为此,我们需要在参数中显式定义索引和数据,否则F
将被视为数据而121
将被视为索引。
missing_weight = pd.Series(index=['F'],data=[121])
这导致missing_weight
等于
F 121
dtype: int64
在这一点上,我们有四个系列,但这不是我们想要的。我们创造后两个系列只是因为我们之前错过了。我们真正想要的只是两个系列——一个是身高系列,一个是体重系列。所以,让我们继续把丢失的值添加到原始序列中。
updated_height_series = height_series.append(missing_height)
updated_weight_series = weight_series.append(missing_weight)
现在,我们有了updated_height_series
的完整数据:
A 72
B 69
C 70
D 62
E 57
F 65
G 60
dtype: int64
并且updated_weight_series
为:
A 186
B 205
C 201
D 125
E 89
F 121
dtype: int64
最后,我们只需要两个系列。但是现在我们发现这个系列的数据仍然是不正确的。这些人的身高被发现比正常情况下少了 5 磅,体重被发现比正常情况下多了 5 磅。让我们用correction_series
来纠正这一点。在这里,我们为 7 个人创建了一个包含 7 个条目的序列,其中每个条目都是 5。我们将使用 NumPy 的ones
方法来完成这项工作。
correction_series = pd.Series(5*np.ones(7),index=['A','B','C','D','E','F','G'])
你本来也可以做5+np.zeros(7)
。无论如何,我们现在有了一个如下所示的修正系列:
A 5.0
B 5.0
C 5.0
D 5.0
E 5.0
F 5.0
G 5.0
dtype: float64
最后,我们可以用这个修正系列来修正这两个系列。
corrected_height_series = updated_height_series + correction_series
corrected_weight_series = updated_weight_series - correction_series
我们现在有了corrected_height_series
作为:
A 77.0
B 74.0
C 75.0
D 67.0
E 62.0
F 70.0
G 65.0
dtype: float64
而corrected_weight_series
为:
A 181.0
B 200.0
C 196.0
D 120.0
E 84.0
F 116.0
G NaN
dtype: float64
注意,添加correction_series
后,系列的数据类型从int64
变为float64
,因为correction_series
创建了一个类型为float64
的系列。还要注意,对于corrected_weight_series
,G
的值不是数字NaN
。这是因为原始的updated_weight_series
不包含G
的条目。因此,当我们试图从一个不存在的值中减去 5 时,我们得到了一个NaN
。
由于 G 的重量是不可得的,我们不能计算 G 的身体质量指数。因此,让我们从corrected_height_series
和corrected_weight_series
中删除 G 的条目。
要从corrected_height_series
中移除 G 的条目,我们可以使用索引来删除该条目。
corrected_height_series.drop(['G'])
我们可以传递一个索引列表作为参数来删除想要的条目。但是,如果我们现在检查corrected_height_series
,我们将会看到什么都没有改变。
A 77.0
B 74.0
C 75.0
D 67.0
E 62.0
F 70.0
G 65.0
dtype: float64
pandas 这样做是为了避免数据意外丢失。为了使放置永久化,我们需要在drop
方法中指定另一个参数。这个参数叫做inplace
,必须设置为True
。在熊猫身上,inplace
的说法被用在许多方法中。让我们继续下去,使下降永久化。
corrected_height_series.drop(['G'],inplace=True)
现在,当我们检查原始序列corrected_height_series
时,G 的条目将被删除。
A 77.0
B 74.0
C 75.0
D 67.0
E 62.0
F 70.0
dtype: float64
对于重量的情况,G 的重量是不可得的。为了删除 G 的条目,我们可以简单地使用dropna
方法。使用上述drop
方法删除所选的指数及其数值。dropna
删除数据点不可用的所有指数。同样,我们需要指定inplace=True
,否则 drop 不会反映在原系列中。
corrected_weight_series.dropna(inplace=True)
现在我们有了corrected_weight_series
作为:
A 181.0
B 200.0
C 196.0
D 120.0
E 84.0
F 116.0
dtype: float64
最后,我们在两个系列中都有了想要的值。现在,是时候计算体重指数了。计算身体质量指数的公式如下:
我们看到我们需要以千克为单位的重量和以米为单位的高度。但是我们上面的数据是以磅为单位的重量和以英寸为单位的高度。因此,在应用公式之前,我们必须首先进行必要的转换。
我们知道,1 磅= 0.453592 千克,1 英寸= 0.0254 米,我们先用变量来定义这些。
lbs_to_kg_ratio = 0.453592
inch_to_meter_ratio = 0.0254
现在,我们可以使用 NumPy 的multiply
方法进行必要的转换。
weights_in_kg = np.multiply(corrected_weight_series,lbs_to_kg_ratio)
那么,weights_in_kg
就是:
A 82.100152
B 90.718400
C 88.904032
D 54.431040
E 38.101728
F 52.616672
dtype: float64
同样的,
heights_in_m = np.multiply(corrected_height_series,inch_to_meter_ratio)
导致heights_in_m
为:
A 1.9558
B 1.8796
C 1.9050
D 1.7018
E 1.5748
F 1.7780
dtype: float64
最后,我们可以用上面的公式来计算身体质量指数。
BMI = np.divide(weights_in_kg,np.square(heights_in_m))
这样我们得到的BMI
系列为:
A 21.463230
B 25.678196
C 24.498049
D 18.794449
E 15.363631
F 16.644083
dtype: float64
你觉得你已经会功夫了吗?等着看另一个熊猫对象——data frame。在第 2 部分中,我们将看看如何使用 DataFrame 解决同样的问题以及其他一些问题。
在第 1 部分中,我们开始走这条路,一路上,我们遇到了系列。
towardsdatascience.com](/beginning-to-walk-the-data-science-road-part-2-pandas-dataframe-c3e898499d90)
开始走数据科学之路(下) :熊猫数据框架
Photo by Jason Leung on Unsplash
在第 1 部分中,我们开始走这条路,一路上,我们遇到了系列。
既然我们已经迈出了数据科学的第一步,
towardsdatascience.com](/beginning-to-walk-the-data-science-road-part-1-pandas-series-920e2237c336)
但是我们的探索还没有结束。在这一部分,我们将看看另一个熊猫对象——data frame。我们将首先解决我们在系列中看到的相同的体重指数问题,然后进入一个稍微复杂一点的问题。
DataFrame 可能是熊猫中最重要也是最常用的对象。数据帧基本上是共享公共索引的一系列数据的集合,这就是我们首先看到系列的原因。数据帧在表格结构中以行和列的形式排列数据。
万一你忘了,让我们重新定义身体质量指数的问题。如果你确实记得,向前跳到解决方案。
问题 1
给你 5 个人的身高(英寸)和体重(磅),如下表所示:
+--------+--------------+-------------+
| Person | Height(inch) | Weight(lbs) |
+--------+--------------+-------------+
| A | 72 | 186 |
| B | 69 | 205 |
| C | 70 | 201 |
| D | 62 | 125 |
| E | 57 | 89 |
+--------+--------------+-------------+
后来发现,该表实际上遗漏了人 F 和 G 的条目,他们的身高分别是 65 英寸和 60 英寸,F 的体重是 121 磅,但是遗漏了 G 的体重数据。此外,发现所有高度的值都比它应有的值小 5 英寸,而所有重量的值都比它应有的值大 5 磅。如果可能的话,为每个人找到正确的体重指数(身体质量指数)。
解决方案 1
我们已经看到了使用级数的解决方案。现在,让我们尝试使用 DataFrame 解决相同的问题。同样,您可以在下面的链接中找到完整的代码。
GitHub 是人们构建软件的地方。超过 2800 万人使用 GitHub 来发现、分享和贡献超过…
github.com](https://github.com/bajracharya-kshitij/pandas)
首先,我们将使用 DataFrames 来表示给定的表。条目(也称为数据点)作为列表传递给数据参数,列名作为字符串列表传递给列参数。我们创建了两个数据框——一个是身高数据框,另一个是体重数据框。
height_df = pd.DataFrame(data=[['A',72],['B',69],['C',70],['D',62],['E',57]], columns=['Person','Height'])
weight_df = pd.DataFrame(data=[['A',186],['B',205],['C',201],['D',125],['E',89]], columns=['Person','Weight'])
接下来,我们检查数据帧的head
。Head 通过返回参数中定义的第一个n
行数,为我们提供了一个表格示例。在这种情况下,我们将定义n = 3
。
height_df.head(n=3)
它返回
如果没有将n
指定为 head 方法的参数,则返回前 5 行。
weight_df.head()
返回
现在,我们有两个数据帧,但实际上我们只是想要一个来表示给定的表。因此,我们将使用merge
方法连接两个数据帧。由于两个数据帧都有公共列 Person ,我们将使用它将它们合并成一个数据帧。
height_weight_df = pd.merge(height_df,weight_df,on='Person')
所以现在我们有height_weight_df
作为:
我们可以在这个数据框架上使用describe
方法来获得关于平均值、标准差、四分位数和其他的统计信息。
height_weight_df.describe()
返回
我们还可以使用info
方法来获得每一列中条目数量及其数据类型的更多细节。
height_weight_df.info()
info
方法的结果看起来是这样的:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5 entries, 0 to 4
Data columns (total 3 columns):
Person 5 non-null object
Height 5 non-null int64
Weight 5 non-null int64
dtypes: int64(2), object(1)
memory usage: 160.0+ bytes
describe
方法只显示身高和体重列的细节,而不显示人员列的细节。这是因为 Person 列中的条目属于object
类型;它们只是名字,不可能对名字进行统计操作,如均值、标准差和四分位数。这也可以通过info
方法来说明,该方法显示身高和体重属于int64
类型,而人属于object
类型。
实际的计算只针对身高和体重。person 列只使用一个公共索引将一对值绑定在一起。因此,让我们使用set_index
方法将 Person 列设置为这个数据帧的索引。set_index
接受一个列数组作为参数。
height_weight_df.set_index(['Person'])
但这不会改变原始数据帧中的任何内容。回想一下系列,熊猫不希望你不小心丢失信息。当我们在数据帧上设置新的索引时,我们会丢失现有的索引。当然,此刻索引只是默认的整数。尽管如此,为了使索引永久化,您必须声明您希望这个改变发生在inplace
。
height_weight_df.set_index(['Person'],inplace=True)
现在,如果我们检查height_weight_df
,我们会看到
info
方法现在只显示身高和体重列。
<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, A to E
Data columns (total 2 columns):
Height 5 non-null int64
Weight 5 non-null int64
dtypes: int64(2)
memory usage: 120.0+ bytes
我们已经用级数解决了。再解决这个问题有什么意义?
这里的要点是证明 DataFrame 只不过是由公共索引绑定在一起的一组序列。如果你打印出height_weight_df[‘Height’]
,它返回
Person
A 72
B 69
C 70
D 62
E 57
Name: Height, dtype: int64
这显然是一个系列。如果你打印出height_weight_df[‘Weight’]
,同样的事情也会发生。这表明身高和体重都是具有共同索引 A 到 e 的序列,这是列所关心的。现在,让我们看看行。如果使用height_weight_df.loc['A']
打印出 A 的行,我们得到
Height 72
Weight 186
Name: A, dtype: int64
也是一个系列。所以,A 到 E 也是拥有共同指数身高和体重的系列。我们可以使用type(height_weight_df[‘Height’])
和type(height_weight_df.loc[‘A’])
来查看这两者的类型。这两个人都回到了pandas.core.series.Series
。
现在我们清楚了数据帧是由系列组成的,让我们回到我们的问题。我们现在意识到 F 和 G 的身高和体重从表格中消失了。因此,我们为丢失的值创建另一个数据帧。
missing_df = pd.DataFrame(data=[[65,121],[60]],index=['F','G'],columns=['Height','Weight'])
missing_df
现在看起来是这样的
这里我们看到 G 的权重丢失了,所以取而代之的是一个NaN
值。接下来,为了获得单个数据帧,我们将这个missing_df
附加到原始的height_weight_df
中,
updated_df = height_weight_df.append(missing_df)
这样updated_df
就变成了
同样,我们发现每个人的身高减少了 5,体重增加了 5。所以,让我们修改一下。
updated_df['Height'] += 5
updated_df['Weight'] -= 5
这就把我们的updated_df
改成了
所有人的身高和体重已被正确更新,并可进一步用于计算身体质量指数。但是由于 G 的重量丢失,不可能计算出 G 的身体质量指数,所以我们把 G 的条目一起去掉。同样,我们需要指定inplace=True
来使其永久化。
updated_df.dropna(inplace=True)
然后移除 G 的条目。
既然我们已经正确地得到了所有的值,那么是时候找到身体质量指数了。我们已经知道,计算身体质量指数的公式如下:
要应用上述公式,首先必须将体重从磅转换为千克,将身高从英寸转换为米。我们知道,1 磅= 0.453592 千克,1 英寸= 0.0254 米,我们用变量来定义这些。
lbs_to_kg_ratio = 0.453592
inch_to_meter_ratio = 0.0254
使用上述比率,我们将数据框更新为所需的单位。
updated_df['Height'] *= inch_to_meter_ratio
updated_df['Weight'] *= lbs_to_kg_ratio
我们现在有updated_df
作为
现在我们已经有了正确单位的所有数据,我们可以使用上面的公式来计算身体质量指数。我们将一个新列BMI
添加到现有的数据帧中
updated_df['BMI'] = updated_df['Weight']/(updated_df['Height']**2)
所以updated_df
现在看起来像
最后,通过将索引标签设置为Person
,我们将这个数据帧导出到一个名为BMI.csv
的 csv 文件中。csv 文件保存在保存程序源代码的同一目录中。
updated_df.to_csv('BMI.csv',index_label='Person')
如果我们比较这两种方法,使用 DataFrame 方法会产生一个更简洁的问题解决方案;部分原因是我们可以用一个数据框架同时处理两个系列。
熊猫能做的就这些吗?
目前我们看到的只是对熊猫的简单利用。然而,当我们处理复杂的问题时,熊猫的真正力量变得显而易见。所以,现在让我们来看一个稍微复杂一点的问题,看看熊猫到底能做什么。这次我们将使用一个真实的数据集。
什么是数据集?
数据集只是在感兴趣的特定领域中收集的数据的集合。例如,可以有一个世界各国的数据集。该数据集可以包含特定年份世界各国的人口、按性别、年龄组划分的人口、各国的 GDP、预期寿命、识字率、婴儿死亡率以及各种其他数据。这些只是一堆毫无意义的数字。但是有了像熊猫这样的分析工具,我们可以从这个数据集产生有价值的见解,比如,一个国家的 GDP 和它的识字率之间有关系吗?或者婴儿死亡率和女性预期寿命的关系?这些是熊猫帮助我们解决的问题类型。 UCI 机器学习库包含许多有趣的数据集。一旦您熟悉了 DataFrame,您就可以尝试使用其中的一些数据集。在这篇文章中,我将使用一个相对简单的数据集,我们将在下一个问题中讨论。
问题 2
我们有一个数据集,其中包含司机在一段时间内的出行数据。数据集的描述如下:
一名司机每天开车上下班时使用一款应用程序追踪 GPS 坐标。该应用程序收集位置和海拔数据。该数据集中总结了大约 200 次旅行的数据。
使用数据集,查找
a)第一个、最后一个和第十个条目的详细信息,
b)每天的详细信息,
c)当一天的总行驶距离大于 90 但小于 100 时的条目,
d)c)单行的距离和燃油经济性,
e)当平均移动速度大于 90 时的星期五的条目,
f)当最大速度大于 135 或燃油经济性小于 8 时的条目,以及
g)
解决方案 2
我们从这个链接下载数据集,并将其保存在一个名为travel-times.csv
的文件中。现在,我们需要从 csv 文件中获取数据。read_csv
方法接受文件名作为参数,并返回一个 DataFrame。
travel_df = pd.read_csv('travel-times.csv')
此时此刻,我们并不真正知道数据集中有什么样的数据。在我们开始解决问题之前熟悉数据通常是一个好习惯。为了查看数据集中可用的数据类型,我们使用了返回 DataFrame 的前 5 行的head
方法。
travel_df.head()
返回以下内容
head
方法让我们熟悉了数据集中可用的列,并提供了一个数据样本。让我们通过使用describe
方法来了解更多的数据。
travel_df.describe()
describe
方法只列出原始数据帧中的 6 列。这是因为只有这 6 个是数字类型,因此它们的平均值、标准差、四分位数等也是数字类型。可以被计算出来。让我们用info
方法进一步验证这一点。
travel_df.info()
返回
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 205 entries, 0 to 204
Data columns (total 13 columns):
Date 205 non-null object
StartTime 205 non-null object
DayOfWeek 205 non-null object
GoingTo 205 non-null object
Distance 205 non-null float64
MaxSpeed 205 non-null float64
AvgSpeed 205 non-null float64
AvgMovingSpeed 205 non-null float64
FuelEconomy 188 non-null object
TotalTime 205 non-null float64
MovingTime 205 non-null float64
Take407All 205 non-null object
Comments 24 non-null object
dtypes: float64(6), object(7)
memory usage: 20.9+ KB
实际上只有 6 列是类型float64
。然而,我们从info
方法中发现了一些有趣的信息。总共有 13 列,其中 11 列有 205 个条目,但是FuelEconomy
只有 188 个,而Comments
字段只有 24 个。相对而言,这是非常少的数据,不能为我们提供太多信息。此外,我们的问题没有定义任何关于评论的东西。因为我们对评论不感兴趣,所以我们将放弃这个专栏。记住,我们需要声明inplace=True
来永久删除该列。
travel_df.drop(labels=['Comments'],axis=1,inplace=True)
如果没有定义 axis,它将被设置为 0,这意味着删除索引。为了删除一列,我们显式定义了axis=1
。同样,我们检查 head 和 info 方法。
travel_df.head()
travel_df.info()
它返回
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 205 entries, 0 to 204
Data columns (total 12 columns):
Date 205 non-null object
StartTime 205 non-null object
DayOfWeek 205 non-null object
GoingTo 205 non-null object
Distance 205 non-null float64
MaxSpeed 205 non-null float64
AvgSpeed 205 non-null float64
AvgMovingSpeed 205 non-null float64
FuelEconomy 188 non-null object
TotalTime 205 non-null float64
MovingTime 205 non-null float64
Take407All 205 non-null object
dtypes: float64(6), object(6)
memory usage: 19.3+ KB
现在,我们只剩下 12 列了。我们仍然在FuelEconomy
列中缺少我们感兴趣的数据。让我们看一个更大的样本,这样我们就可以看到 FuelEconomy 不是 NaN 的行。
travel_df.head(n=10)
我们看到FuelEconomy
列包含数字,但是info
方法将FuelEconomy
列的数据类型显示为object
。让我们用dtype
属性进一步验证这一点。
travel_df['FuelEconomy'].dtype
它返回dtype(‘O’)
。“O”表示它属于类型object
。通过查看上面的头部,我们可以看到它不仅包含NaN
s,还包含虚线(-)条目,类型为object
。在执行任何操作之前,我们需要将FuelEconomy
列转换为数字类型。为此,我们使用to_numeric
方法。
travel_df['FuelEconomy'] = pd.to_numeric(travel_df['FuelEconomy'],errors='coerce')
方法试图将一个字符串解析成一个数字。errors=’coerce’
将无法解析为数字的条目设置为NaN
。如果没有显式定义 errors,默认结果将是抛出一个异常,因为虚线(-)条目无法解析为数字。
现在,让我们再次看看 info 和 head 方法。travel_df.info()
现在退货
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 205 entries, 0 to 204
Data columns (total 12 columns):
Date 205 non-null object
StartTime 205 non-null object
DayOfWeek 205 non-null object
GoingTo 205 non-null object
Distance 205 non-null float64
MaxSpeed 205 non-null float64
AvgSpeed 205 non-null float64
AvgMovingSpeed 205 non-null float64
FuelEconomy 186 non-null float64
TotalTime 205 non-null float64
MovingTime 205 non-null float64
Take407All 205 non-null object
dtypes: float64(7), object(5)
memory usage: 19.3+ KB
而travel_df.head(n=10)
现在显示
FuelEconomy
的数据类型现在已经更改为float64
,现在有 186 个非空条目,因为虚线条目已经设置为NaN
。
为了执行进一步的计算,最好将所有数值都填满。移除NaN
值的一个常用方法是用列中可用值的平均值填充这些条目。为此,我们将fillna
方法与inplace=True
结合使用。
travel_df['FuelEconomy'].fillna(travel_df['FuelEconomy'].mean(),inplace=True)
head
现在显示
并且info
给出
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 205 entries, 0 to 204
Data columns (total 12 columns):
Date 205 non-null object
StartTime 205 non-null object
DayOfWeek 205 non-null object
GoingTo 205 non-null object
Distance 205 non-null float64
MaxSpeed 205 non-null float64
AvgSpeed 205 non-null float64
AvgMovingSpeed 205 non-null float64
FuelEconomy 205 non-null float64
TotalTime 205 non-null float64
MovingTime 205 non-null float64
Take407All 205 non-null object
dtypes: float64(7), object(5)
memory usage: 19.3+ KB
现在,我们在FuelEconomy
列中的所有 205 个值都用平均值填充了数据缺失的地方。
现在我们准备开始解决上面给出的问题。对于第一个问题,我们使用iloc
属性来查找数据帧中的第一个、最后一个和第 10 个条目。
travel_df.iloc[0]
给了我们第一排
Date 1/6/2012
StartTime 16:37
DayOfWeek Friday
GoingTo Home
Distance 51.29
MaxSpeed 127.4
AvgSpeed 78.3
AvgMovingSpeed 84.8
FuelEconomy 8.69059
TotalTime 39.3
MovingTime 36.3
Take407All No
Name: 0, dtype: object
我们可以看到这是一个系列。
类似地,我们可以使用travel_df.iloc[-1]
查找最后一行,使用travel_df.iloc[9]
查找第 10 个元素。
接下来,我们看到一个日期有多个条目。因此,让我们将数据分组,以便每个日期只有一个条目。我们尝试按照Date
列对数据帧进行分组。
travel_df_by_date = travel_df.groupby(['Date'])
如果我们通过使用type(travel_df_by_date)
来查看travel_df_by_date
的类型,我们将看到它返回pandas.core.groupby.DataFrameGroupBy
。所以travel_df_by_date
是一个DataFrameGroupBy
实例。为了组合具有相同日期的多行,我们在DataFrameGroupBy
实例上使用了sum
方法。
travel_df_by_date_combined = travel_df_by_date.sum()
该数据帧的head
返回
看我们的问题,也需要DayOfWeek
栏。但是使用sum
方法只能保留数字字段。因此,为了获得DayOfWeek
列,我们通过Date
和DayOfWeek
列以及结果DataFrameGroupBy
实例上的sum
进行分组。
travel_df_by_date = travel_df.groupby(['Date','DayOfWeek'])
travel_df_by_date_combined = travel_df_by_date.sum()
travel_df_by_date_combined
的head
显示
但是我们现在可以看到 DataFrame 现在有一些不正确的数据。按日期分组时,Distance
、TotalTime
和MovingTime
列的总和是正确的。但是通过使用sum
方法,我们还添加了MaxSpeed
、AvgSpeed
、AvgMovingSpeed
和FuelEconomy
列,这是不正确的。MaxSpeed
应包含特定日期各行的最大值,其他列应包含各行的平均值。所以,让我们修改一下。
travel_df_by_date_combined['MaxSpeed'] = travel_df_by_date['MaxSpeed'].max() travel_df_by_date_combined['AvgSpeed'] = travel_df_by_date['AvgSpeed'].mean() travel_df_by_date_combined['AvgMovingSpeed'] = travel_df_by_date['AvgMovingSpeed'].mean() travel_df_by_date_combined['FuelEconomy'] = travel_df_by_date['FuelEconomy'].mean()
现在,如果我们检查一下travel_df_by_date_combined
的head
,我们会看到
太好了。我们现在有了所有所需列的正确数据。现在让我们检查数据框travel_df_by_date_combined
上的info
。
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 111 entries, (1/2/2012, Monday) to (9/8/2011, Thursday)
Data columns (total 7 columns):
Distance 111 non-null float64
MaxSpeed 111 non-null float64
AvgSpeed 111 non-null float64
AvgMovingSpeed 111 non-null float64
FuelEconomy 111 non-null float64
TotalTime 111 non-null float64
MovingTime 111 non-null float64
dtypes: float64(7)
memory usage: 7.4+ KB
通过Date
和DayOfWeek
列进行分组产生了一个多索引数据帧,如 head 和 info 方法所示。但是我们希望DayOfWeek
是一个常规列,而不是索引。因此,我们首先重置索引,使数据帧的索引变成普通整数。在下一步中,我们将Date
列设置回索引。
travel_df_by_date_combined.reset_index(inplace=True)
这一次我们使用tail
方法查看最后 5 行,并且看到Date
和DayOfWeek
都被设置为常规列。
travel_df_by_date_combined.tail()
接下来,我们将Date
列设置为索引。
travel_df_by_date_combined.set_index(['Date'],inplace=True)
travel_df_by_date_combined
中的head
现在显示
完美。我们将Date
作为索引,我们还保留了DayOfWeek
列和所有其他数字列。每个日期都有一个条目。这是上面问题 b 的答案。
这么多工作只为了一个简单的答案。
是的。那是一个相当大的过程。但是不用担心。到目前为止,我们一直在准备数据,以便能够回答上述所有问题。从这里开始,事情就非常简单了。我们已经做了所有的艰苦工作。现在是收获我们所播种的东西的时候了。
现在,让我们找出距离大于 90 但小于 100 的条目。为此,我们使用条件选择。
distance_above_ninety = travel_df_by_date_combined['Distance']>90
这将导致distance_above_ninety
包含一系列布尔值。它的作用是,获取travel_df_by_date_combined[‘Distance’]
数据帧的每个条目,并检查它是否大于 90。如果是,它为结果序列中的相应条目设置True
;否则设置False
。请注意,该系列的索引将是Date
列。
同样,我们可以发现
distance_below_hundred = travel_df_by_date_combined['Distance']<100
现在我们可以把这两个数列结合起来,找出距离大于 90 小于 100 的Distance
。但是我们不能像在 Python 中那样使用*and*
操作符来组合distance_above_ninety
和distance_below_hundred
。这是因为*and*
操作符只作用于两个布尔值,但是这里我们处理的是两个布尔值序列。使用*and*
操作符会导致值错误:一个序列的真值是不明确的。为了找到一系列组合的真值,我们需要使用*&*
操作符。也就是我们用distance_above_ninety & distance_below_hundred
。
结合条件选择,
ninety_to_hundred_df = travel_df_by_date_combined[distance_above_ninety & distance_below_hundred]
我们得到一个数据帧,其中只有满足这两个条件的条目
我们可以看到所有的距离都在 90 到 100 之间。这解决了我们的问题 c。我们可以使用这个数据帧来解决问题 d。在问题 d 中,我们需要做的就是从上面的数据帧中提取任意行的详细信息。让我们用loc
得到最后一个日期的Distance
和FuelEconomy
。
ninety_to_hundred_df.loc[['8/26/2011'],['Distance','FuelEconomy']]
对于问题 e,我们再次使用组合条件选择来查找星期五平均移动速度高于 90 的条目。
over_ninety_on_friday = travel_df_by_date_combined[(travel_df_by_date_combined['AvgMovingSpeed']>90) & (travel_df_by_date_combined['DayOfWeek']=='Friday')]
和上面的条件选择一样。我们现在已经简单地在一行中写了所有的内容。
所有条目都是星期五的,每行的平均移动速度超过 90。
我们用同样的方法来解决问题 f。这里,我们需要最大速度大于 135 或者燃油经济性小于 8 的条目。就像在*and*
操作符的情况下,出于同样的原因,我们不能使用*or*
操作符。相反,我们使用管道(|)运算符。
max_speed_over_one_thirty_five_or_fuel_economy_below_eight = travel_df_by_date_combined[(travel_df_by_date_combined['MaxSpeed']>135) | (travel_df_by_date_combined['FuelEconomy']<8)]
这次我们有更多的行,因为只需要满足两个条件中的一个。有些条目的MaxSpeed
高于 135,有些条目的FuelEconomy
低于 8,有些条目两者都有。这就解决了问题 f。
最后,我们来看看一周中每一天的一些统计信息。DataFrameGroupBy 实例上应用的sum
方法提供了每一天中每一列的总和。
travel_df.groupby(['DayOfWeek']).sum()
请注意,这些列再次包含不正确的MaxSpeed
、AvgSpeed
、AvgMovingSpeed
和FuelEconomy
值。但是这里我们只是在演示sum
方法的作用。
同样,我们可以沿着各个日行找到每一列的max
值。max
方法也适用于非数字列。
travel_df.groupby(['DayOfWeek']).max()
也可以使用 describe 方法获得所有细节,如平均值、标准差、四分位数等。立刻。下面我们对其中一列AvgMovingSpeed
使用 describe 方法。
travel_df.groupby(['DayOfWeek'])['AvgMovingSpeed'].describe()
这解决了我们的最后一个问题。
我头疼。
我知道这很难接受。但是 DataFrame 是一个非常重要的主题,一旦你熟悉了它,你就可以选择你感兴趣的任何数据集,然后找到对数据的所需见解。同样,这篇文章没有涵盖 DataFrame 的所有方法和属性。这篇文章中所采取的一系列步骤可能不是解决问题的唯一途径。也许你可以找到另一种方法。更有效的方法。你需要的只是练习。只要像阿宝一样坚持下去,你也能成为功夫熊猫。
在下一篇文章中,我们将利用我们目前所学的知识,以一种更紧凑、更具视觉吸引力的方式将结果可视化。我们将使用 Matplotlib 包,特别是 pyplot 模块,最终用图形和图表来表示文本、数字和表格。
[## 冲刺可视化轨道(第 1 部分):Matplotlib
我们已经用 DataFrame 走了很久,
towardsdatascience.com](/sprinting-into-the-visualization-track-part-1-matplotlib-6c069ac91e40)
使用 Graphext 进行行为分析
为什么人们会这样做?他们为什么买产品,为什么辞职,为什么换伴侣?这些动机中的许多可以从人们的行为中归纳出来,这些行为反映在数据中。
公司拥有大量关于客户、员工、供应商的数据……让我们将这些数据用于智能数据发现,看看我们能学到什么。
我们将使用我们在 Kaggle 中找到的来自 IBM 人力资源部门的数据集来演示一个示例:https://www . ka ggle . com/pavansubhasht/IBM-HR-analytics-attraction-dataset
在这个数据集中,每一行代表一个雇员,而列是描述它们的不同变量。这些变量包括分类和定量信息。让我们将数据集上传到 Graphext 并查看一下:
在这个例子中,我们想要分析员工离开的原因。在原始数据集的二进制变量“LEFT”列中,1 表示一名员工已经离开,0 表示他们已经留下。从我们的分析中排除这个“目标变量”列,然后我们可以使用其余的变量来观察可能会或可能不会导致人才流失的行为模式。让我们来看看输出。
在这个可视化中,每个节点都是一个雇员。彼此相似的节点位置更近,反之亦然。因此,我们可以看到具有不同模式的数据图。我们使用我们自己的高级降维方法创建了这个网络,并在此基础上运行了网络中社区检测的聚类算法。
因为我们有一个要解释的目标变量,所以让我们用变量“LEFT”给数据集着色,看看它是如何分布的。
我们可以清楚地看到,以黄色表示的离职员工形成了不同的群体,表明他们有不同的行为模式,尽管他们都被归入了同一个“左派”类别。
使用预测模型的传统分析会从将所有“左”员工放在同一个篮子中开始,忽略了存在许多不同类型的“左”员工的事实。然而,使用智能数据发现,我们可以识别这些员工的行为模式,区分他们的行为,并在开始预测之前提出更好的问题。
让我们从人力资源的角度来看这个问题,把分析的重点放在“销售”部门和“低”工资的员工身上。通过点击这两个过滤器,我们可以缩小我们的数据选择。
现在,让我们用“左”或“不”来给员工涂色,看看这个小组的行为模式有何不同。
我们可以看到,至少有三组不同的员工“离开”了公司。
首先,我们选择左上方的集群,找出它们离开的原因。左边的面板会自动告诉我们是什么变量将这个群体从其他人群中分离出来。
Graphext 自动告诉我们它们是由以下分布定义的:
- 我们能看到的“项目数量”非常少
- “满意度”约为 4 分(满分 10 分),与整个人口相比也非常低
- “最后评价”在 4-6 分之间(满分 10 分),也非常低
- “平均月小时数”,低于平均值
现在让我们问一个问题,你会主动在你的公司留住这类员工吗?这些员工不开心,只在几个项目中工作过,而且上次评估很糟糕。如果你想留住他们,你可以根据他们的需求提供专门的培训项目。
让我们继续,选择下一批已经离开的员工。
在这种情况下,它们由以下分布定义:
- “平均每月小时数”,我们可以看到很高,但不是最高的
- “在公司度过的时间”,大约在 5 到 6 年达到顶峰
- “最后评价”,我们可以看到非常高,意味着他们是非常好的员工
- “满意度”,在分布中相当高,意味着他们很快乐
这些员工工作时间很长,对公司很满意。他们才是你真正想留住的人!这些员工离开可能是因为他们被另一家提供更高薪水的公司录用了。为了留住他们,惩罚计划可能会创造奇迹。
我们看到了两种截然不同的行为模式,需要不同的保持策略。用传统的预测模型分析这些数据会让你失去做出有实际影响的决策的机会。通过智能数据发现发现这些模式将允许您为每种特定行为创建更好的规范策略。
想了解更多?向我们索取演示!
行为克隆在自动驾驶汽车模拟赛道上的应用
最近我在 Udacity 上了一门课程,重点是无人驾驶汽车,所以我终于能够在课程中发布其中一个项目了。
这个项目,标题如上,有一个目标是训练一个模型在模拟轨道上自动驾驶汽车。该模型驾驶汽车的能力是通过克隆人类驾驶员的行为来学习的。训练数据从模拟器中的人类驾驶示例中获得,然后输入到深度学习网络中,该网络学习模拟中遇到的每一帧的响应(转向角度)。换句话说,该模型被训练为在驾驶时为每一帧预测适当的转向角度。然后,在新的轨迹上验证该模型,以检查用于执行转向角预测的学习特征的一般化。
我对这个项目的解决方案受到了 nvidia 论文、 comma.ai 论文和 vivek 博客的影响,我在制定解决方案时参考了这些论文。 Keras 深度学习库与 Tensorflow 后端一起使用,执行深度学习操作。
这篇文章组织如下:1。数据记录,2。数据处理,3。模特培训,4。模型测试;5 .结论。
1。数据记录
模拟器有两种模式——训练模式和自主模式。训练模式用于收集训练数据,方法是在赛道上行驶,并将行驶数据记录在文件夹中。自主模式用于测试经过训练的模型。
Self-Driving Car Simulator
Udacity 提供了一组训练数据(24,108 个数据集),可以通过模拟器下载。我认为 Udacity 数据集可能不够,所以我记录了自己的训练数据(104,145 个数据集),并将使用 Udacity 数据集进行验证。绘制 10,000 个训练数据样本的直方图显示,由于轨道的性质,来自轨道 1 的数据具有更多的 0°和左转向角,因此我们的处理步骤还将包括数据扩充和平衡,以防止我们的模型偏向于直行和左转。
2.数据处理
进行数据处理是为了让我们的模型能够轻松地处理用于训练的原始数据。在这个项目中,数据处理内置在一个生成器(keras fit_generator )中,以允许实时处理数据。这样做的好处是,在我们处理大量数据的情况下,整个数据集不会加载到内存中,因此我们可以一次处理一批可管理的数据。因此,为了提高效率,发电机与模型并行运行。
以下是对数据执行的处理步骤:
- **从中心、左、右摄像机图像中随机选择:**模拟器提供三个摄像机视图,即:中央、左侧和右侧视图。因为我们只需要使用一个摄像机视图,所以我们从三个视图中随机选择。在使用左右图像时,我们分别给转向角加上和减去 0.25,以补偿相机偏移 1 。
- **平移图像(抖动)并补偿转向角:**由于原始图像大小为 160x320 像素,我们随机将图像向左或向右平移,并以每平移像素 0.008 补偿转向角的平移。然后,我们从图像中裁剪出一个 120x220 像素的感兴趣区域。请注意,对于我的解决方案,我仅在水平方向平移。
- **随机翻转图像:**为了平衡左右图像,我们随机翻转图像并改变转向角的符号。下图显示了经过抖动、裁剪和角度校正后的左、右和中央摄像机的视图。右摄像机视图已经翻转,因此看起来像左摄像机图像。
- 增亮我们通过将图像转换为 HSV 通道,并随机缩放 V 通道来模拟不同的亮度场合。
Camera views after processing and steering angle compensation.
绘制 10,000 个已处理图像的样本显示了处理后转向角的更平衡的分布:
3.模特培训
采用 Nvidia 模型进行训练,因为它在试验了其他类型的模型(例如 comma.ai)后给出了更好的结果。该网络由 9 层组成,包括一个归一化层、5 个卷积层和 3 个全连接层。与 Nvidia 模型相反,输入图像在传送到网络之前被分割成 HSV 平面。
图像在第一层被标准化。根据 Nvidia 的论文,这使得标准化也可以通过 GPU 处理来加速。
卷积在前三层中使用 2x2 步长和 5x5 内核,非步长卷积在后两层中使用 3x3 内核。
卷积层之后是三个全连接层,然后输出转向角。
通过在所有层上使用积极的下降(0.2)和在第一层上使用 L2 正则化(0.001)来减少过拟合。这被证明是一个很好的实践,因为该模型可以推广到第二个轨道,而无需将其用于培训。
Adam 优化器用于优化。由于学习速率是自适应的,这几乎不需要调整。此外,在训练过程中使用检查点和早期停止机制,通过监控验证损失来选择最佳训练模型,如果损失在连续三个时期内没有减少,则停止训练。
虽然有超过 100,000 个训练数据,但是每个时期包括 24,064 个样本。这使得训练更容易处理,并且由于我们使用了生成器,所有的训练数据仍然在训练中使用,但是在不同的时期。
再次重申,自我记录的数据用于训练,而 Udacity 提供的数据用于训练期间的验证。
4.模型检验
经过训练的模型在第一条跑道上进行了测试。这给出了一个很好的结果,因为赛车可以在赛道上平稳行驶。参见下面的路线 1 测试结果视频
此外,为了测试推广性,在第二个轨道上测试了模型。值得注意的是,该模型从未在这条赛道的样本上训练过,但它在这条赛道上驾驶成功。参见下面的路线 2 测试结果视频:
5.结论
通过使用人类行为采样数据来训练在模拟轨道上自主驾驶的深度学习模型。该模型包括 5 个卷积层和 3 个更完全连接的层,能够通过克隆人类行为进行学习,并能够概括对新测试轨道的反应。虽然该模型只控制转向角,但它也可以扩展到控制油门和刹车。
笔记
以下是我在这个项目中的个人笔记:
- **数据处理和学习过程一样重要:**我意识到,也许这个项目最重要的部分是提出一种预测测试用例并进行归纳的数据处理,因此使用了抖动和亮度增强。一旦我能够在 Nvidia 模型上训练,在 comma.ai 模型上工作也很容易,在相同的数据处理下,它也给出了令人满意的结果。
- **数据量统计:**更多的数据最能提高学习效率。当我有大量数据进行训练时,我可以很容易地看到改进,并能够根据 Udacity 数据集进行验证。
- **一些我觉得没用的处理:**虽然其他一些人也用了这些方法,但对我来说并没有什么影响。例如,垂直平移、通过添加一些均匀噪声来扰动 0°附近的转向角,以及使用正方形大小的输入。
你可以在我的 github 这里找到这个项目和其他自动驾驶汽车相关的项目。虽然这个项目已经完成,但我想改进或者训练这辆车在越野赛道上行驶。请在评论中给出任何建议、更正或补充。
成为一名自学成才的机器学习工程师:7 个月
在我作为机器学习工程师的头 7 个月里,我学到了 7 件事
Where most of my self-study/project work happens.
在过去的 7 个月里,我一直是 Max Kelsen 的机器学习工程师。在我参与的几个项目中,有几件事每次都会出现。
当然,因为数据不同,客户不同,目标不同,所以永远不会相同。但是一个问题的原理通常可以用于另一个问题。
每当我开始使用新的数据集时,我都要提醒自己以下几点。
a)看数据。不是真的,看看数据。
当你第一次得到一个数据集时,你应该做的第一件事就是浏览它,并制定一系列的问题。
不要马上寻找答案,过早这样做可能会给你的探索过程设置障碍。
‘这个专栏和什么有关?’
“这会产生这样的效果吗?”
‘我应该了解更多关于这个变量的信息吗?’
“为什么这些数字是这样的?”
“这些样品总是以那种方式出现吗?”
你可以在第二次浏览数据时开始回答这些问题。如果这些问题你自己都无法回答,那就去找专家吧。
b)与专家交流
数据就是数据。它不会说谎。事情就是这样。但这并不意味着你得出的一些结论不会因为你自己的直觉而产生偏差。
假设你试图预测房价。可能有些事情你已经知道了。房价在 2008 年下跌,有白色栅栏的房子赚得更多,等等。
但是重要的是不要把这些当作硬性的假设。在你开始建造世界上最好的住房模型之前,你可能想问一些有经验的人的问题。
为什么?
因为这会节省你的时间。当你在第一部分列出你的问题清单后,问一个主题专家可以节省你几个小时的预处理时间。
“哦,我们不再使用那个指标了,你可以忽略它。”
“你看到的那个数字实际上与其他东西有关。”
c)确保你回答了正确的问题
当你开始建立一个模型的时候,确保你已经想好了你要解决的问题。
这应该与客户、项目经理和任何其他主要贡献者进行讨论。
模型的理想结果是什么?
当然,当你重复不同的选项时,目标可能会改变,但是有目标总是一个好的开始。
没有什么比花两周时间建立一个 99%准确的模型,然后向客户展示你的作品,却发现你在建模错误的东西更糟糕的了。
**测量两次。切一次。**实际上,这句话对机器学习并不适用,因为你会制作大量的模型。但是你明白了。
d)特征工程、特征编码和数据预处理
有什么样的数据?
仅仅是数字吗?
有没有可以纳入模型的分类特征?
注意,分类特征可以被认为是任何类型的数据,这些数据不能立即以数字形式出现。
在尝试预测房价的问题中,您可能会将个浴室作为数据的数字特征,将房屋的郊区作为数据的分类特征(非数字类别)。
有不同的方法来处理这两个问题。
对于数字,主要的方法是确保它们都是相同的格式。例如,想象一下汽车的制造年份。
99(99 年)是 18(2018 年)的四倍吗?
您可能希望将这些更改为 1999 年和 2018 年,以确保模型捕捉到这两个数字实际上有多接近。
分类特征的目标是将它们转换成数字。你怎么能把住宅郊区变成数字呢?
比如说你有帕克里奇格林维尔和阿斯科特。
你能说帕克里奇= 1,格林维尔= 2,阿斯科特= 3 吗?
但不代表帕克里奇+格林维尔=阿斯科特?
这说不通。
更好的选择是对它们进行一次热编码。这意味着给一个值 1 代表它是什么,0 代表它不是什么。
有许多其他的方法可以将分类变量转换成数字,而计算出最好的方法是有趣的部分。
e)快速测试、迭代、更新
您能在开始时创建一个简单的度量标准吗?
可能有一个你正在努力实现的理想场景,但是有没有一个更简单的模型可以用来测试你的想法呢?
从最简单的模型开始,逐渐增加复杂性。
不要害怕犯错,一次又一次,一次又一次。测试中出错总比生产中出错好。
如果有疑问,运行代码。就像数据一样,代码不会说谎。它会完全按照你说的去做。
你越快发现什么不起作用,就能越快找到什么起作用。
f)不断重温主要目标
机器学习项目产生的主要问题通常不是数据或模型,而是相关方之间的沟通。
沟通永远是关键。
解决一个问题可能会让你陷入困境。你想尝试一件事,这导致了一件又一件事,现在你甚至不确定你在解决什么问题。
这不一定是一件坏事,一些最好的解决方案就是这样找到的。
但是记住不是每个人都能理解你的思路。如有疑问,请多沟通。
问问你自己,“我还在正确的轨道上吗?”因为如果你答不出来,你觉得别人会怎么走?
g)几声大喊
在我偶然发现这两个惊人的资源后,我的工作质量得到了提升。
- Daniel Formoso (很棒的名字)的笔记本,它从头到尾使用 scikit-learn、TensorFlow 和一系列其他技术完成了一项数据科学分类任务。
- CatBoost ,决策树库上的火箭动力开源梯度 boosting。换句话说,一个史诗般的算法将我最近的所有结果提高了 10%。
你可以将这两者结合起来,为你的下一个机器学习项目建立一个非常健壮的基础。
额外收获:每天都是第一天
我差点忘了这个。
这个领域有太多的事情正在发生。可能很难跟上。尤其是当你刚开始的时候。
机器学习技术具有难以置信的潜力,可以为社会带来价值。所以它们值得学习是有道理的。但是像任何值得学习的东西一样,这些技能需要时间来培养。
每次你认为你已经尽了最大努力,总会有更多的收获。你可能会对此感到厌烦或兴奋。一个有用,另一个没用。
**想要更多吗?**我在 YouTube 上制作关于学习机器学习、健康和健身的每周视频,并在mrdbourke.com上写每日文章(这就是这篇文章的出处!).我在 LinkedIn 上也很活跃。回头见!
比谷歌更擅长机器学习——可能吗?
Comparing Facebox by Machine Box with Google Vision
说你在某件事上比谷歌更好是没有意义的。然而,当我对我们的面部识别技术和谷歌的视觉 API 进行测试时,我发现我们更加准确……更加准确。
当我看到‘我们’时,我说的是我公司的机器箱。我们在 Docker 容器中制作机器学习模型,这样任何可以编写 API 的开发人员都可以在他们的产品中实现机器学习,不需要博士或数学知识。
这一切都是从一个实验开始的,看看 Facebox 可以在一张图片中看到多少张脸。我搜索“人群”的图片,想找到一些好的测试图片,结果发现了这个:
A photo with a lot of faces — source: http://www.sportsplexoperators.com/blog/wp-content/uploads/2013/07/crowd_2.jpg
所以我创建了一个 Facebox 的实例,并把图片贴在上面。下载并分析图像几秒钟后,Facebox 用 JSON 作出响应,在 JSON 的顶部是一个facesCount
元素,显示检测到的人脸总数。
JSON response from Facebox
153,还不错。我通过我们开发人员的控制台预览模式再次运行了这张图片,得到了一些值得截图的东西:
Screen shot of Facebox’s preview mode in the developer console
然后我想知道,鉴于他们围绕机器学习的新声明,这与其他云认知服务,特别是谷歌视觉,有什么关系。我访问了他们的页面,他们让你在服务上发布一张照片,看看会有什么结果。经过几秒钟的处理,我得到了这个结果。
Google Vision console
我可以立即从缩略图看出检测到的人脸较少,但当我向下滚动右侧的响应窗口时,我有点震惊地看到他们只检测到了 50 张人脸。
他们漏掉了那张照片中的 100 多张脸。那太多了。😬
谷歌视觉的人脸识别产品当然有更多的功能,比如情绪检测、眉毛定位、头饰检测等等。在 Machine Box,我们让 Facebox 非常擅长检测和识别人脸(你可以用一张图片教 Facebox 某人是谁)。就是这样!我们这样做是因为我们希望我们的盒子具有尽可能高的质量,这意味着只有在技术水平足够好以返回准确结果的情况下才实现特性。
也就是说,我们喜欢谷歌,对于一些用例来说,他们用于机器学习的公共云 API 将会工作得很好。他们有一个惊人的数据集来训练机器学习模型。那么 Machine Box 比 Google 更擅长机器学习吗?不,当然不是…是谷歌!他们在深度学习和其他人工智能相关技术上投入了大量时间和金钱,当然,也为地球上的几乎每个人提供了有价值的服务,这令人敬畏。但是,很多开发人员需要在本地或在他们自己的基础设施中实现一些具有极高精确度的东西(他们喜欢 Docker),所以他们选择了 Machine Box——我们非常感激。
制作锋利的开发工具是我们的热情和信念,我们希望您能尝试一下。它将永远免费用于开发和测试。
2018 年 CNN 推理的标杆硬件
CNN 推理和边缘计算即将到来——几乎每个移动平台(苹果、三星、华为)都将获得专用硬件来进行推理。而且,随着自动驾驶汽车的出现,有像英伟达的 Jetson Tx2 这样的机器人平台将推理带到了边缘。今年夏天,我有机会尝试了各种硬件平台,并了解了 CNN 推断的堆栈是如何相互竞争的。
今年夏天,我有机会在 Aquifi 实习,这是一家 3D 视觉初创公司,旨在实现制造业物流流程的自动化。通常,摄像机连接到进行推理处理的远程服务器。然而,他们的智能相机还包括一个附加的“片上系统”,所以我们想看看我们是否可以在边缘运行网络。3D vision 中的示例网络可大可小,例如:
小:用于关键点检测的 KCNN
关键点在 3D 视觉中有许多用途,例如识别用于 3D 重建的良好特征。
大型: MVCNN 用于识别 3D 形状
MVCNN 是一个大型网络,它采用许多 2D 图像来识别一幅 3D 图像。它使用一个 VGG 作为主干,以及一个“视图池”层来聚合各个 2D 影像的特征地图。
我测试的各种硬件有:
1)英伟达 Jetson Tx2
2) Movidius 2450(英特尔神经电脑棒/谷歌视觉套件)
3)英伟达 1080ti(benchline)
4)麒麟 970(华为手机)
5)高通 660
6) ActionSemiS900
Hardware Platforms
要考虑的因素
在 CNN 的推断中,需要考虑的事情很多。我将主要关注推理速度。
1)用电量
2)成本
3)开发容易度
4)推理速度
CNN 的推论可以运行在哪里?
1)FPGA
2)GPU
3)DSP
4)ASIC
5)x86 或 Arm CPU
6)加速器(TPU NPE)
所有这些硬件在灵活性和效率方面都有各种各样的折衷。此外,公司现在正在生产新的名称,如 NPU(神经处理单元)或 TPU(张量处理单元),但实际上这些只是矩阵乘法和相关算术运算的加速器。在同一平台中,设备通常有多种类型。例如,高通 660 在同一块主板上集成了 CPU、GPU 和 DSP(数字信号处理器)。这使得实现算法变得困难,因为你必须实现所有硬件的所有原语层。下图显示了高通平台上不同图层类型的兼容性。
https://developer.qualcomm.com/docs/snpe/network_layers.html
编译程序
那么你已经在 Tensorflow/Pytorch 中训练了一个模型,你实际上如何让它在这些特定的硬件上运行呢?虽然一般可以在 GPU 或 CPU 上运行网络进行训练,但在推理过程中,大多数平台一般都要求你在网络上运行自己专有的编译器。
英伟达:TensorRT
谷歌视觉套件:视觉软帽编译器
麒麟 970: 华为图形编译器
**高通:**SnapDragon-tensor flow-to-DLC
**神经计算棒:**神经棒图形编译器
尽管这些编译器有不同的实现,但我们可以假设它们做了以下一些事情:
1)自动层融合
2)内存优化
3)不同硬件处理器(CPU、GPU、DSP、NPU)之间的分配
4)权重&激活校准(INT8 或 FP16)
Nvidia TensorRT
型号
InceptionV3: ~92 Mb,~ 2380 万参数
InceptionV2_Resnet: 214Mb, 5580 万参数
MobilenetV1 _ 0p 5 _ 128:~ 1.89 Mb,~0.5 万参数
MobilenetV1_1p_224: 16.3Mb, 420 万参数
MobilenetV1_0p5_160: 5.2Mb, 130 万参数
选择的模型是那些最终适用于大多数平台的模型。我排除了 VGG,因为它相当大,永远不会运行移动。Resnets 也是被排除在外的热门选择。
结果
初始版本 3
当每个平台具有不同的功能时,有时很难进行公平的评估。例如,在图中,高通将推理量化为 8 位。在 Nvidia TensorRT 中,您可以选择使用 FP32 或 FP16。麒麟 970 支持 8 位和 1 位量化。在这个图表中,一些有趣的点
1)英特尔神经计算棒是最慢的,比英特尔 i7–8700k CPU 慢 3 倍。
2) Nvidia Jetson Tx2 GPU 运行速度与英特尔 i7–8700k CPU 相同
3) 1080ti 比英特尔 i7–8700k CPU 快约 10 倍
4) Kirin970 和高通 660 移动平台速度相似
5) Jetson Tx2(Float TensorRT)与移动平台速度相似,但由于 Float 与 8 位推断不完全相同,因此这种比较并不公平。
移动网络
对于更小的 mobilenets,这使得不太强大的硬件如 ActionSemiS900 甚至 RaspberryPi 能够进行推理。Mobilenets 是最先进的边缘计算,有两个主要参数可以调整:1)宽度乘数 2)输入图像的大小。
下图显示了
1)宽度乘数= 0.25 &输入大小= 128
2)宽度乘数= 0.5 &输入大小= 160
使用最小的 mobilenet,硬件可以在几毫秒内进行推断。此时,硬件之间的传播差异小于 50 毫秒。因此,加载模型权重、将数据从 CPU 传输到 GPU 以及其他各种事情可能比推理本身需要更长的时间。
有趣点 1)英特尔神经棒比谷歌视觉套件快 4 倍,二者使用相同的底层 Movidius 2450 板。相同层的软件实现很重要。
2)
Nvidia Tx2 洞察
就速度而言 TensorRT(Half) < TensorRT(Float) < Tensorflow(Float), each faster by a factor of ~2x. We can expect the fastest verson TX2 TensorRT(Half) to be roughly 2–5x slower than 1080ti(Float) for various models — check out 这个再现了它。
https://github.com/NVIDIA-Jetson/tf_to_trt_image_classification
高通 660 洞见
高通 660 是该平台的旧版本,当前版本是 845。就像 Mobilenets、mobilenetsd、InceptionV3 这样的小型网络而言,高通 660 提供了不错的速度。例如,它可以以 Mobiletnet_0p25_128 为主干,为 MobilenetSSD 做 10fps。虽然速度很快,但缺点是 SNPE 平台仍然相对较新。在尝试使用 snpe-tensorflow-to-dlc 编译器编译某些最先进的模型时,我遇到了一个问题。我在论坛上看过类似的问题,但这是对新平台的预期。
麒麟 970 见解
对于 InceptionV3,麒麟 970 比高通 660 快一点。它甚至比高通的 SNPE 平台更新,因为华为 HiAI 平台于 2018 年 5 月发布。这个平台主要支持 Caffe。有一定的限制,如他们只支持 Tensorflow 1.3 和模型大小必须是<100mb. Most of the newest Mobilenets are trained with Tensorflow 1.6 or above. Thus, it is hard to compile some of the pretrained models on the internet currently.
ActionSemiS900 & CPU TF 结果
ActionSemiS900 是一款低功耗主板,配有 64 位四核 Cortex-A53 CPU 和 G6230 PowerVR GPU。虽然 PowerVR 为面向人工智能的应用程序推出了他们的 PowerVR CLDNN SDK ,但截至目前,它只支持拥有 PowerVR GPU 的 Chromebooks。因此,我在 Tensorflow 和 TFLite 上对 Cortex-A53 CPU 进行了一些测试。你可以实时运行所有的移动网络。TFLite 是谷歌的边缘计算方法,是 TF Mobile 的继任者。TFLite 对于特定型号来说速度稍快,但截至 2018 年 7 月,它还没有准备好生产-对于某些更大的型号,如 InceptionResnetV2(图中未显示),它甚至慢了几个数量级。
其他知名公司
就硬件而言,它真的是狂野的西部。下面显示的是 4 家公司,他们特别想从事人工智能系统芯片业务。要查看除片上系统之外的硬件,请查看这个全面的列表。简单总结一下这四个:
恩智浦:拥有各种 SoC 和其他解决方案,如 I.MX 8 系列用于 CNN 推断,使用 DeepView ML 工具包
**联发科:**芯片供应商对于中型手机,Helio P60 将类似于高通或华为的平台。使用他们的 NeuroPilot AI 平台,该平台被认为支持 TF,Caffe,ONNX,Android NN API
**意法半导体:**真正的大公司,在 1 月份的 CES 上宣布它想进入这个领域。
RockChip: 福州一家公司,宣称他们的 SoC 比 Jetson Tx2,Kirin970,Apple A11 都快…
展望未来
可以预计,硬件/平台将在 ML 的未来发挥很大作用。如你所见,每个手机芯片供应商(苹果、华为、高通、联发科…)都在抢着建自己的加速器。尽管硬件将在不到一年的时间内上市,但软件平台可能需要更长的时间才能赶上。真的,Nvidia 比这些家伙领先 10 年,这些芯片供应商正在从头开始编写软件。使用不同的专有编译器可能会很笨拙,在未来,我希望有一个像 Android NN API 这样的通用接口,可以访问硬件。
Android NN API
数据科学的优势和伦理挑战——COMPAS 和智能电表
长篇散文。
Getting the balance right: weighing benefits against ethical challenges in Data Science.
1.介绍
最近在处理大量数据方面取得的进步为改善个人生活和我们社会的福利创造了大量新的机会。例如,监控家庭用电量的智能电表可以在不在家时帮助省电,或者根据消费模式建议最便宜的电力供应商。
然而,想象一下电力供应商的网站说,如果你提供实时而不是每周的电力消耗数据,你每年的电力成本将下降 20%。应该允许电力供应商向消费者施压,用隐私换取金钱吗?
1.1.概述
本文描述了数据科学的两个应用,即美国法院和家用智能电表中使用的替代制裁罪犯管理概况(COMPAS)软件系统,以对比它们的好处和道德挑战。
1.2.关键术语的定义
定义数据科学有两个组成部分。首先,海量数据(兆兆字节、千兆字节)具有大数据的三个特征:容量、速度和多样性(Laney,2001)。第二,数据科学代表以软件形式实现的统计模型,可以检测这些数据中的模式。
当关于什么是对什么是错的观点出现分歧时,伦理挑战就出现了。比如,一个算法是否应该拥有决定被告是否被保释的权力?由于统计模型是建立在数据之上的,像 COMPAS 这样的应用首先需要分析数据是如何产生的。当巡逻的警察以有偏见的方式控制公民时,道德挑战可能会出现,但这超出了本文的范围。
为了改善个人生活和我们社会的福利需要一个应用程序来为一个或多个个人的生活创造价值,而没有负外部性并且在法律界限内。换句话说,有人从使用这项技术中获益。
最后,智能电表是一种电子设备,它测量家庭用电量,并与其他电子设备进行通信,作为连接网络的一部分(想想物联网)。
2.好处和道德挑战
COMPAS 和智能电表利用大量数据,提供清晰明确的优势,提出引人注目的道德挑战,受到众多学者的讨论,似乎对当今和未来的社会影响最大。
2.1.什么是 COMPAS?
美国各地的法官越来越依赖算法来评估等待审判的被告是否有可能再次犯罪。由 Northpointe 公司开发的一个这样的算法系统叫做 COMPAS,在威斯康星州、加利福尼亚州、科罗拉多州和佛罗里达州等地使用。在审讯过程中,每名被告都提供了 100 多个独立的输入变量,包括年龄、性别和犯罪史(安格温,未注明日期)。根据被告与特定群体的相似程度,COMPAS 输出从 0 到 10 的风险评分。得分从 5 到 7 代表中等,得分从 8 到 10 代表再次犯罪的可能性高。评委将分数视为决策过程中的众多因素之一。
好处
Swets 等人(2000 年)的研究论文发现,在某些情况下,数据科学方法优于人类判断。COMPAS 是对人类判断的补充,保证了基于所有可用的案例证据对被告进行客观公正的评估。它有助于防止出现 Danziger 等人(2011 年)描述的结果,他们发现,在法官用膳休息后,法院做出有利裁决的可能性迅速上升(见下图)。
Proportion of rulings in favour of the prisoners. Circled points represent the first decision after meal breaks (Danziger et al., 2011).
此外,COMPAS 在充斥着官僚主义和行政挑战的刑事司法系统中大放异彩,因为它简化了管理,简化了决策过程,提高了效率。
伦理挑战
我确定了三个主要的道德挑战:不公平的歧视、强化人类偏见和缺乏透明度。
不公平的歧视。
什么是公平被告评估,数据科学家如何开发适用于任何被告的相应算法?
Northpointe 对公平算法的定义指出,无论种族如何,每个风险类别中重新犯罪的被告比例大致相同。换句话说,例如 7 的风险分数预示着黑人和白人被告再次犯罪的可能性相等。根据定义,任何替代定义都会通过人为提高白人被告的风险水平来歧视他们。斯坦福大学和伯克利大学的研究人员根据佛罗里达州布劳沃德县的大约 5,000 个样本验证了单一风险分数代表实际再犯的风险大致相等(Corbett-Davies 等人,2016 年)。
然而,调查性新闻机构 ProPublica 通过分析佛罗里达州布劳沃德县治安官办公室的 1 万多份被告样本,发现了对黑人被告的不公平歧视。他们比较了 COMPAS 发布的累犯风险分数和分数发布两年后的实际累犯率,发现该算法将黑人被告归类为中等至高风险的可能性是白人被告的两倍多,即使黑人和白人被告都没有继续犯罪。虽然黑人被告没有重新犯罪,但他们受到了法院系统更严厉的对待(Larson et al .,2016)。
歧视性待遇本身不存在道德问题;这种待遇的影响,即根据种族被送进监狱或保释,是这种应用的伦理问题(Schermer,2011)。
一个算法能在满足 Northpointe 对公平的定义的同时减轻 ProPublica 的合法担忧吗?
强化人类的偏见。
前面定义的数据科学的两个方面(大量数据和统计模型)导致了基于过去数据模式做出决策的固有限制。COMPAS 的开发人员可能会向系统输入累犯数据,让模型识别与再次犯罪可能性相关的变量——这是训练分类算法的标准方式。如果数据是完全无偏的,那就不会有问题,但是公司所能做的就是鹦鹉学舌般地告诉我们自己的偏见。其中包括法官严重的种族主义偏见,他们认为黑人被告“比白人更有可能再次杀人”(Epps,2017 年),或者墨西哥被告实施了性侵犯,“因为他是墨西哥人,墨西哥男子想拿什么就拿什么”(科罗拉多最高法院,2017 年)。
将判决的责任交给电脑,让法官不仅可以根据相关因素(如犯罪的严重性)做出决定,还可以根据道德上有问题的因素(如推断的种族和性别)做出决定。假设 COMPAS 预测被告是高风险。然而,法官不同意并释放了被告,他后来再次犯罪。为什么法官不遵从软件的建议?这种结果比 COMPAS 建议低风险时更容易发现,但法官对被告进行判决,并(可能)防止再犯。
谓缺乏透明度。
向公众隐瞒公司的内部运作禁止了对减轻习得性偏见的理解和讨论。然而,可以理解的是,Northpointe 辩称,公布其专有算法将导致竞争劣势,“因为这肯定是我们业务的核心部分”(Liptak,2017),正如《纽约时报》援引一位高管的话说。当政府机构授权私营公司将数据科学应用于敏感的政府数据时,这种困境就不足为奇了。有两个关键领域需要透明度。
首先,统计建模的透明度要求 Northpointe 披露导致风险评分的逐步过程、基本模型及其参数。根据所使用的模型,这项任务可能非常困难,因为像神经网络这样的模型的确切工作方式仍然不清楚。立法者应该只允许完全理解的算法做出如此广泛的建议吗?
第二,仍然不清楚使用了什么数据。虽然种族不是一个输入变量,但其他变量,如性别,在 Eric L. Loomis 案件的诉讼程序中显而易见(威斯康星州最高法院,2016 年)。如果用于训练的数据集可以根据其他变量来推断种族,这在伦理上是非常成问题的。有超过 100 个输入变量,有可能一些变量子集可以准确地预测种族。在这种情况下,统计模型无法区分单个变量和该组变量的预测能力。Northpointe 的首席科学家蒂姆·布伦南(Tim Brennan)甚至承认,“很难构建一个不包括可以与种族相关的项目的分数”(Angwin et al .,2016)。共享变量之间的相关性与商业秘密并不冲突。
被告应该有权知道 COMPAS 是如何计算分数的吗?COMPAS 是否侵犯了被告获得个性化判决的权利和基于准确信息被判刑的权利?(《州诉卢米斯案》,2017 年)
2.2.什么是智能电表?
最近的技术进步引发了从许多小规模来源而不是少数大型发电厂向更分布式发电的转变。这至少需要对电网进行部分重新设计,包括智能电表,以保证安全运行。更具体地说,系统运营商可以获得网络透明度,消费者可以可视化和优化他们的电力消耗。智能电表有很多好处,但也有风险(芬斯特和鲍姆加特,2015)。
利益
电力供应商的利益可分为网络运营和更灵活的计费(Jawurek 等人,2012 年)。
智能电表使公司能够更好地管理电网,包括更好地预测未来的网络容量需求、网络基础设施的预防性维护和快速停电检测(Depuru 等人,2011b)。
关于计费机会,公司可以利用数据开发新的电价模型,包括电力消费和发电(上网电价)。这为消费者提供了更多选择的新市场。事实上,先进的计量基础设施是具有波动电力馈入的分散式网络的关键使能因素(Rö mer et al .,2012)。此外,智能电表有助于检测欺诈,降低电力供应商和消费者的成本。一项研究估计,全球电力供应商每年因窃电损失约 250 亿美元,由于发电量增加和缺乏回收二氧化碳的资金,这也导致二氧化碳排放量增加。即使是部分缓解也能降低电力公司和消费者的成本,减少二氧化碳排放,增加社会福利(Depuru 等人,2011a)。
除此之外,消费者还受益于更高的电力消费透明度、为物联网中心的计量基础设施重新定位的灵活性,为其他智能服务和新的商业模式提供动力,例如允许离家为电动汽车充电(Veale,2017)。
道德挑战
道德挑战可以分为三个主要领域:隐私、缺乏透明度、同意和权力。
隐私。
乍一看,人们可能不会将用电量归类为特别敏感的数据。然而,精确的仪表读数可以用来确定一个人是否在家,在什么时间使用哪些电器(莫利纳-马卡姆等人,2010 年),你是否让电器超过要求的时间,甚至建筑物的特征(贝克尔等人,2014 年)。因此,用户日常生活的隐私细节可能会被暴露,并以侵犯个人隐私的方式使用(Quinn,2009)。
谓缺乏透明度。
例如,征收新关税的机会引发了透明度问题。假设我的邻居和我的价格不同,即使我们有相同的单位面积和数据参数。这种差异是因为我周末用的电比她多吗?什么数据定义关税模型?
同意和权力。
新的关税模型可能会将数据粒度与关税价格联系起来。换句话说,数据越细,资费越便宜。因此,消费者可以用隐私换取电费,这可能会推动低收入家庭同意更多的数据共享(Veale,2017)。
然而,在同意分享之前,消费者首先需要理解并能够访问这些数据。尼森鲍姆(2011)将这个问题称为透明悖论:低水平数据难以理解,汇总统计数据隐藏了关键细节——我们无法在不放弃另一个的情况下实现一个。
3.批判性分析
我不想提供克服所讨论的挑战的具体建议,而是想用以下方法批判性地分析第 2 部分中讨论的挑战:统计分析、权衡而不是完美、数据的伦理(个人和群体隐私)以及实践的伦理。
3.1.康派斯牌衬衫
统计分析
回到涉及 Northpointe 和 ProPublica 的辩论,我们建立了两个前提:
- 无论种族如何,每个风险类别中重新犯罪的被告比例应该大致相同(Northpointe 对公平的定义)。
- 没有再犯的黑人被告被认为比他们的白人同行更危险(ProPublica 的批评)。
缺少的一条信息是,黑人被告的总体累犯率高于白人被告(52%比 39%)(Corbett-Davies 等人,2016 年)。这意味着,为了满足 Northpointe 对公平的定义,我们说过改变这一定义是有问题的,从数学上来说,对于最终没有再次犯罪的被告,黑人被告被分配更高的风险水平——该模型代表了数据集中的偏斜。
这并不意味着我们应该忽视 ProPublica 的观点,而是应该与包括立法者、法官和公民在内的利益相关者就哪些算法应该优先考虑以及可以引入哪些替代政策进行公开讨论。例如,新的跟踪技术可以使保释要求变得无用,这样就不会有人被不必要的监禁。
取舍而非完美。
COMPAS 不能做出完美的决策,但是我们不能期望它没有偏见和副作用。完美是一个追求的方向,但是当我们务实地比较有 COMPAS 的法院系统和没有 COMPAS 的法院系统时,前者似乎具有更好的利益与挑战之比(Baase,2012)。我们仍应寻求改进,例如终止与 Northpointe 的合作,在美国政府内部开发类似的软件工具,并防止商业秘密的困境。政府可以公布算法细节以确保透明度。
3.2.智能电表
数据伦理学。
最紧迫的个人隐私挑战是重新识别和实时监控。这些可以通过例如将所有数据存储在设备上来减轻,直到在消费发生一天后传输总消费数据。这种方法降低了信息价值,但增加了隐私,同时仍然允许前面讨论的好处。电力供应商寻求高粒度的数据,但无论消费者的收入水平如何,法律都应确保数据粒度不能越过个人尊严屈服于电力供应商要求的界限(Warren 和 Brandeis,1890)。
欧盟委员会(2014 年)在 2014 年宣布,到 2020 年,28 个成员国中的 16 个将大规模(80%或以上)覆盖智能电表。数据粒度、安全机制和应急计划等关键主题尚未得到解决。
例如,计量数据可以根据特定的消费模式(例如工作日与周末)将人们分类。保护个人隐私并不一定意味着保护群体隐私。人群可能成为罪犯的诱人目标,例如周末用电量较少的市民,暗示他们不在家。Floridi 认为,当前的政策框架(如当前的欧洲立法)过于以人类为中心(强调自然人)和原子论(只考虑单个个人),无法确保群体隐私。法律保护个人隐私和社会隐私,但不保护社会群体的隐私。Floridi (2015 年)认为,这种新法律需要调和两种道德义务:改善人类福利和促进人权隐私权。有时,保护个体的唯一方式是保护群体,就像一个渔民带着一群沙丁鱼一样——他试图抓住鱼群,而不是个体沙丁鱼(Floridi,2014)。
实践伦理。
传统的伦理分析可能会提出一个道义上的行为准则,关于什么是道德的,什么不是。然而,我们处在一个应用伦理学的环境中,在这种环境中,结果主义的方法更合适。这是因为新技术带来了新问题,而旧方法对这些问题的价值有限。政策可能导致不可预见的后果,因此需要一个灵活的政策框架,允许快速和频繁的适应。这种框架的一个例子是英国内阁办公室部长(2016) 数据科学道德框架,旨在通过建立六项对比公共利益和项目风险的关键原则,使创新更加容易。这是一份简单易懂的文件。
4.结论
总之,本文对问题进行了批判性分析,并围绕 COMPAS 和智能电表作为应用数据科学的例子展开了辩论。确定的挑战包括不公平的歧视、强化人类偏见(COMPAS)、隐私、同意和权力(智能电表)以及缺乏透明度(两者都有)。批判性分析使用了统计分析、权衡而非完美(COMPAS)、个人和群体隐私以及实践道德(智能仪表)等方法。
让我们回到开篇提出的问题:应该允许电力供应商向消费者施压,用隐私换取金钱吗?否。考虑到所讨论的方法,政策制定者需要给予消费者最低程度的隐私,无论其经济状况如何。找到合适的水平需要公开的公共讨论(参见 COMPAS)和灵活的政策框架(参见 smart meters)。
你还想到了其他什么应用?
5.文献学
Angwin,j . n . d .样本-对比-风险-评估-对比-“核心”。ProPublica。
Angwin,j .,Larson,j .,Mattu,s .,Kirchner,l .,2016。机器偏差。全国各地都有用来预测未来罪犯的软件。而且对黑人有偏见。ProPublica。
Baase,s .,2012 年。火的礼物:计算技术的社会、法律和伦理问题,第 4 版。由…编辑新泽西州上萨德尔河皮尔逊。
贝克尔,c .,萨达莫里,l .,斯塔克,t .,桑蒂尼,s .,2014 年。从智能电表数据揭示家庭特征。能量 78,397–410。【https://doi.org/10.1016/j.energy.2014.10.025
科比特-戴维斯,s .,皮尔森,e .,费勒,a .,戈埃尔,s .,2016。一个用于保释和判决的计算机程序被贴上了对黑人有偏见的标签。其实没那么清楚。华盛顿州贴吧。
Danziger,s .,Levav,j .,Avnaim-Pesso,l .,2011 年。司法判决中的外部因素。继续。自然。阿卡德。Sci。108, 6889–6892.https://doi.org/10.1073/pnas.1018033108
德普鲁,s . s . s . s . r .,王,l .,天尊菩萨,v .,2011a。窃电——概述、问题、预防和基于智能电表的防窃电方法。能源政策,关于海上风力发电规划、经济和环境的特殊章节 39,1007–1015。https://doi.org/10.1016/j.enpol.2010.11.037
Depuru,s . s . s . s . r .,Wang,l .,Devabhaktuni,v .,n . 2011 b。面向电网的智能电表——挑战、问题、优势和现状,载于:2011 年 IEEE/PES 电力系统会议和博览会。发表于 2011 年 IEEE/PES 电力系统会议暨博览会,第 1–7 页。https://doi.org/10.1109/PSCE.2011.5772451
Epps,g .,2017。最高法院在陪审团室直面种族主义。大西洋。
欧盟委员会,2014 年。以电力为重点,对 EU-27 中的智能计量部署进行基准测试。
印第安纳州鲍姆加特市芬斯特,2015 年。隐私感知智能计量:一项调查。IEEE Commun。Surv。家教。17, 1088–1101.https://doi.org/10.1109/COMST.2015.2425958
佛罗里达州弗洛里迪,2015 年。信息伦理,再版。由…编辑牛津大学出版社,牛津。
佛罗里达州弗洛里迪,2014 年。开放数据、数据保护和群体隐私。菲洛斯。技术。27, 1–3.https://doi.org/10.1007/s13347-014-0157-8
Jawurek,m .,Kerschbaum,f .,Danezis,g .,2012 年。SoK:智能电网的保密技术——选项调查。
兰尼博士,2001 年。3D 数据管理:控制数据量、速度和多样性。
拉尔森,j .,马特图,s .,基什内尔,l .,安格温,j .,2016。我们如何分析 COMPAS 累犯算法?ProPublica。
利普塔克,2017 年。被一个软件程序的秘密算法送进了监狱。纽约时报。
内阁办公室部长,2016 年。数据科学道德框架— GOV.UK
2016 年,米特斯塔特大学,法学学士,阿洛大学,轩辕洛尹大学,沃希特大学,洛里迪大学。算法的伦理:绘制辩论图。大数据 Soc。3, 2053951716679679.https://doi.org/10.1177/2053951716679679
莫利纳-马卡姆,a .,谢诺伊,p .,傅,k .,切切特,e .,欧文,d .,2010。智能电表私人回忆录,载于:第二届 ACM 建筑节能嵌入式传感系统研讨会会议录,BuildSys '10。美国纽约州纽约市 ACM,第 61-66 页。【https://doi.org/10.1145/1878431.1878446
h .尼森鲍姆,2011 年。在线隐私的情境方法。代达罗斯 140,32–48。https://doi.org/10.1162/DAED_a_00113
奎因,2009 年。隐私和新能源基础设施(SSRN 学术论文编号 ID 1370731)。纽约州罗切斯特市社会科学研究网络。
Rö mer,b .,Reichhart,p .,Kranz,j .,皮科特,a .,2012 年。智能计量和分散式电力存储在智能电网中的作用:正外部性的重要性。能源政策,特别部分:过去和未来的能源转变——历史的洞察力 50,486–495。https://doi.org/10.1016/j.enpol.2012.07.047
Schermer,B.W .,2011 年。自动剖析和数据挖掘中的隐私限制。计算机。法律安全。修订版 27,45–52。https://doi.org/10.1016/j.clsr.2010.11.009
2017 年州诉卢米斯案。。哈维。法律修订
科罗拉多州最高法院,2017 年。佩纳-罗德里格斯诉科罗拉多(教学大纲)。
威斯康星州最高法院,2016 年。埃里克. l .卢米斯诉威斯康星。
Swets,J.A .,Dawes,R.M .,Monahan,j .,2000 年。心理科学可以改善诊断决策。心理学。Sci。公共利益 1,1–26。https://doi.org/10.1111/1529-1006.001
维勒,硕士,2017。数据管理和使用:技术和治理案例研究——为英国科学院和皇家学会编写。
沃伦,法学博士,布兰代斯,法学博士,1890 年。隐私权。哈维。法律修订版 4,193–220。https://doi.org/10.2307/1321160
BERT 解释道:NLP 的艺术语言模型
BERT(来自变压器的双向编码器表示)是谷歌人工智能语言的研究人员最近发表的一篇论文。它在各种各样的 NLP 任务中展示了最先进的结果,包括问答(SQuAD v1.1)、自然语言推理(MNLI)等,从而在机器学习社区中引起了轰动。
BERT 的关键技术创新是将 Transformer(一种流行的注意力模型)的双向训练应用于语言建模。这与以前从左到右或者结合从左到右和从右到左训练来查看文本序列的努力形成对比。论文的研究结果表明,双向训练的语言模型比单向训练的语言模型具有更深的语境感和语流感。在论文中,研究人员详细介绍了一种名为掩蔽 LM (MLM)的新技术,它允许在模型中进行双向训练,这在以前是不可能的。
背景
在计算机视觉领域,研究人员已经多次展示了迁移学习的价值——在已知任务(例如 ImageNet)上预先训练神经网络模型,然后进行微调——使用经过训练的神经网络作为新的特定目的模型的基础。近年来,研究人员已经表明,类似的技术在许多自然语言任务中是有用的。
另一种不同的方法是基于特征的训练,这种方法在 NLP 任务中也很流行,并在最近的 ELMo 论文中举例说明。在这种方法中,预先训练的神经网络产生单词嵌入,然后将其用作 NLP 模型中的特征。
伯特是如何工作的
BERT 使用 Transformer,这是一种学习文本中单词(或子单词)之间上下文关系的注意力机制。一般来说,Transformer 包括两个独立的机制——一个读取文本输入的编码器和一个为任务生成预测的解码器。由于 BERT 的目标是生成一个语言模型,所以只有编码器机制是必要的。谷歌在的一篇论文中描述了 Transformer 的详细工作原理。
与顺序读取文本输入(从左到右或从右到左)的方向模型相反,Transformer 编码器一次读取整个单词序列。因此,它被认为是双向的,虽然说它是非定向的会更准确。这一特性允许模型基于单词的所有周围环境(单词的左侧和右侧)来学习单词的上下文。
下图是变压器编码器的高级描述。输入是一系列标记,这些标记首先被嵌入到向量中,然后在神经网络中进行处理。输出是大小为 H 的向量序列,其中每个向量对应于一个具有相同索引的输入令牌。
当训练语言模型时,存在定义预测目标的挑战。许多模型预测序列中的下一个单词(例如,“孩子从 __”回家),这是一种方向性的方法,固有地限制了上下文学习。为了克服这一挑战,BERT 采用了两种训练策略:
蒙面 LM (MLM)
在将单词序列输入 BERT 之前,每个序列中 15%的单词被替换为一个[MASK]标记。然后,该模型尝试根据序列中其他未屏蔽单词提供的上下文来预测屏蔽单词的原始值。在技术术语中,输出字的预测需要:
- 在编码器输出之上添加分类层。
- 将输出向量乘以嵌入矩阵,将它们转换到词汇维度。
- 用 softmax 计算词汇中每个单词的概率。
BERT 损失函数只考虑屏蔽值的预测,而忽略非屏蔽字的预测。因此,该模型比方向模型收敛得更慢,这一特性被其增强的上下文感知所抵消(参见要点 3)。
注意:在实践中,BERT 实现稍微复杂一些,并不能取代所有的 15%屏蔽字。更多信息参见 附录 A 。
下一句预测(NSP)
在 BERT 训练过程中,模型接收句子对作为输入,并学习预测句子对中的第二个句子是否是原始文档中的后续句子。在训练期间,50%的输入是一对,其中第二个句子是原始文档中的后续句子,而在另外 50%中,从语料库中随机选择一个句子作为第二个句子。假设随机句子将与第一个句子断开。
为了帮助模型在训练中区分这两个句子,输入在进入模型之前以下列方式处理:
- 在第一个句子的开头插入一个[CLS]标记,在每个句子的结尾插入一个[SEP]标记。
- 指示句子 A 或句子 B 的句子嵌入被添加到每个记号。句子嵌入在概念上类似于词汇为 2 的标记嵌入。
- 向每个标记添加位置嵌入,以指示其在序列中的位置。Transformer 论文中介绍了位置嵌入的概念和实现。
Source: BERT [Devlin et al., 2018], with modifications
为了预测第二个句子是否确实与第一个句子相关联,执行以下步骤:
- 整个输入序列经过变压器模型。
- 使用简单的分类层(权重和偏差的学习矩阵),将[CLS]令牌的输出转换成 2×1 形状的向量。
- 用 softmax 计算 IsNextSequence 的概率。
在训练 BERT 模型时,屏蔽 LM 和下一句预测一起训练,目标是最小化两种策略的组合损失函数。
如何使用 BERT(微调)
使用 BERT 完成特定任务相对简单:
BERT 可以用于各种各样的语言任务,同时只在核心模型中增加了一个小的层:
- 通过在[CLS]令牌的转换器输出之上添加分类层,类似于下一句分类来完成诸如情感分析的分类任务。
- 在问题回答任务中(例如,SQuAD v1.1),软件接收关于文本序列的问题,并被要求在序列中标记答案。使用 BERT,可以通过学习标记答案开始和结束的两个额外向量来训练问答模型。
- 在命名实体识别(NER)中,软件接收文本序列,并被要求标记文本中出现的各种类型的实体(人、组织、日期等)。使用 BERT,可以通过将每个令牌的输出向量馈送到预测 NER 标签的分类层来训练 NER 模型。
在微调训练中,大多数超参数保持与 BERT 训练中相同,本文对需要调整的超参数给出了具体指导(第 3.5 节)。BERT 团队已经使用这种技术在各种具有挑战性的自然语言任务上实现了最先进的结果,详见本文的第 4 部分。
外卖食品
- 模型的大小很重要,即使是大规模的。 BERT_large,拥有 3.45 亿个参数,是同类型中最大的模型。在小规模任务上,它明显优于 BERT_base,后者使用相同的架构,只有 1 . 1 亿个参数。
- *有了足够的训练数据,更多的训练步数==更高的准确率。*例如,在 MNLI 任务上,当在 1M 步(128,000 字批量大小)上训练时,与相同批量大小的 500K 步相比,BERT_base 准确度提高了 1.0%。
- 伯特的双向方法(MLM)比从左到右的方法收敛得慢(因为每批中只有 15%的单词被预测),但是在少量的预训练步骤之后,双向训练仍然优于从左到右的训练。
Source: BERT [Devlin et al., 2018]
计算考虑因素(培训和应用)
结论
BERT 无疑是机器学习用于自然语言处理的一个突破。事实上,它的平易近人,并允许快速微调,将有可能允许在未来广泛的实际应用。在这个总结中,我们试图描述论文的主要思想,而不是淹没在过多的技术细节中。对于那些希望更深入了解的人,我们强烈建议阅读全文和其中引用的辅助文章。另一个有用的参考是 BERT 源代码和模型,它们涵盖了 103 种语言,并由研究团队慷慨地作为开源发布。
附录 A —单词屏蔽
在 BERT 中训练语言模型是通过预测输入中随机选取的 15%的标记来完成的。这些标记经过如下预处理— 80%替换为“[MASK]”标记,10%替换为随机单词,10%使用原始单词。促使作者选择这种方法的直觉如下(感谢来自 Google 的 Jacob Devlin 的洞察力):
- 如果我们 100%的时间都使用[MASK],那么这个模型不一定能为非屏蔽单词产生良好的表征。未屏蔽的标记仍然用于上下文,但是该模型被优化用于预测屏蔽的单词。
- 如果我们在 90%的时间里使用[掩码],在 10%的时间里使用随机单词,这将告诉模型观察到的单词是永远不会正确的。
- 如果我们在 90%的时间里使用[MASK],在 10%的时间里保留同一个单词,那么这个模型就可以简单地复制非上下文嵌入。
这种方法的比率没有进行消融,不同的比率可能效果更好。此外,模型性能并没有通过简单地屏蔽 100%的所选令牌来测试。
关于最近机器学习研究的更多总结,请查看 Lyrn。AI 。
除了单词嵌入,为什么你需要知道字符嵌入?
2013 年,Tomas Mikolov [1]引入了单词嵌入来学习更好的单词质量。那时,单词嵌入是处理文本的最新技术。后来,也引入了 doc2vec。如果我们从另一个角度思考呢?不是从一个单词到一个文档的聚合,而是从一个字符到一个单词的聚合。
在这篇文章中,你将经历什么,为什么,什么时候以及如何进行字符嵌入。
什么?
项和扬恩[2]介绍了人物 CNN。他们发现字符包含了改善模型性能的关键信号。在本文中,字符表定义了 70 个字符,其中包括 26 个英文字母、10 个数字、33 个特殊字符和换行符。
Capture from Text Understanding from Scratch (Xiang and Yann, 2016)
# Copy from Char CNN paperabcdefghijklmnopqrstuvwxyz0123456789 -,;.!?:’’’/\|_@#$%ˆ&*˜‘+-=()[]{}
另一方面,Google Brain 团队引入了探索语言建模的极限并发布了 lm_1b 模型,该模型包含 256 个向量(包括 52 个字符、特殊字符),维数仅为 16。与单词嵌入相比,维数可以增加到 300,而向量的数量是巨大的。
Capture from Exploring the Limits of Language Modeling ( Rafal et al., 2016)
为什么?
在英语中,所有的单词都是由 26 个字符组成的(如果同时包含大小写字符,则为 52 个字符,如果包含特殊字符,则为更多)。有了字符嵌入,每个单词的向量都可以形成,即使是未登录词(可选)。另一方面,单词嵌入只能处理那些看到的单词。
Another benefit is that it good fits for misspelling words, emoticons, new words (e.g. In 2018, Oxford English Dictionary introduced new word which is boba tea 波霸奶茶. Before that we do not have any pre-trained word embedding for that).
它比 word2vec 嵌入更好地处理不常用的单词,因为后者缺乏足够的训练机会来训练这些不常用的单词。
第三个原因是,由于只有少量的向量,它降低了模型的复杂性并提高了性能(就速度而言)
什么时候?
在 NLP 中,我们可以将字符嵌入应用于:
怎么会?
字符嵌入
- 定义一个列表中的一个字符(即 m)。例如,可以使用字母数字和一些特殊字符。对于我的例子,英语字符(52),数字(10),特殊字符(20)和一个未知字符,UNK。总共 83 个字符。
- 将字符转换为 1-hot 编码,得到一个向量序列。对于未知字符和空白字符,用全零向量代替。如果超过预定义的最大字符长度(即 l),则忽略它。每个字符的输出是 16 维向量。
- 使用 3 个 1D CNN 层(可配置)来学习序列
句子嵌入
- 双向 LSTM 遵循 CNN 层
- LSTM 之后添加了一些辍学层。
密码
这个示例代码将演示如何使用字符嵌入来进行分类。测试数据集可以在 UCI ML 知识库中找到。
预处理
首先,我们需要准备元信息,包括字符字典和将标签从文本转换为数字(因为 keras 只支持数字输入)。
preporcess(labels=df['category'].unique())
输出
-----> Stage: preprocess
Totoal number of chars: 83
First 3 char_indices sample: {';': 0, '"': 1, 'A': 2}
First 3 indices_char sample: {0: ';', 1: '"', 2: 'A'}
Label to Index: {'b': 0, 'e': 2, 'm': 3, 't': 1}
Index to Label: {0: 'b', 1: 't', 2: 'e', 3: 'm'}
流程
我们必须将原始输入训练数据和测试转换为 keras 输入的 numpy 格式
x_train, y_train = char_cnn.process(
df=train_df, x_col='headline', y_col='category')
x_test, y_test = char_cnn.process(
df=test_df, x_col='headline', y_col='category')
输出
-----> Stage: process
Number of news: 100
Actual max sentence: 3
Train Shape: (100, 5, 256) (100,)
-----> Stage: process
Number of news: 10
Actual max sentence: 1
Train Shape: (10, 5, 256) (10,)
建立模型
利用 CNN 层和双向 LSTM 构建字符 CNN 文本分类器。首先,用一维 CNN 建立字符块
def _build_character_block(
self, block, dropout=0.3,
filters=[64, 100], kernel_size=[3, 3],
pool_size=[2, 2], padding='valid', activation='relu',
kernel_initializer='glorot_normal'):
for i in range(len(filters)):
block = Conv1D(
filters=filters[i], kernel_size=kernel_size[i],
padding=padding, activation=activation,
kernel_initializer=kernel_initializer)(block) block = Dropout(dropout)(block)
block = MaxPooling1D(pool_size=pool_size[i])(block) block = GlobalMaxPool1D()(block)
block = Dense(128, activation='relu')(block)
return block
句子级别块将使用 3 个字符块构建
def _build_sentence_block(
self, max_len_of_sentence, max_num_of_setnence,
filters=[[100, 200, 200], [200, 300, 300], [300, 400, 400]],
kernel_sizes=[[4, 3, 3], [5, 3, 3], [6, 3, 3]],
pool_sizes=[[2, 2, 2], [2, 2, 2], [2, 2, 2]],
dropout=0.4):
sent_input = Input(shape=(max_len_of_sentence, ), dtype='int64')
embedded = Embedding(self.num_of_char, char_dimension,
input_length=max_len_of_sentence)(sent_input)
blocks = []
for i, filter_layers in enumerate(filters):
blocks.append(
self._build_character_block(
block=embedded, filters=filter_layers,
kernel_size=kernel_sizes[i],
pool_size=pool_sizes[i])
) sent_output = concatenate(blocks, axis=-1)
sent_output = Dropout(dropout)(sent_output)
sent_encoder = Model(inputs=sent_input, outputs=sent_output) return sent_encoder
最后,我们将根据句子建立文档块
def _build_document_block(
self, sent_encoder, max_len_of_sentence, max_num_of_setnence,
num_of_label, dropout=0.3,
loss='sparse_categorical_crossentropy', optimizer='rmsprop',
metrics=['accuracy']):
doc_input = Input(shape=(
max_num_of_setnence, max_len_of_sentence), dtype='int64')
doc_output = TimeDistributed(sent_encoder)(doc_input)
doc_output = Bidirectional(LSTM(
128, return_sequences=False,
dropout=dropout))(doc_output) doc_output = Dropout(dropout)(doc_output)
doc_output = Dense(128, activation='relu')(doc_output)
doc_output = Dropout(dropout)(doc_output)
doc_output = Dense(
num_of_label, activation='sigmoid')(doc_output) doc_encoder = Model(inputs=doc_input, outputs=doc_output)
doc_encoder.compile(
loss=loss, optimizer=optimizer, metrics=metrics)
return doc_encoder
输出
训练
train(x_train, y_train, x_test, y_test, epochs=10)
输出
结论
你可以从 github 中找到所有代码。
字符嵌入是解决大量文本分类的绝妙设计。它解决了一些单词嵌入问题。字符嵌入和单词嵌入的区别在于,字符嵌入可以构建任何单词,只要包含这些字符。
脸书艾研究(尚可)做了更进一步。小组使用子词来训练模型。以“脸书”为例,他们用“F”、“Fa”、“Fac”等来训练单词。关于 fasttext 的详细信息,您可以访问他们的网站以便更好地了解。
这是对字符嵌入的一些评论,因为它不包括任何词义,而只是使用字符。我们可以同时包括字符嵌入和单词嵌入来解决我们的 NLP 问题。
额外材料
关于我
我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客、 LinkedIn 或 Github 联系我。
参考
[1]托马斯·米科洛夫、格雷戈·科拉多、程凯和杰弗里·迪恩。向量空间中单词表示的有效估计。2013 年 9 月。https://arxiv.org/pdf/1301.3781.pdf
[2]张翔,颜乐存。文本理解从零开始。2016.https://arxiv.org/pdf/1502.01710v5.pdf
[3]金伊、杰尼特伊、桑塔格、拉什…字符感知神经语言模型。2015.https://arxiv.org/pdf/1508.06615.pdf
按城市划分的最佳和最差租赁时间
寻找一个新的公寓或晚上更新你的租约是我们许多人每年都必须参与的一些更有压力的事件。一部分原因是每天都可能发生的租金定价的剧烈波动。特别是对于长期租赁,即使是轻微的租金价格上涨也意味着租赁期内的一笔巨款。利用 Zillow 提供的逐月单居室租金数据,我们来看看一些与租金相关的指标:
美国顶级城市租金最贵和最便宜的月份
年同比租金价格趋势
每个市场的价格波动幅度
下面我将呈现一些最有趣的全国范围内的见解,但如果你有兴趣查看特定的州或城市,我强烈推荐你访问我的 免费互动仪表板 ,以便更深入地挖掘你感兴趣的地点。
租金最贵的城市:一居室租金定价——按月租金中位数(美元)排序
看看排名前 50 位的市场,通常都是顶级玩家。大城市和硅谷位居前列,前五大市场的一居室公寓平均月租金超过 2000 美元!旧金山以每月 3480 美元的租金中位数领先,这似乎很荒谬。然而,这五大市场的租金中值增幅不超过 1.7%(纽约),实际上旧金山、圣何塞和波士顿的租金有所下降(我知道你在想什么,“太便宜了!”).那么,如果这些顶级市场没有继续暴涨,那么哪些市场会继续暴涨呢?
上涨的租金成本:单卧室租金定价——按租金中值的同比变化排序
当查看前 50 个市场中哪个经历了最大的年同比增长时,北卡罗来纳州和加利福尼亚州占据了前 5 名。北卡罗来纳州城市罗利和夏洛特的增长率分别为 29%和 14.5%。在加州,萨克拉门托、阿纳海姆和长滩的同比增幅分别为 14.5%、14.3%和 14.0%。
定价可变性:单卧室租金定价——按月定价可变性排序
我为此分析的另一件事是定价的每月可变性。为此,我查看了每个城市最贵月的租金中位数和最便宜月的租金中位数之间的差异,并将该差异除以 2016 年的租金中位数。田纳西州的孟菲斯以 30.2%的可变性击败竞争对手,紧随其后的是底特律(22.7%)。这两个城市的月租金都相对较低(月租金中位数都在 700 美元以下),但排名第三的阿纳海姆的月租金变动率为 18.9%(最便宜的月份(仍为 1575 美元)和最贵的月份(1883 美元)相差 308 美元)。另一个值得一提的是旧金山,排在前十名之外。在 12 月(3100 美元)和 2 月(3635 美元)租公寓有 535 美元的月差。尽管如此,引用北加州人的话说,即使是最便宜的月租金 3100 美元也是“海拉贵”。
当观察排名最前的所有 272 个城市时,发现平均而言,租金最便宜的月份是 1 月和 12 月,其中 34.2%的城市有最便宜的月份。租金最贵的时间往往是在夏季的中心(9 月是 13.1%的城市租金最贵的月份,紧随其后的是 6 月和 7 月。
现在让我们来看看排名前 100 的市场,这些市场被贴上了一居室租金最便宜的月份的标签。瓷砖按州进行了着色:
现在,这些只是一些样本见解,但我已经建立了一个交互式仪表板,供您在 Tableau Public 上访问和互动,以便您可以更深入地了解您最关心的州和城市。点击此处查看!
要阅读更多关于公立学校免费餐项目、NBA 出勤率和旅游业的数据报道,请点击这里!
最佳和最差租赁月份(美国前 30 大市场):
纽约纽约纽约房租最便宜的月份:12 月(比纽约房租中位数低 5)
纽约房租最贵的月份:10 月(比纽约房租中位数高 7)
加州洛杉矶
洛杉矶房租最便宜的月份:12 月(比洛杉矶房租中位数低 7)
洛杉矶房租最贵的月份:4 月(比洛杉矶房租中位数高 1)
芝加哥、 伊利诺伊州
芝加哥房租最便宜的月份:7 月(比芝加哥房租中位数低 3)
芝加哥房租最贵的月份:2 月(比芝加哥房租中位数高 11)
德克萨斯州休斯顿
休斯顿房租最便宜的月份:11 月(比休斯顿房租中位数低 9)
休斯顿房租最贵的月份:1 月(比休斯顿房租中位数高 8)
费城、 宾夕法尼亚州
费城房租最便宜的月份:1 月(比费城房租中位数低 3)
费城房租最贵的月份:5 月(比费城房租中位数高 4)
亚利桑那州凤凰城
凤凰城房租最便宜的月份:12 月(比凤凰城房租中位数低 5)
凤凰城房租最贵的月份:6 月(比凤凰城房租中位数高 7)
拉斯维加斯、 内华达州
拉斯维加斯房租最便宜的月份:7 月(比拉斯维加斯房租中位数低 2)
拉斯维加斯房租最贵的月份:6 月(比拉斯维加斯房租中位数高 3)
德克萨斯州圣安东尼奥
圣安东尼奥房租最便宜的月份:12 月(比圣安东尼奥房租中位数低 4)
圣安东尼奥房租最贵的月份:3 月(比圣安东尼奥房租中位数高 3%)
要查看其他几大城市房租最便宜和最贵的月份,请前往 我的网站 !
感谢您阅读我最新的数据帖子。作为一名产品营销和数据分析专业人士,我对数据支持的讲故事充满热情。这些数据新闻帖子是我将真实数据与我个人的不同兴趣整合起来的方式,这些兴趣包括从旅行和娱乐到经济和社会问题的任何事情。
如果您有任何评论、故事想法或预期的数据项目,请随时发送电子邮件至 dwpwriting <至> gmail < dot > com 或通过LinkedIn联系我。
原载于 2017 年 12 月 3 日【dwpeterson.com】。
最佳书架:用 D3.js 改编真实世界对象的数据可视化
这个项目是关于数据可视化项目,最好的书架。
1996 年以来《纽约时报》评选的最佳书籍的数据可视化。由谭永金创作。由…提供动力
tany.kim](http://tany.kim/best-bookshelf)
当你听到“数据可视化”时,第一个想到的视觉形式是什么?条形图还是折线图?一些更奇特的东西,比如热图或者定向网络?虽然这些经过验证的可视化技术已被广泛用于有效地交流数据,但独特的视觉形式可以更好地实现主题匹配,并且可以简单地在视觉上更令人愉悦*,而*不会牺牲数据可视化最重要的作用——将数字真实地编码为视觉元素。
这篇文章是关于我最近的数据可视化项目最佳书架的设计过程。我将书籍和作者数据可视化,以适应现实世界中的物体、书籍和书架。改编有三个方面。
- 每本书的数据维度被编码到一本书的物理属性中。
- 分组和排序书籍的方式类似于书架上存放书籍的各种规则(每个人都有她或他自己的方式!).
- 交互和跟随动画复制了在书架上拿起和移动书籍的动作。
How would you organize your books on the bookshelf? (source)
Curious to know what the height, width, diagonal lines, tags, and colors mean? How would you organize books?
《纽约时报》最佳书籍及其元数据
我关心我花时间看的内容的质量。在找好书推荐的时候,偶然看到一篇文章,《纽约时报》的2016 年 10 本最好的书。从这开始,我列出了从 1996 年开始的所有最好的书,那是 NYT 第一次宣布最好/最著名的书。后来,利用Goodreads API和纽约时报图书 API (当然还有手工填写电子表格),我收集了每本书及其作者的元数据。Python 脚本可以在我的 GitHub repo 获得。
最终,我有了 206 本书和 184 个作者。数据集包括以下字段。在这里,我按数据类型列出了它们——它们是在设计过程中将被可视化编码的东西。
名义数据
- 书名:如《房间》
- 作者姓名:如爱玛·多诺霍
- 出版商:例如,利特尔、布朗和公司
分类数据—每种类型有两个值
- 体裁:小说和非小说
- 作者性别:女性或男性
- 畅销书:要么这些书是纽约时报的畅销书,要么不是
- 语言:原文为英文或翻译
定量数据—序数
- 选择年份:例如,2010 年
- 出版和原始出版日期
- 作者的出生日期:如 1969 年 10 月 24 日
- 作者死亡日期:可以为空
定量数据—连续
- 页数
- 给图书评分的 Goodreads 用户数
- 平均阅读评分
- 最初出版时作者的年龄:从最初出版日期和出生/死亡日期开始计算。
- 书名的长度
数据集的初步检查
在可视化设计的早期阶段,我通常会快速检查数据集,看看是否有什么有趣的模式。我使用的一些常用方法是带有 ggplot 的 R 和带有 Matplotlib 或 Seaborn 的 Python。为了这个项目,我也尝试了 Tableau Public 。通过这项初步工作,我从数据集中发现了一些事实。举几个例子,我看到大多数书的页数在 200-400 页之间;小说的作者比非小说的作者年龄范围更广。从过去 11 年的数据来看,我并没有看到作者性别的不平衡(但是你会在文章的最后看到一些不同的东西!).
Age of author at publication & Number of pages, generated with Python Matplotlib
Gender of authors of the best books from 1996 to 2006
另外,我按年创建了小倍数。这是用 D3.js 做的。
Small multiples: visualizing best books by year
在这一点上,我不相信数据集对于一个交互式可视化项目来说是足够引人注目的。老实说,尽管我在生成数据集方面付出了努力,但我还是对继续这个项目持怀疑态度。
来自日常物品的设计灵感
我承认简单地在二维图表上绘制图书并不有趣,我开始考虑一种不同的方法——根据不同的数据维度列出和过滤图书。这样,作为数据点的书籍可以以线性方式显示;然后我意识到这正是人们整理书架上书籍的方式。
将数据字段编码成书籍的物理属性
在一本书的物理属性中,我重点关注了当一本书被垂直放在书架上时可以实际看到的那些属性。你只会看到书脊是一个细长的长方形,其宽度由页数决定(假设纸张厚度相同)。因此,将页面数量编码成矩形宽度是一个直观的决定。高度的决定是相当武断的,但我希望它是现实的;*物理属性的维度可以代表一个数据字段的范围。*在连续的数据维度中,我发现所有书籍的平均 Goodreads 评分大多在五分之三以上。从之前的数据检查中,我发现作者在出版时的年龄在可视化时会很有趣。因此,这个连续的变量在脊柱上呈现为半透明的覆盖层。带有 D3 和 Lodash 的 javascript 代码如下所示:
const storyH = 100; //same as maximum book height
const bookWRange = [10, 60]; //book thickness
const bookHRange = [60, storyH]; //book height rangeconst pages = books.map((d) => d.book.pages);
const pageRange = getRange(pages, 100);
const ageRange = getRange(ages, 10);//pages to width
const bookW = d3.scaleLinear().domain(pageRange).range(bookWRange); //average rating to height
const bookH = d3.scaleLinear().domain([3, 5]).range(bookHRange); //age to overlayed height
const middleH = d3.scaleLinear().domain(ageRange)
.range([10, bookHRange[0]]);//get floor/ceiling range
function getRange(arr, by) {
return [
Math.floor(_.min(arr) / by) * by,
Math.ceil(_.max(arr) / by) * by
];
}
在数据集中,有四种分类数据。我想把这一点也编码到书的其他物理属性中。所有这些维度都是二元的,或者有两个可能的值。体裁用颜色区分(绿色代表小说,红色代表非小说)。女作家的书充满了斜线(性别通常用颜色来表示,但我想避免太传统的东西。《纽约时报》的畅销书都标有一颗星。已翻译的图书会在左上角突出显示一个三角形。
Total seven data dimensions are represented as physical attributes of a book. This legends are introduced on the actual project page.
组织书籍-对数据集进行分组和排序
让我们重温一下数据类型——分类数据、名义数据、数量序数数据和数量连续数据。为了组织书籍,C 分类和顺序变量用于分组数据点,而名义和连续变量用于排序。
Organizing (grouping or sorting) options in HTML page: first, the books are grouped by year, then by genre. The labels are both levels are also displayed.
这些分组和排序功能是作为 HTML 页面中的下拉选择实现的。一旦用户选择了对数据集进行分组或排序的维度,所有的书都会重新排列。如果第一个选择的项目是用于分组的维度,则可以在第一个类别下进一步对图书进行分组或排序(如果第二个级别也是分组,则图书按照第二个组中的原始数据集中所列进行排序)。如果用户选择一个名义或类别尺寸,第二个选项变得不可见。
When the books are sorted by the number of pages (ascending), the dividers appear and the labels are seen as the first-level grouping
排序或分组的结果被合并到可视化中。我把第一个选项的标签放在书架上层的书上。例如,当书籍第一次按年份排序时,您会看到年份和年份内的书籍数量。第二层标签显示在书籍之间的分隔线上。当书名或作者的名字在书脊上旋转时,第二级选项的名字也旋转。当书籍没有预先分组就被分类时,我在书籍之间添加了分隔线,以便更好地索引。
D3 书的物理运动的过渡
Moving mouse over a book triggers lifting the book and tooltip popup.
当鼠标悬停在一本书上时,这本书的垂直位置会发生变化,这是在模仿被拾取的书的状态。这种微妙的过渡可以包含现实世界物体的特征。
重组书籍意味着改变视觉元素的位置。书籍的过渡以随机速度进行动画制作,首先到同一文章的新位置(X 位置),然后到新文章(Y 位置)。
来自最佳书架的见解
正如我之前所描述的,我没有发现很多关于《纽约时报》选择最佳书籍的惊人事实(模式、相关性或异常值)。然而,调整书架的逻辑和美学,这种可视化有助于研究书籍的视觉编码属性。我发现了一些有趣的见解:
- 2009 年是《纽约时报》选择女性作者的书籍多于男性作者的第一年。自 1996 年以来,男女作家之间一直不平衡。我个人想多读读女人说的话,所以这个发现很重要。
- 非科幻片往往有一个较长的标题,主要是由于它的描述性副标题。与 23 部小说相比,只有 3 部非小说的标题少于 10 个字母。
- 英文原版书占主导地位。只有 11 本书是翻译的,没有一本是 2003 年以前选的。
- 成为畅销书并不意味着 Goodreads 上的高收视率。不过似乎和平均评分更有关系。如果平均评分高于 5 分中的 4 分,成为畅销书的几率会增加约 50%。
- 当作者 35 岁或更年轻时,只有 4 本非小说类图书出版,而当作者 35 岁或更年轻时,有 15 本小说出版。最年轻的五位作者都是小说家。
在最终设计中,我添加了一个输入表单,用户可以通过作者姓名、书名或出版商进行搜索。当用户键入三个或更多字母时,会显示结果总数。这样就可以了解到出版社的图书数量。Knopf 的书最多,25 本;企鹅出版社出版了 16 本,兰登书屋出版了 15 本。
这个项目是一个不直接使用传统图表的数据可视化的例子。相反,我将数据集的主题“书”关联起来,将书和书架的物理属性应用到可视化设计中——将单个数据作为书(将定量连续数据编码为书的大小,将分类数据编码为颜色/图案/标记),将数据集分组和排序作为组织书的规则,D3 转换作为组织书时书的移动。我希望这篇文章对那些想要创建足够有创意但又不会迷惑用户的定制数据可视化的人有所帮助。
你发现最好的书有什么有趣的地方吗?请通过回复让我们知道!
购买小玩意最贵和最便宜的国家
你在哪里可以买到清单上那个小玩意的最优惠价格?使用这个包含 2016-2017 年 72 个国家流行电子设备和品牌成本的数据集,我探索了购买特定小工具最昂贵和最便宜的国家。
gadget price by country and continent (excluding Venezuela)
我们可以进行许多观察,包括但不限于:
- 安哥拉是购买 iphone 的好地方,但不是安卓产品、PS4 或智能电视的好地方
- 孟加拉国在硬盘方面提供很好的交易
- 而在匈牙利,也得到了一台 PS4
- 从俄罗斯买苹果手表可能比从菲律宾买要好
当我第一次看这些数据时,委内瑞拉的物价看起来完全疯了(一部 iphone 可能要 10 万美元),我起初以为有什么问题,直到我读了这篇 Times 的文章,才意识到通货膨胀已经把它的价格吹得不成比例。
如果包括委内瑞拉小配件价格的异常值,图表看起来像这样:
New way to flout your wealth is to buy a gadget in Venezuela
按国家查看后,我们可以探究区域级别的价格。
Gadget price benchmark by region
在区域一级,我们可以看到:
- 大洋洲的 Xbox one 和 Apple Watch 价格更低
- 几乎所有非洲国家苹果产品和游戏设备的价格都高于中值
- 品牌耳机在亚洲有点贵,而 Macbook 在大多数国家价格较低。
除了与全球基准相比,我们还可以与考虑了工资因素的当地购买力相比。这更能说明一个国家的电子产品对当地消费者来说价格过高。
Gadget price is relatively high in several South America and Southeast Asian countries considering purchasing powers
这是我关于数据科学和视觉故事的# 100 日项目的第 25 天。我的 github 上的全部代码。感谢阅读,欢迎反馈。
机器学习和数据科学的最佳 Python 库:(第 1 部分)
Python 日渐流行,已经开始取代业界很多流行的语言。Python 受欢迎的主要原因是因为以下原因:
- Python 因其简单性而被称为初学者语言。
- Python 有助于开发人员从开发到部署和维护都更加高效。
- 与 Java、C 和 C++相比,Python 的语法非常简单和高级,因此可以用更少的代码行构建应用程序。
- Python 有大量的库集合。
- 可移植性(当然概率也是 Java 的主要特点)。
用于机器学习的 Python:
python 的简单性吸引了许多开发人员建立机器学习和数据科学的库,因为所有这些库,Python 几乎作为数据科学的 R 而流行。一些最好的 Python 机器学习库是:
1.张量流:
如果你正在工作或者对机器学习感兴趣,那么你可能听说过这个著名的开源库 Tensorflow。它是由谷歌大脑团队开发的。谷歌几乎所有的应用都使用 Tensorflow 进行机器学习。如果你正在使用谷歌照片或谷歌语音搜索,那么你就间接地在使用 Tensorflow 建立的模型。
Tensorflow 只是一个计算框架,用于表达涉及大量张量运算的算法,因为神经网络可以表示为计算图形,它们可以使用 Tensorflow 作为对张量的一系列运算来实现。张量是代表我们数据的 N 维矩阵。
tensorflow 的主要优势是并行性,这意味着您的计算图形是并行执行的,您可以完全控制执行,并且可以在不同的处理器上调度不同的操作,如 CPU、GPU 等。
Tensorflow 基本上是用 C 和 C++编写的,但有一个复杂的 Python 前端。您的 Python 代码被编译,然后在使用 C 和 C++开发的 Tensorflow 分布式执行引擎上运行。Tensorflow 针对速度进行了优化,它可以利用 XLA 等技术来实现更快的线性代数运算。您可以使用 pip 获取 Tensorflow 或访问该网站获取说明:https://www.tensorflow.org//?nav=true
详细教程:https://www . data camp . com/community/tutorials/tensor flow-tutorial
2.Numpy:
Numpy 当然是 Python 最伟大的数学和科学计算库之一。Tensorflow 和其他平台在内部使用 Numpy 对张量执行多种操作。Numpy 最重要的特性之一是它的数组接口。
该接口可用于将图像、声波或任何其他原始二进制流表示为 N 维实数数组。Numpy 知识对于机器学习和数据科学非常重要。
3.Keras:
Keras 是最酷的机器学习库之一。如果你是机器学习的初学者,我建议你使用 Keras。它提供了一种更简单的表达神经网络的方法。它还提供了一些用于处理数据集、编译模型、评估结果、可视化图表等的工具。
Keras 内部使用 Tensorflow 或 Theano 作为后端。也可以使用其他一些类似 CNTK 的 pouplar 神经网络框架。如果您使用 Tensorflow 作为后端,那么您可以参考本文 Tensorflow 部分显示的 Tensorflow 架构图。与其他库相比,Keras 速度较慢,因为它使用后端基础设施构建计算图,然后使用它来执行操作。Keras 模型是可移植的(HDF5 模型), Keras 提供了许多预处理数据集和预训练模型,如 Inception、SqueezeNet、Mnist、VGG、ResNet 等
Keras 教程:https://elitedata science . com/keras-tutorial-deep-learning-in-python
4.Theano:
Theano 是一个计算多维数组的计算框架。Theano 类似于 Tensorflow,但其效率不如 Tensorflow,因为它无法适应生产环境。Theano 可以像 Tensorflow 一样用在并行或分布式环境中。
教程:【http://deeplearning.net/software/theano/tutorial/
更多的库将在下一部分介绍。谢谢你,☺
文本分类深度学习最佳研究文章(2015–2016)
文本分类在许多任务中都有应用,例如句子分类、文档分类、情感分析等。当我最初开始寻找使用深度神经网络进行文本分类的研究文章时,我发现很难找到最近最好的文章。经过相当长的时间和努力,我能够总结使用深度神经网络进行文本分类所需的研究文章:)
这些文章已经按顺序排列,这有助于读者逐步学习和理解各种深度神经网络模型,因此随着列表的下降,复杂程度增加;)
- 许多关于神经网络尤其是卷积神经网络的文章都涉及图像数据。但是第一篇文章“用于句子分类的卷积神经网络”有助于读者理解 CNN 关于文本数据的基础知识,这对于理解来说是惊人的。
- 一旦读者理解了 CNN 在文本数据上的用法,下一步就是帮助神经网络从零开始理解文本;)
- 本文详细介绍了如何构建一个用于文本分类的字符级 CNN以及更多的实验结果。需要注意的是,本文是对第 2 点中提到的文章的详细撰写;)
- 所有上述文章都处理像句子这样的文本数据,但(几乎)从未处理过文档分类,尽管文档分类是最重要的任务之一。但是关于“Recurrent CNN for text class ification”的文章考虑到了这个缺点,并提出了一个神经网络模型来显式地处理文档分类。
请随意评论更多关于文本分类的感兴趣的文章。
应对人工智能黑暗面的最佳方法
人工智能(AI)是一个已经发展了一段时间的概念。它对我们今天的生活有着切实的影响。事实上,它是如此的主流,以至于它几乎存在于我们所做的、所见的、所触的和所听的一切事物中。虽然有些人利用这一点为我们的社会做出积极贡献,但其他人却以更可疑的方式从中赚钱,丝毫不顾他们的社区或他们行为的后果。这是生命中一切事物的命运——包括人工智能。当在正确的人手中时,人工智能提供了很好的网络安全解决方案,但与此同时,黑客和网络罪犯也在使用它来进行他们的秘密活动。
使用双重性问题
Teiss 说这很可悲,但却是事实:人工智能技术可能会导致创新类型的网络犯罪和政治危机的发生。这是因为网络安全官员在战斗中落后了。虽然一旦黑客发动攻击,他们需要一段时间来创建合理的解决方案,但网络犯罪分子自己可以迅速找到系统和网络中的新漏洞进行攻击。从这个角度来看,人工智能就像一把双刃剑——既可以用来打击犯罪,也可以用来增强安全系统。
为什么提高意识很重要
意识是更好的在线和数据保护习惯的开始,这将降低网络犯罪率(例如,身份盗窃、隐私泄露、被盗信用卡号)。在某个时候,即使是最注重隐私的人也会成为人工智能技术被用于邪恶目的的受害者。
人工智能现在被认为是一个广泛的主题。虽然今年没有很多重要突破,但它显然有可能产生新的威胁。这就是为什么创建有效的监管框架至关重要,这样你的企业才能更好地防止人工智能技术的恶意实施。在这些恶意实现之外,AI 是一个奇妙的东西。然而,正是这些恶意的实现威胁着我们现有的所有在线互动。
涉及人工智能技术的可能威胁
教育人们如何使用人工智能以及如何将它用于好的目的是很重要的,因为大多数人听到的是人们如何使用它以不良和不负责任的方式行事。然而,很多人没有意识到的是,AI 是一个自动检测软件漏洞的伟大工具。然而,网络罪犯正在利用这一点,在人们最意想不到的时候发动攻击。这增加了目前存在的恶意链接和附件的数量。可悲的是,这可以超越数字平台,进入我们的物理世界——例如,恐怖分子在技术驱动的发展和发明中植入炸药。
在一些社会中,人工智能也被用来制造政治混乱。一些政府甚至用它来压制少数民族和那些对其政权持异议的人。还有一些设备被用来制造虚假信息运动,并执行拒绝信息罪,以产生和传播假新闻。
虚拟专用网络如何帮助
阻止网络罪犯的最佳方法之一是实施不太容易被黑客攻击的软件和设备。这是政府和国际监管机构需要参与的事情,提供资金资助这些技术的研究和开发。
实施 VPN 服务(虚拟专用网)将是另一个伟大的解决方案。这些将加密你的内容,所以人们不能窥探你-你基本上绕过互联网服务提供商,黑客和政府监督机构。
适用措施
T4 对网络安全情报的使用将有助于挫败网络攻击。要做到这一点,你需要理解为什么你必须改进技术工作。这将需要使用人工智能的国家之间更好、更顺畅的政策整合。这里的主要目标是了解人工智能错误信息和滥用的危险,以便人工智能支持的网络攻击和黑客事件的影响可以最小化,人工智能技术可以用作防御机制。
要做到这一点,决策者和研究负责人必须合作。目前,当人工智能用于数字安全时,政府和网络安全行业必须控制、培养和资助人工智能的创新进展。道德的最佳实践必须被认为是有效的,无害的创造被发现。
每个人都必须付出努力
重要的是采用一种有效的方法来应对人工智能的双重用途问题。在这个过程中会有一些模糊和争议,因为不存在针对网络犯罪威胁的快速、直接的解决方案。采取上述一些措施将有助于我们应对网络犯罪的影响,并为长期解决方案建立一个框架。一些专家认为,找到确定的解决方案可能永远也不可能。相反,我可能只是在事情上贴了一个“创可贴”。
政府到达
我们大多数人已经知道并理解黑客事件或重大网络攻击可能造成的损害程度。这是因为社会工程和虚假信息运动更容易产生“虚假”内容。虽然有些人可以快速而容易地确定一幅图像是否被篡改,但这对于主流媒体来说并不容易确定。这就是为什么人们很容易陷入恐慌。使用人工智能来预测未来可能会成为一种徒劳的练习,因为它必须扩展今天的威胁,同时也扩展抵御网络威胁所必需的防御机制。
结论
我们的知识和我们对人工智能的使用之间有很大的差距。这种争论有时会避开某些领域——尤其是那些尚未完全开发的领域。这就是为什么政府、研究人员、网络安全公司和行业专业人士必须共同努力,击退黑客和网络罪犯。这不仅仅是建立一个充满可能解决方案的政策框架。他们还必须投资工具来打击 AI 的恶意使用。虽然这些人负责处理这个问题,但理解人工智能是一个影响我们所有人的问题很重要。当黑客利用和完善 AI 的时候,所有人都会受害。这些影响将是巨大的,尤其是当涉及到影响个人的数据隐私和匿名时。
更好的协作数据科学
从 Kaggle 社区学到的两个指导性见解
上周六,我在南加州最大的数据会议Data Con LA 2018(原大数据日 LA)上做了主题演讲。这是我的博客形式的演讲。
在我的主题演讲中,我分享了 Kaggle 的团队学到的两件事,这些事让数据科学家能够在项目中更高效地合作。这两种见解决定了我们的社区在过去八年中如何发展成为世界上最大的数据科学家在线社区。
- 获得社会认可的知识的重要性
- 使数据项目易于复制的重要性
Kaggle 简介
首先,以防你没听说过 Kaggle,我给你提供一点背景。今天,超过 200 万 Kagglers 来到这个平台来做数据科学项目。他们参加机器学习竞赛,并在我们的数据集平台上发布和探索数据。对于竞赛和我们的数据集平台,用户可以用 R 或 Python 分析数据,并与我们的免费托管笔记本环境 Kernels 分享他们的工作。
Some recent stats about Kaggle’s prolific community. August 2018.
所有这些竞赛、内核中共享的开源代码以及公共数据集,都让我们对数据科学家如何合作解决问题有了更深入的了解。
有了这个简短的介绍,我想直接进入这两个洞见,从获得社会认可的知识开始。
我们很早就了解到,即使在竞争激烈的环境中,我们的社区也非常积极地分享知识,但有时发现和改进信息和想法很困难。
当 Kaggle 上的每个竞赛结束时,用户在论坛上分享获胜和创新的解决方案;他们已经在我们的博客上发布了 200 多个“我是如何做到的”采访。有时甚至发表关于新方法的论文,如使用 WaveNet 进行销售预测或使用卷积神经网络诊断糖尿病视网膜病变的一些早期工作。
现在有一个传统,每当一个新的比赛开始时,竞争者会立即在我们的网站和互联网上搜寻他们可以用来启动他们在这个新挑战上的工作的见解。虽然一方面,这些内容的存在很棒,但每次需要访问它们时,这本身就是一个挑战。
现在,我想用一个例子来对比一下,在这个例子中,获取知识不仅容易,而且很容易。为此,让我们转向 XGBoost 梯度增强库的开发。
在早期,作者陈天琦 在竞争论坛上引导竞争对手逐步安装和试用他的新软件。在那里,他对意外行为和撞车的报告做出反应。他甚至能够在比赛结束时通过调查寻求反馈。结果,他做了改进,修复了他知道对图书馆用户很重要的错误。
几年后,XGBoost 成为在结构化数据上进行机器学习的最成功的算法之一,这要归功于社区中用户的紧密反馈循环,在这个社区中,知识得到了积累,质量得到了提高。
回到每次比赛产生的知识洪流的例子。今天,我们提供工具来帮助用户发现与他们想要解决的问题相关的内容。
例如,我们的一个用户利用我们关于 Kaggle 的公共数据集 Meta Kaggle,创建了所有获奖解决方案的最终主列表,使用多类分类等标签按问题陈述和特征进行组织。例如,现在每当多类分类竞赛开始时,用户就可以一站式查阅过去在类似问题上的工作。
在一个类似的例子中,另一个 Kaggler 使用标签和其他流行度指标创建了一个数据科学词汇表,其中包含了内核中共享的所有顶级开源代码,这些代码通过使用标签的技术进行组织。对于开始新数据项目的人来说,这是多么不可思议的资源啊!
那么我们的团队从这样的例子中学到了什么呢?我们的团队坚信,没有人应该从闪烁的光标开始数据科学项目。
这种洞察力对于新的数据科学家来说尤其重要。无论是刚开始学习的人还是团队中的新人。它甚至适用于一个新的商业或研究问题。
使用集中定位的和可搜索的知识,通过与当前问题的相关性来组织,用户应该能够更快地开始编写代码和回答问题。我们还了解到,像 XGBoost 这样在我们的社区中得到社会验证的知识,或者通过可用性和流行度指标得到验证的知识,对于识别和重复好的想法是至关重要的。
关于协作数据科学,我们学到的第二个观点是让您的工作具有可重复性的重要性。再现性不仅对你的队友很重要,对你的头号合作者也很重要:你未来的自己。
为了说明可再生数据科学的重要性,我将回到五年前的一场比赛。在这个例子中,一个用户出于好意,希望让更多的人参与到协作解决问题中来。
然而,在这篇论坛帖子中,我们观察到数据科学家在试图分享他们的工作时遇到的许多绊脚石。
- 首先,在一个 pastebin 中共享他的代码。我们也经常看到用户将 Python 和 R 代码作为论坛附件添加给其他人下载,并弄清楚如何在本地运行。
- 其次,他列出了他对数据形状的假设。他必须这么做,因为他没有分享数据本身。
- 最后,真正有意思的是,他在自己的帖子上添加了一个更新。其他人(企图合作!)发现了一个 bug,所以他不得不在 pastebin 中调整他的代码。每个下载旧代码的人都被蒙在鼓里。
所有这些挑战,我们在早期的 Kaggle 论坛上反复看到,意味着代码、想法和结果极难重现。这是合作的巨大障碍,即使有意愿(或必要性)也是如此。
我们的团队没有忽视用户在协作方面的痛点。我们希望让用户能够轻松分享他们的想法并进行协作,因此我们构建了内核,这是我们为笔记本和脚本提供的免费托管计算环境。从这里开始,事情发生了巨大的变化。
为了说明这一点,我在这里展示了一个Fran ois Chollet 的教程内核,演示了如何使用他当时的新库 Keras,在预测西尼罗河病毒的比赛中获得可观的分数。
Franç ois Chollet 的 starter 内核与通过 pastebin 五年共享的代码形成了巨大的对比,因为内核是代码、数据和环境的版本包。这意味着大约 60 个用户能够从他们自己的副本中派生出他的代码并执行。
在这一点上,我希望你记得一个更早的统计数据:截至 2018 年 8 月,平台上有 184,000 个公共开源内核,任何人都可以派生、运行和修改。现在只需点击一个按钮;没有混乱的安装或数据下载需要。
内核促进可再现性的容易程度也对 Keras 在 Kaggle 上的流行轨迹产生了很大影响。就在 6 月,超过 1500 个 Python 内核在 Kaggle 上导入了 Keras。
最后,这不仅仅是工具和基础设施的问题。我们还观察到,Kaggle 用户为他们的数据项目采用的最佳实践往往分为以下两类:
- 模板化
- 证明文件
模板化是一种最佳实践,例如跨项目使用公共目录结构、模块化代码和数据,以及为团队中常用的代码片段创建和共享库。
然后是文档。除了记录代码,我们的用户还在 Kaggle 上记录他们的数据。我们采访过的顶级 Kagglers 也普遍报告说保持包括重现结果的步骤的密切日志,特别是如果他们在比赛中不使用内核的话。他们还使用“实验室风格”笔记来记录他们实验的想法、他们测试的假设以及他们在迭代项目时的结果。这意味着想法和无效的结果不会被放到抽屉里积灰,而是可以从中学习。此外,他们可以为将数据项目用作投资组合的一部分打下良好的基础。
那么我们从这些例子中得到了什么启示呢?如果数据科学中的好想法易于复制,更多的人将能够质疑、使用和扩展这些好想法。
可再生数据科学项目将版本化的代码、数据和环境打包在一起。他们还使用模板化和文档化等最佳实践。
结论
总之,我们的团队了解到,数据科学家最大的两个需求是获得社会认可的知识,以及复制他们和其他人的工作的能力。
这些见解和其他见解已经告知我们如何开发我们的数据集和内核产品,以允许用户今天在竞争之外的数据项目上进行合作。
如果你想发现更多关于数据科学家如何合作的见解,我鼓励你查看我们关于 Kaggle 的公共数据集,Meta Kaggle 。有大量的社区内核可供浏览并从中派生出您自己的数据项目!