7.2. 真实世界数据集#

scikit-learn 提供了加载更大数据集的工具,如有必要,还会下载它们。

可以使用以下函数加载它们

fetch_olivetti_faces(*[, data_home, ...])

从 AT&T 加载 Olivetti 人脸数据集(分类)。

fetch_20newsgroups(*[, data_home, subset, ...])

加载 20 个新闻组数据集的文件名和数据(分类)。

fetch_20newsgroups_vectorized(*[, subset, ...])

加载并向量化 20 个新闻组数据集(分类)。

fetch_lfw_people(*[, data_home, funneled, ...])

加载 Labeled Faces in the Wild (LFW) 人脸数据集(分类)。

fetch_lfw_pairs(*[, subset, data_home, ...])

加载 Labeled Faces in the Wild (LFW) pairs 数据集(分类)。

fetch_covtype(*[, data_home, ...])

加载 covertype 数据集(分类)。

fetch_rcv1(*[, data_home, subset, ...])

加载 RCV1 多标签数据集(分类)。

fetch_kddcup99(*[, subset, data_home, ...])

加载 kddcup99 数据集(分类)。

fetch_california_housing(*[, data_home, ...])

加载加州房屋数据集(回归)。

fetch_species_distributions(*[, data_home, ...])

用于加载 Phillips 等人提供的物种分布数据集的加载器。

7.2.1. Olivetti 人脸数据集#

此数据集包含一组人脸图像,拍摄于 1992 年 4 月至 1994 年 4 月期间,地点位于 AT&T 实验室剑桥分部。sklearn.datasets.fetch_olivetti_faces 函数是数据获取/缓存函数,用于从 AT&T 下载数据存档。

正如原始网站上所述

该数据集包含 40 个不同对象的 10 幅不同图像。对于某些对象,图像是在不同时间拍摄的,变化包括照明、面部表情(睁眼/闭眼,微笑/不微笑)和面部细节(戴眼镜/不戴眼镜)。所有图像均在黑暗的均匀背景下拍摄,对象处于直立的正面位置(允许一些侧向移动)。

数据集特征

类别

40

样本总数

400

维数

4096

特征

实数,介于 0 和 1 之间

图像被量化成256个灰度级别,并存储为无符号8位整数;加载器会将其转换为[0, 1]区间内的浮点数,这对于许多算法来说更容易处理。

此数据库的“目标”是一个0到39之间的整数,表示图片中人物的身份;但是,每个类别只有10个示例,因此这个相对较小的数据集从无监督或半监督的角度来看更有趣。

原始数据集的大小为92 x 112,而此处提供的版本包含64x64的图像。

使用这些图像时,请注明版权归属:AT&T实验室剑桥分部。

7.2.2. 20个新闻组文本数据集#

20个新闻组数据集包含大约18000个关于20个主题的新闻组帖子,分为两个子集:一个用于训练(或开发),另一个用于测试(或性能评估)。训练集和测试集的划分是基于特定日期之前和之后发布的消息。

此模块包含两个加载器。第一个,sklearn.datasets.fetch_20newsgroups,返回一个原始文本列表,可以将其馈送到文本特征提取器,例如CountVectorizer(使用自定义参数),以提取特征向量。第二个,sklearn.datasets.fetch_20newsgroups_vectorized,返回可以直接使用的特征,即无需使用特征提取器。

数据集特征

类别

20

样本总数

18846

维数

1

特征

文本

使用方法#

sklearn.datasets.fetch_20newsgroups 函数是一个数据获取/缓存函数,它从原始的20个新闻组网站下载数据存档,将存档内容提取到~/scikit_learn_data/20news_home文件夹中,并在训练集或测试集文件夹(或两者)上调用sklearn.datasets.load_files

>>> from sklearn.datasets import fetch_20newsgroups
>>> newsgroups_train = fetch_20newsgroups(subset='train')

>>> from pprint import pprint
>>> pprint(list(newsgroups_train.target_names))
['alt.atheism',
 'comp.graphics',
 'comp.os.ms-windows.misc',
 'comp.sys.ibm.pc.hardware',
 'comp.sys.mac.hardware',
 'comp.windows.x',
 'misc.forsale',
 'rec.autos',
 'rec.motorcycles',
 'rec.sport.baseball',
 'rec.sport.hockey',
 'sci.crypt',
 'sci.electronics',
 'sci.med',
 'sci.space',
 'soc.religion.christian',
 'talk.politics.guns',
 'talk.politics.mideast',
 'talk.politics.misc',
 'talk.religion.misc']

实际数据位于filenamestarget属性中。“target”属性是类别的整数索引。

>>> newsgroups_train.filenames.shape
(11314,)
>>> newsgroups_train.target.shape
(11314,)
>>> newsgroups_train.target[:10]
array([ 7,  4,  4,  1, 14, 16, 13,  3,  2,  4])

可以通过将要加载的类别列表传递给sklearn.datasets.fetch_20newsgroups函数来仅加载类别的子集。

>>> cats = ['alt.atheism', 'sci.space']
>>> newsgroups_train = fetch_20newsgroups(subset='train', categories=cats)

>>> list(newsgroups_train.target_names)
['alt.atheism', 'sci.space']
>>> newsgroups_train.filenames.shape
(1073,)
>>> newsgroups_train.target.shape
(1073,)
>>> newsgroups_train.target[:10]
array([0, 1, 1, 1, 0, 1, 1, 0, 0, 0])
将文本转换为向量#

为了用文本数据来训练预测模型或聚类模型,首先需要将文本转换为适合统计分析的数值向量。这可以通过sklearn.feature_extraction.text中的实用程序来实现,如下面的示例所示,该示例从20news的子集中提取TF-IDF单字词向量。

>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> categories = ['alt.atheism', 'talk.religion.misc',
...               'comp.graphics', 'sci.space']
>>> newsgroups_train = fetch_20newsgroups(subset='train',
...                                       categories=categories)
>>> vectorizer = TfidfVectorizer()
>>> vectors = vectorizer.fit_transform(newsgroups_train.data)
>>> vectors.shape
(2034, 34118)

提取的TF-IDF向量非常稀疏,在超过30000维的空间中,每个样本平均有159个非零分量(少于0.5%的非零特征)。

>>> vectors.nnz / float(vectors.shape[0])
159.01327...

sklearn.datasets.fetch_20newsgroups_vectorized是一个函数,它返回可以直接使用的词频特征,而不是文件名。

过滤文本以进行更真实的训练#

分类器很容易过度拟合20个新闻组数据中出现的特定内容,例如新闻组标题。许多分类器都达到了非常高的F值,但它们的结果并不能推广到其他并非来自此时间窗口的文档。

例如,让我们看看多项式朴素贝叶斯分类器的结果,它训练速度快,并且可以达到不错的F值。

>>> from sklearn.naive_bayes import MultinomialNB
>>> from sklearn import metrics
>>> newsgroups_test = fetch_20newsgroups(subset='test',
...                                      categories=categories)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> clf = MultinomialNB(alpha=.01)
>>> clf.fit(vectors, newsgroups_train.target)
MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)

>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(newsgroups_test.target, pred, average='macro')
0.88213...

(示例使用稀疏特征进行文本文档分类对训练数据和测试数据进行随机排序,而不是按时间段分割,在这种情况下,多项式朴素贝叶斯分类器的F值要高得多,达到0.88。你是否怀疑这个分类器内部发生了什么?)

让我们看看哪些是最有信息的特征。

>>> import numpy as np
>>> def show_top10(classifier, vectorizer, categories):
...     feature_names = vectorizer.get_feature_names_out()
...     for i, category in enumerate(categories):
...         top10 = np.argsort(classifier.coef_[i])[-10:]
...         print("%s: %s" % (category, " ".join(feature_names[top10])))
...
>>> show_top10(clf, vectorizer, newsgroups_train.target_names)
alt.atheism: edu it and in you that is of to the
comp.graphics: edu in graphics it is for and of to the
sci.space: edu it that is in and space to of the
talk.religion.misc: not it you in is that and to of the

现在你可以看到这些特征过度拟合的许多方面。

  • 几乎每个组都通过NNTP-Posting-Host:Distribution:等标题出现频率的高低来区分。

  • 另一个重要的特征涉及发送者是否隶属于大学,这可以通过他们的标题或签名来指示。

  • “文章”一词是一个重要特征,基于人们引用先前帖子的频率,例如:“在文章 [文章 ID] 中,[姓名] <[电子邮件地址]> 写道:”

  • 其他特征匹配当时发帖的特定人员的姓名和电子邮件地址。

由于有如此丰富的线索来区分新闻组,分类器几乎不需要从文本中识别主题,并且它们都达到了相同的较高水平。

因此,加载 20 个新闻组数据的函数提供了一个名为 remove 的参数,告诉它要从每个文件中去除哪些信息。remove 应该是一个元组,包含 ('headers', 'footers', 'quotes') 的任何子集,分别告诉它删除页眉、签名块和引用块。

>>> newsgroups_test = fetch_20newsgroups(subset='test',
...                                      remove=('headers', 'footers', 'quotes'),
...                                      categories=categories)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(pred, newsgroups_test.target, average='macro')
0.77310...

这个分类器的 F 值下降了很多,仅仅是因为我们去除了与主题分类几乎无关的元数据。如果我们也从训练数据中去除这些元数据,损失会更大。

>>> newsgroups_train = fetch_20newsgroups(subset='train',
...                                       remove=('headers', 'footers', 'quotes'),
...                                       categories=categories)
>>> vectors = vectorizer.fit_transform(newsgroups_train.data)
>>> clf = MultinomialNB(alpha=.01)
>>> clf.fit(vectors, newsgroups_train.target)
MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)
>>> vectors_test = vectorizer.transform(newsgroups_test.data)
>>> pred = clf.predict(vectors_test)
>>> metrics.f1_score(newsgroups_test.target, pred, average='macro')
0.76995...

其他一些分类器能更好地应对这个更难的任务。尝试使用和不使用 remove 选项来比较 文本特征提取和评估示例 中的结果。

数据注意事项

克利夫兰印第安人队是一支位于美国俄亥俄州克利夫兰的美国职业棒球大联盟球队。2020 年 12 月,有报道称:“在乔治·弗洛伊德去世以及全国范围内对种族和殖民主义进行反思引发的数月讨论之后,克利夫兰印第安人队决定更改队名。”球队老板保罗·多兰“确实明确表示,球队不会将它的非正式昵称——部落——作为新的队名。”“这不会是与印第安人队名仅仅略有不同的改变,”多兰说。“我们不会采用以美洲原住民为主题的队名。”

https://www.mlb.com/news/cleveland-indians-team-name-change

建议

  • 在对 20 个新闻组数据上的文本分类器进行评估时,应去除与新闻组相关的元数据。在 scikit-learn 中,可以通过设置 remove=('headers', 'footers', 'quotes') 来实现。F 值会降低,因为这样更符合实际情况。

  • 此文本数据集包含可能不适用于某些 NLP 应用的数据。上面“数据注意事项”部分列举了一个示例。在 NLP 中使用当前文本数据集进行句子完成、聚类和其他应用的挑战在于,具有文化偏见和煽动性的文本会传播偏见。在使用数据集、审查输出时应考虑到这一点,并且应记录这种偏见。

示例

7.2.3. Labeled Faces in the Wild 人脸识别数据集#

此数据集是从互联网上收集的名人 JPEG 图片的集合,所有细节都可以在官方网站上找到。

http://vis-www.cs.umass.edu/lfw/

每张图片都以单个人脸为中心。典型的任务称为人脸验证:给定两张图片,二元分类器必须预测这两张图片是否来自同一个人。

另一种任务,人脸识别或人脸辨识是:给定一个未知人士人脸的照片,通过参考以前见过的已识别人士的照片库来识别该人士的姓名。

人脸验证和人脸识别通常是在经过训练以执行人脸检测的模型的输出上执行的任务。最流行的人脸检测模型称为 Viola-Jones,并在 OpenCV 库中实现。LFW 人脸是由这个从各种在线网站提取人脸的检测器提取的。

数据集特征

类别

5749

样本总数

13233

维数

5828

特征

真实值,介于 0 和 255 之间

用法#

scikit-learn 提供两个加载器,它们将自动下载、缓存、解析元数据文件,解码 jpeg 并将有趣的切片转换为内存映射的 numpy 数组。此数据集大小超过 200 MB。第一次加载通常需要超过几分钟才能将 JPEG 文件的相关部分完全解码为 numpy 数组。如果数据集已加载一次,则后续加载时间使用 joblib~/scikit_learn_data/lfw_home/ 文件夹中存储在磁盘上的内存映射版本,加载时间将少于 200 毫秒。

第一个加载器用于人脸识别任务:一个多类分类任务(因此是监督学习)

>>> from sklearn.datasets import fetch_lfw_people
>>> lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)

>>> for name in lfw_people.target_names:
...     print(name)
...
Ariel Sharon
Colin Powell
Donald Rumsfeld
George W Bush
Gerhard Schroeder
Hugo Chavez
Tony Blair

默认切片是围绕人脸的矩形形状,去除了大部分背景

>>> lfw_people.data.dtype
dtype('float32')

>>> lfw_people.data.shape
(1288, 1850)

>>> lfw_people.images.shape
(1288, 50, 37)

1140 张人脸中的每一张都在 target 数组中分配给单个人员 ID

>>> lfw_people.target.shape
(1288,)

>>> list(lfw_people.target[:10])
[5, 6, 3, 1, 0, 1, 3, 4, 3, 0]

第二个加载器通常用于人脸验证任务:每个样本都是属于或不属于同一个人的一对图片

>>> from sklearn.datasets import fetch_lfw_pairs
>>> lfw_pairs_train = fetch_lfw_pairs(subset='train')

>>> list(lfw_pairs_train.target_names)
['Different persons', 'Same person']

>>> lfw_pairs_train.pairs.shape
(2200, 2, 62, 47)

>>> lfw_pairs_train.data.shape
(2200, 5828)

>>> lfw_pairs_train.target.shape
(2200,)

对于 sklearn.datasets.fetch_lfw_peoplesklearn.datasets.fetch_lfw_pairs 函数,都可以通过传递 color=True 来获得具有 RGB 颜色通道的附加维度,在这种情况下,形状将为 (2200, 2, 62, 47, 3)

sklearn.datasets.fetch_lfw_pairs 数据集细分为 3 个子集:开发 train 集、开发 test 集和一个评估 10_folds 集,用于使用 10 折交叉验证方案计算性能指标。

参考文献

示例

7.2.4. 森林覆盖类型#

此数据集中的样本对应于美国 30×30 米的森林斑块,收集用于预测每个斑块的覆盖类型,即主要的树种。共有七种覆盖类型,这使得这是一个多类分类问题。每个样本都有 54 个特征,在 数据集的主页 上进行了描述。一些特征是布尔指示器,而其他特征是离散或连续的测量值。

数据集特征

类别

7

样本总数

581012

维数

54

特征

整数

sklearn.datasets.fetch_covtype 将加载覆盖类型数据集;它返回一个类似字典的“Bunch”对象,其中特征矩阵位于 data 成员中,目标值位于 target 中。如果可选参数 'as_frame' 设置为 'True',它将返回 datatarget 作为 pandas 数据框,并且还将有一个额外的成员 frame。如有必要,数据集将从网上下载。

7.2.5. RCV1 数据集#

路透社语料库第一卷 (RCV1) 是路透有限公司为研究目的提供的包含 80 多万条人工分类新闻报道的档案。该数据集在 [1] 中进行了详细描述。

数据集特征

类别

103

样本总数

804414

维数

47236

特征

实数,介于 0 和 1 之间

sklearn.datasets.fetch_rcv1 将加载以下版本:RCV1-v2,向量,完整集合,主题多标签

>>> from sklearn.datasets import fetch_rcv1
>>> rcv1 = fetch_rcv1()

它返回一个类似字典的对象,具有以下属性:

data:特征矩阵是一个 scipy CSR 稀疏矩阵,包含 804414 个样本和 47236 个特征。非零值包含余弦归一化的对数 TF-IDF 向量。[1] 中提出了一种近乎按时间顺序的划分:前 23149 个样本是训练集。最后 781265 个样本是测试集。这遵循官方 LYRL2004 时间顺序划分。该数组的非零值比例为 0.16%。

>>> rcv1.data.shape
(804414, 47236)

target:目标值存储在一个 scipy CSR 稀疏矩阵中,包含 804414 个样本和 103 个类别。每个样本在其类别中值为 1,在其他类别中值为 0。该数组的非零值比例为 3.15%。

>>> rcv1.target.shape
(804414, 103)

sample_id:每个样本都可以通过其 ID 标识,范围(带有间隙)从 2286 到 810596。

>>> rcv1.sample_id[:3]
array([2286, 2287, 2288], dtype=uint32)

target_names:目标值是每个样本的主题。每个样本至少属于一个主题,最多属于 17 个主题。共有 103 个主题,每个主题都用字符串表示。它们的语料库频率跨越五个数量级,从 'GMIL' 的 5 次出现到 'CCAT' 的 381327 次出现。

>>> rcv1.target_names[:3].tolist()  
['E11', 'ECAT', 'M11']

如有必要,数据集将从 rcv1 主页 下载。压缩大小约为 656 MB。

参考文献

7.2.6. Kddcup 99 数据集#

KDD Cup '99 数据集是通过处理 1998 年 DARPA 入侵检测系统 (IDS) 评估数据集的 tcpdump 部分创建的,该数据集由麻省理工学院林肯实验室创建 [2]。人工数据(在 数据集的主页 上描述)是使用封闭网络和手动注入的攻击生成的,以产生大量不同类型的攻击以及背景中的正常活动。由于最初的目标是为监督学习算法生成大型训练集,因此异常数据的比例很大(80.1%),这在现实世界中是不现实的,并且不适用于旨在检测“异常”数据的无监督异常检测,即:

  • 在质量上与正常数据不同

  • 在观测结果中占少数。

因此,我们将 KDD 数据集转换为两个不同的数据集:SA 和 SF。

  • SA 是通过简单地选择所有正常数据和一小部分异常数据获得的,异常比例为 1%。

  • SF 是如 [3] 中所述获得的,方法是简单地选择属性 logged_in 为正的数据,从而专注于入侵攻击,攻击比例为 0.3%。

  • http 和 smtp 是 SF 的两个子集,分别对应于第三个特征等于 'http'(或 'smtp')。

通用 KDD 结构

样本总数

4898431

维数

41

特征

离散(整数)或连续(浮点数)

目标

字符串,'normal.' 或异常类型的名称

SA 结构

样本总数

976158

维数

41

特征

离散(整数)或连续(浮点数)

目标

字符串,'normal.' 或异常类型的名称

SF 结构

样本总数

699691

维数

4

特征

离散(整数)或连续(浮点数)

目标

字符串,'normal.' 或异常类型的名称

http 结构

样本总数

619052

维数

3

特征

离散(整数)或连续(浮点数)

目标

字符串,'normal.' 或异常类型的名称

smtp 结构

样本总数

95373

维数

3

特征

离散(整数)或连续(浮点数)

目标

字符串,'normal.' 或异常类型的名称

sklearn.datasets.fetch_kddcup99 将加载 kddcup99 数据集;它返回一个类似字典的对象,其中特征矩阵位于 data 成员中,目标值位于 target 中。“as_frame”可选参数将 data 转换为 pandas DataFrame,并将 target 转换为 pandas Series。如有必要,数据集将从网上下载。

参考文献

7.2.7. 加利福尼亚住房数据集#

数据集特征

实例数量:

20640

属性数量:

8 个数值型预测属性和目标变量

属性信息:
  • MedInc 街区组中位收入

  • HouseAge 街区组中位房屋年龄

  • AveRooms 平均每户房间数

  • AveBedrms 平均每户卧室数

  • Population 街区组人口

  • AveOccup 平均每户家庭成员数

  • Latitude 街区组纬度

  • Longitude 街区组经度

缺失属性值:

此数据集来自 StatLib 存储库。https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html

目标变量是加利福尼亚州地区的房屋中位数价值,以十万美元计(100,000 美元)。

此数据集来自 1990 年美国人口普查,每个普查街区组使用一行数据。街区组是美国人口普查局发布样本数据的最小地理单元(一个街区组的人口通常在 600 到 3000 人之间)。

家庭是指居住在一所房子里的一群人。由于此数据集中提供了每个家庭的平均房间数和卧室数,因此对于家庭数量少而空置房屋数量多的街区组(例如度假胜地),这些列的值可能会出乎意料地大。

可以使用 sklearn.datasets.fetch_california_housing 函数下载/加载。

参考文献

  • Pace, R. Kelley 和 Ronald Barry,《稀疏空间自回归》,《统计与概率快报》,33 (1997) 291-297

7.2.8. 物种分布数据集#

此数据集表示中美洲和南美洲两种物种的地理分布。这两种物种是

此数据集并非典型数据集,因为它不返回包含属性datatargetBunch。相反,我们拥有允许创建不同物种“密度”地图的信息。

可以使用属性x_left_lower_cornery_left_lower_cornerNxNygrid_size构建地图网格,它们分别对应于网格左下角的x和y坐标、沿x轴和y轴的点数以及网格上步长的尺寸。

网格中每个位置的密度包含在coverage属性中。

最后,traintest属性包含有关物种在特定位置的信息。

此数据集由Phillips等人提供 (2006)。

参考文献

示例