与其他编程练习相比,机器学习项目是代码和数据的混合体。你需要两者才能获得结果并做有用的事情。多年来,许多知名的公共数据集被创建,其中许多已成为标准或基准。在本教程中,我们将了解如何轻松获取这些知名的公共数据集。我们还将学习如何在现有数据集不满足我们的需求时制作一个合成数据集。
完成本教程后,您将了解
- 在哪里可以找到免费的机器学习项目数据集
- 如何使用 Python 中的库下载数据集
- 如何使用 scikit-learn 生成合成数据集
通过我的新书 Python for Machine Learning 启动您的项目,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。
Python机器学习数据集获取指南
照片由 Olha Ruskykh 拍摄。部分权利保留。
教程概述
本教程分为四个部分;它们是
- 数据集存储库
- 在 scikit-learn 和 Seaborn 中检索数据集
- 在 TensorFlow 中检索数据集
- 在 scikit-learn 中生成数据集
数据集存储库
机器学习已经发展了几十年,因此有一些具有历史意义的数据集。这些数据集中最知名的存储库之一是 UCI 机器学习存储库。那里的大多数数据集都很小,因为当时的技术不足以处理更大的数据。该存储库中的一些著名数据集是鸢尾花数据集(由 Ronald Fisher 于 1936 年推出)和 20 个新闻组数据集(文本数据,通常在信息检索文献中引用)。
较新的数据集通常体积更大。例如,ImageNet 数据集超过 160 GB。这些数据集通常在 Kaggle 中找到,我们可以按名称搜索它们。如果我们需要下载它们,建议在注册帐户后使用 Kaggle 的命令行工具。
OpenML 是一个较新的存储库,托管了大量数据集。它很方便,因为您可以按名称搜索数据集,而且它还提供了一个标准化的 Web API 供用户检索数据。如果您想使用 Weka,它提供 ARFF 格式的文件,这将非常有用。
但仍然有许多数据集是公开可用的,但由于各种原因并未包含在这些存储库中。您还可以查看 Wikipedia 上的“机器学习研究数据集列表”。该页面包含按不同类别分类的数据集列表,并附有下载链接。
在 scikit-learn 和 Seaborn 中检索数据集
很自然地,您可以通过从网上下载数据集来获取这些数据集,无论是通过浏览器、命令行,使用 wget
工具,还是使用 Python 中的 requests
等网络库。由于其中一些数据集已成为标准或基准,因此许多机器学习库都创建了函数来帮助检索它们。出于实际原因,数据集通常不会随库一起提供,而是在您调用函数时实时下载。因此,您需要稳定的互联网连接才能使用它们。
Scikit-learn 就是一个例子,您可以使用其 API 下载数据集。相关函数定义在 sklearn.datasets
下,您可以在以下位置查看函数列表:
例如,您可以使用 load_iris()
函数获取鸢尾花数据集,如下所示:
1 2 3 4 5 |
import sklearn.datasets data, target = sklearn.datasets.load_iris(return_X_y=True, as_frame=True) data["target"] = target print(data) |
除非指定了参数 as_frame=True
,否则 load_iris()
函数将返回 numpy 数组(即没有列标题),而不是 pandas DataFrame。此外,我们将 return_X_y=True
传递给函数,因此只返回机器学习特征和目标,而不是元数据,例如数据集的描述。上面的代码打印如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
萼片长度 (cm) 萼片宽度 (cm) 花瓣长度 (cm) 花瓣宽度 (cm) 目标 0 5.1 3.5 1.4 0.2 0 1 4.9 3.0 1.4 0.2 0 2 4.7 3.2 1.3 0.2 0 3 4.6 3.1 1.5 0.2 0 4 5.0 3.6 1.4 0.2 0 .. ... ... ... ... ... 145 6.7 3.0 5.2 2.3 2 146 6.3 2.5 5.0 1.9 2 147 6.5 3.0 5.2 2.0 2 148 6.2 3.4 5.4 2.3 2 149 5.9 3.0 5.1 1.8 2 [150 行 x 5 列] |
将特征和目标分开对于训练 scikit-learn 模型很方便,但将它们结合起来进行可视化会很有帮助。例如,我们可以组合上面的 DataFrame,然后使用 Seaborn 可视化相关图
1 2 3 4 5 6 7 8 9 10 |
import sklearn.datasets import matplotlib.pyplot as plt import seaborn as sns data, target = sklearn.datasets.load_iris(return_X_y=True, as_frame=True) data["target"] = target sns.pairplot(data, kind="scatter", diag_kind="kde", hue="target", palette="muted", plot_kws={'alpha':0.7}) plt.show() |
从相关图可以看出,目标 0 很容易区分,但目标 1 和 2 通常有一些重叠。由于此数据集也可用于演示绘图功能,我们可以从 Seaborn 找到相应的数据加载函数。我们可以将上面的代码重写为以下内容:
1 2 3 4 5 6 7 |
import matplotlib.pyplot as plt import seaborn as sns data = sns.load_dataset("iris") sns.pairplot(data, kind="scatter", diag_kind="kde", hue="species", palette="muted", plot_kws={'alpha':0.7}) plt.show() |
Seaborn 支持的数据集更为有限。我们可以通过运行以下命令查看所有受支持数据集的名称:
1 2 |
import seaborn as sns print(sns.get_dataset_names()) |
以下是 Seaborn 的所有数据集:
1 2 3 |
['anagrams', 'anscombe', 'attention', 'brain_networks', 'car_crashes', 'diamonds', 'dots', 'exercise', 'flights', 'fmri', 'gammas', 'geyser', 'iris', 'mpg', 'penguins', 'planets', 'taxis', 'tips', 'titanic'] |
scikit-learn 中有许多类似的函数可以加载“玩具数据集”。例如,我们有以类似方式定义的 load_wine()
和 load_diabetes()
。
更大的数据集也类似。例如,我们有 fetch_california_housing()
,它需要从互联网下载数据集(因此函数名称中带有“fetch”)。Scikit-learn 文档称这些为“真实世界数据集”,但实际上,玩具数据集同样是真实的。
1 2 3 4 5 |
import sklearn.datasets data = sklearn.datasets.fetch_california_housing(return_X_y=False, as_frame=True) data = data["frame"] print(data) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude Longitude MedHouseVal 0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 -122.23 4.526 1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 -122.22 3.585 2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 -122.24 3.521 3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 -122.25 3.413 4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 -122.25 3.422 ... ... ... ... ... ... ... ... ... ... 20635 1.5603 25.0 5.045455 1.133333 845.0 2.560606 39.48 -121.09 0.781 20636 2.5568 18.0 6.114035 1.315789 356.0 3.122807 39.49 -121.21 0.771 20637 1.7000 17.0 5.205543 1.120092 1007.0 2.325635 39.43 -121.22 0.923 20638 1.8672 18.0 5.329513 1.171920 741.0 2.123209 39.43 -121.32 0.847 20639 2.3886 16.0 5.254717 1.162264 1387.0 2.616981 39.37 -121.24 0.894 [20640 行 x 9 列] |
如果我们还需要更多,scikit-learn 提供了一个方便的函数来读取 OpenML 中的任何数据集。例如:
1 2 3 4 5 |
import sklearn.datasets data = sklearn.datasets.fetch_openml("diabetes", version=1, as_frame=True, return_X_y=False) data = data["frame"] print(data) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
preg plas pres skin insu mass pedi age class 0 6.0 148.0 72.0 35.0 0.0 33.6 0.627 50.0 tested_positive 1 1.0 85.0 66.0 29.0 0.0 26.6 0.351 31.0 tested_negative 2 8.0 183.0 64.0 0.0 0.0 23.3 0.672 32.0 tested_positive 3 1.0 89.0 66.0 23.0 94.0 28.1 0.167 21.0 tested_negative 4 0.0 137.0 40.0 35.0 168.0 43.1 2.288 33.0 tested_positive .. ... ... ... ... ... ... ... ... ... 763 10.0 101.0 76.0 48.0 180.0 32.9 0.171 63.0 tested_negative 764 2.0 122.0 70.0 27.0 0.0 36.8 0.340 27.0 tested_negative 765 5.0 121.0 72.0 23.0 112.0 26.2 0.245 30.0 tested_negative 766 1.0 126.0 60.0 0.0 0.0 30.1 0.349 47.0 tested_positive 767 1.0 93.0 70.0 31.0 0.0 30.4 0.315 23.0 tested_negative [768 行 x 9 列] |
有时,我们不应使用名称来识别 OpenML 中的数据集,因为可能有多个同名数据集。我们可以按如下方式在 OpenML 上搜索数据 ID 并在函数中使用它:
1 2 3 4 5 |
import sklearn.datasets data = sklearn.datasets.fetch_openml(data_id=42437, return_X_y=False, as_frame=True) data = data["frame"] print(data) |
上面的代码中的数据 ID 指的是泰坦尼克号数据集。我们可以将代码扩展为以下内容,以展示如何获取泰坦尼克号数据集然后运行逻辑回归:
1 2 3 4 5 6 7 |
from sklearn.linear_model import LogisticRegression 从 sklearn.datasets 导入 fetch_openml X, y = fetch_openml(data_id=42437, return_X_y=True, as_frame=False) clf = LogisticRegression(random_state=0).fit(X, y) print(clf.score(X,y)) # 准确率 print(clf.coef_) # 逻辑回归中的系数 |
1 2 3 |
0.8114478114478114 [[-0.7551392 2.24013347 -0.20761281 0.28073571 0.24416706 -0.36699113 0.4782924 ]] |
想开始学习机器学习 Python 吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
在 TensorFlow 中检索数据集
除了 scikit-learn,TensorFlow 也是我们可以用于机器学习项目的工具。出于类似的原因,TensorFlow 也有一个数据集 API,可以为您提供最适合 TensorFlow 的格式的数据集。与 scikit-learn 不同,该 API 不是标准 TensorFlow 包的一部分。您需要使用以下命令进行安装:
1 |
pip install tensorflow-datasets |
所有数据集的列表可在目录中找到:
所有数据集都由名称标识。名称可以在上面的目录中找到。您也可以使用以下方法获取名称列表:
1 2 |
import tensorflow_datasets as tfds print(tfds.list_builders()) |
这会打印出超过 1000 个名称。
例如,让我们以 MNIST 手写数字数据集为例。我们可以如下下载数据:
1 2 3 |
import tensorflow_datasets as tfds ds = tfds.load("mnist", split="train", shuffle_files=True) print(ds) |
这向我们展示了 tfds.load()
返回一个 tensorflow.data.OptionsDataset
类型的对象
1 |
<_OptionsDataset shapes: {image: (28, 28, 1), label: ()}, types: {image: tf.uint8, label: tf.int64}> |
特别是,此数据集的数据实例(图像)是形状为 (28,28,1) 的 numpy 数组,目标(标签)是标量。
经过少量调整,数据就可以在 Keras 的 fit()
函数中使用。示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import tensorflow as tf import tensorflow_datasets as tfds from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, Dense, AveragePooling2D, Dropout, Flatten from tensorflow.keras.callbacks import EarlyStopping # 读取带训练-测试分割的数据 ds_train, ds_test = tfds.load("mnist", split=['train', 'test'], shuffle_files=True, as_supervised=True) # 从 OptionsDataset 对象设置 BatchDataset ds_train = ds_train.batch(32) ds_test = ds_test.batch(32) # 构建 LeNet5 模型并训练 model = Sequential([ Conv2D(6, (5,5), input_shape=(28,28,1), padding="same", activation="tanh"), AveragePooling2D((2,2), strides=2), Conv2D(16, (5,5), activation="tanh"), AveragePooling2D((2,2), strides=2), Conv2D(120, (5,5), activation="tanh"), Flatten(), Dense(84, activation="tanh"), Dense(10, activation="softmax") ]) model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["sparse_categorical_accuracy"]) earlystopping = EarlyStopping(monitor="val_loss", patience=2, restore_best_weights=True) model.fit(ds_train, validation_data=ds_test, epochs=100, callbacks=[earlystopping]) |
如果我们提供了 as_supervised=True
,数据集将是元组 (features, targets) 的记录,而不是字典。这对于 Keras 是必需的。此外,要将数据集用于 fit()
函数,我们需要创建一个批次的迭代器。这可以通过设置数据集的批次大小来完成,将其从 OptionsDataset
对象转换为 BatchDataset
对象。
我们应用了 LeNet5 模型进行图像分类。但由于数据集中目标是数值(0 到 9),而不是布尔向量,因此我们在 compile()
函数中指定 sparse_categorical_accuracy
和 sparse_categorical_crossentropy
,让 Keras 在计算准确率和损失之前将 softmax 输出向量转换为数字。
这里的关键是理解每个数据集的形状都不同。当您将其与 TensorFlow 模型一起使用时,需要调整模型以适应数据集。
在 scikit-learn 中生成数据集
在 scikit-learn 中,有一组非常有用的函数可以生成具有特定属性的数据集。由于我们可以控制合成数据集的属性,因此有助于在其他数据集中不常见的情况下评估模型的性能。
Scikit-learn 文档称这些函数为样本生成器。它易于使用;例如:
1 2 3 4 5 6 7 |
from sklearn.datasets import make_circles import matplotlib.pyplot as plt data, target = make_circles(n_samples=500, shuffle=True, factor=0.7, noise=0.1) plt.figure(figsize=(6,6)) plt.scatter(data[:,0], data[:,1], c=target, alpha=0.8, cmap="Set1") plt.show() |
make_circles()
函数生成一个二维平面上的散点坐标,使得有两个类呈同心圆形式排列。我们可以通过参数 factor
和 noise
来控制圆的大小和重叠程度。这个合成数据集有助于评估支持向量机等分类模型,因为没有线性分隔器可用。
make_circles()
的输出始终是两个类别,坐标也始终是二维的。但其他一些函数可以生成更多类别或更高维度的点,例如 make_blob()
。在下面的示例中,我们生成了一个 3D 数据集,包含 4 个类别:
1 2 3 4 5 6 7 8 9 10 |
from sklearn.datasets import make_blobs import matplotlib.pyplot as plt data, target = make_blobs(n_samples=500, n_features=3, centers=4, shuffle=True, random_state=42, cluster_std=2.5) fig = plt.figure(figsize=(8,8)) ax = fig.add_subplot(projection='3d') ax.scatter(data[:,0], data[:,1], data[:,2], c=target, alpha=0.7, cmap="Set1") plt.show() |
还有一些函数可以为回归问题生成数据集。例如,make_s_curve()
和 make_swiss_roll()
将生成 3D 坐标,目标为连续值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from sklearn.datasets import make_s_curve, make_swiss_roll import matplotlib.pyplot as plt data, target = make_s_curve(n_samples=5000, random_state=42) fig = plt.figure(figsize=(15,8)) ax = fig.add_subplot(121, projection='3d') ax.scatter(data[:,0], data[:,1], data[:,2], c=target, alpha=0.7, cmap="viridis") data, target = make_swiss_roll(n_samples=5000, random_state=42) ax = fig.add_subplot(122, projection='3d') ax.scatter(data[:,0], data[:,1], data[:,2], c=target, alpha=0.7, cmap="viridis") plt.show() |
如果我们不想从几何角度看待数据,还有make_classification()
和make_regression()
。与其它函数相比,这两个函数为我们提供了更多对特征集的控制,例如引入一些冗余或无关的特征。
下面是使用make_regression()
生成数据集并在此数据集上运行线性回归的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from sklearn.datasets import make_regression 来自 sklearn.linear_model 导入 LinearRegression import numpy as np # 生成10维特征和1维目标 X, y = make_regression(n_samples=500, n_features=10, n_targets=1, n_informative=4, noise=0.5, bias=-2.5, random_state=42) # 在数据上运行线性回归 reg = LinearRegression() reg.fit(X, y) # 打印找到的系数和截距 with np.printoptions(precision=5, linewidth=100, suppress=True): print(np.array(reg.coef_)) print(reg.intercept_) |
在上面的示例中,我们创建了10维特征,但只有4个是有信息的。因此,从回归结果来看,我们发现只有4个系数显著非零。
1 2 |
[-0.00435 -0.02232 19.0113 0.04391 46.04906 -0.02882 -0.05692 28.61786 -0.01839 16.79397] -2.5106367126731413 |
类似地,使用make_classification()
的示例如下。在本例中使用了支持向量机分类器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from sklearn.datasets import make_classification from sklearn.svm import SVC import numpy as np # 生成10维特征和3类目标 X, y = make_classification(n_samples=1000, n_features=10, n_classes=3, n_informative=4, n_redundant=2, n_repeated=1, random_state=42) # 在数据上运行SVC clf = SVC(kernel="rbf") clf.fit(X, y) # 打印准确率 print(clf.score(X, y)) |
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
存储库
- UCI机器学习存储库
- Kaggle
- OpenML
- 维基百科,https://en.wikipedia.org/wiki/List_of_datasets_for_machine-learning_research
文章
- 机器学习研究数据集列表,维基百科
- scikit-learn示例数据集
- scikit-learn真实世界数据集
- TensorFlow数据集目录
- 使用TensorFlow Datasets上的Keras在MNIST上训练神经网络
API
总结
在本教程中,您将探索在Python中加载常用数据集或生成数据集的各种选项。
具体来说,你学到了:
- 如何使用scikit-learn、Seaborn和TensorFlow中的数据集API加载常见的机器学习数据集
- 不同API返回的数据集格式之间的小差异以及如何使用它们
- 如何使用scikit-learn生成数据集
这是IT领域一个经典问题,无论是训练人工智能还是构建SAAS平台;获取上线数据。我很欣赏本文的技术指导,因为在当今互联网的广阔天地中,我很少看到这样的内容。
Bret,反馈很棒!
获取数据集对我来说并不容易。但在这里我发现了一些算法,这让我想要尝试和学习。谢谢如此好的文章!
这是我的一些作品:https://www.annotationsupport.com/services.php