机器学习数据集的获取和测试集的构建方法
机器学习入门系列(2)--如何构建一个完整的机器学习项目的第二篇文章
上一篇机器学习入门系列(2)--如何构建一个完整的机器学习项目(一)介绍了开始一个机器学习项目需要明确的问题,比如当前任务属于有监督还是无监督学习问题,然后性能指标需要选择什么,常用的分类和回归损失函数有哪些,以及实际开发中需要明确系统的输入输出接口问题。
第二篇,会介绍下如何获取数据集和构建测试集的方法。前者,对于机器学习来说,数据集的好坏对模型性能有很大的影响。而后者,主要是避免两个偏差--数据透视偏差和采样偏差。
2. 获取数据
2.1 常用数据集
在我们学习机器学习的时候,最好使用真实数据,即符合真实场景的数据集,而不是人工数据集,采用这种人工数据集在实际应用中会让系统表现很糟糕,因为人工数据集一般都和真实场景下的数据有较大的差异。幸运的是,现在有非常多的开源数据集,并且涵盖了多个领域,这里介绍几个常用的可以查找数据集的网站以及一些在计算机视觉常用的图像数据集:
- Kaggle 数据集:每个数据集都是一个小型社区,用户可以在其中讨论数据、查找公共代码或在内核中创建自己的项目。包含各式各样的真实数据集。
- Amazon 数据集:该数据源包含多个不同领域的数据集,如:公共交通、生态资源、卫星图像等。网页中也有一个搜索框来帮助用户寻找想要的数据集,还有所有数据集的描述和使用示例,这些数据集信息丰富且易于使用!
- UCI机器学习资源库:来自加州大学信息与计算机科学学院的大型资源库,包含100多个数据集。用户可以找到单变量和多变量时间序列数据集,分类、回归或推荐系统的数据集。
- 谷歌数据集搜索引擎:这是一个可以按名称搜索数据集的工具箱。
- 微软数据集:2018年7月,微软与外部研究社区共同宣布推出“Microsoft Research Open Data”。它在云中包含一个数据存储库,用于促进全球研究社区之间的协作。它提供了一系列用于已发表研究的、经过处理的数据集。
- Awesome Public Datasets Collection:Github 上的一个按“主题”组织的数据集,比如生物学、经济学、教育学等。大多数数据集都是免费的,但是在使用任何数据集之前,用户需要检查一下许可要求。
- 计算机视觉数据集:Visual Data包含一些可以用来构建计算机视觉(CV)模型的大型数据集。用户可以通过特定的CV主题查找特定的数据集,如语义分割、图像标题、图像生成,甚至可以通过解决方案(自动驾驶汽车数据集)查找特定的数据集。
常用的部分图像数据集:
- Mnist: 手写数字数据集,包含 60000 张训练集和 10000 张测试集。(但该数据集通常只是作为简单 demo 使用,如果要验证算法模型的性能,最好在更大数据集上进行测试,实验结果才有足够的可信度)
- Cifar:分为 Cifar10 和 Cifar100。前者包含 60000 张图片,总共10个类别,每类 6000 张图片。后者是 100 个类别,每个类别 600 张图片。类别包括猫狗鸟等动物、飞机汽车船等交通工具。
- ImageNet:应该是目前最大的开源图像数据集,包含 1500 万张图片,2.2 万个类别。
- LFW:人脸数据集,包含13000+张图片和1680个不同的人。
- CelebA:人脸数据集,包含大约 20w 张图片,总共 10177个不同的人,以及每张图片都有 5 个位置标注点,40 个属性信息
2.2 准备开发环境
在找到数据集,并下载后,我们就需要开始准备开发环境,也就是需要采用的编程语言和相应的框架。
现在机器学习,一般都是采用 Python 语言,因为它简单易学,对程序员非常友好,而且也有相应很多应用于机器学习和深度学习方面的框架,比如 scikit-learn
,opencv
,深度学习方面的TensorFlow, Pytorch, Keras
等。
而为了方便可视化数据,查看代码运行效果,通常会选择采用 Jupyter
这个模块。其他必要的 Python 模块有:
- Numpy:一个运行速度非常快的数学库,主要用于数组计算,支持大量的维度数据和矩阵运算
- Pandas:快速处理数据和分析数据
- Matplotlib: 绘图,可视化数据
此外,python 比较不友好的问题就是 2.7 版本和 3.+ 版本的不兼容问题,所以我们需要有一个包管理工具,可以单独配置不同的开发环境,这里推荐使用的是 Anaconda
。
这些模块的安装,网上都有非常多详细的教程,这里就不花时间介绍了。
2.3 创建测试集
在下载数据后,首先要做的是创建测试集,这是在分析数据前先排除测试集的数据,不会引入测试数据的规律,从而影响算法的选择,保证采用测试集进行测试的结果是客观可信的,而不会出现数据透视偏差的问题。
数据透视偏差:即由于选择模型时候参考了测试集的规律,导致在测试集上准确率很好,但实际应用的时候,系统表现很糟糕的情况。
一般我们会按照 8:2 的比例划分训练集和测试集,可以采用如下代码,随机划分出测试集:
import numpy as np
def split_train_test(data, test_ratio):
shuffled_indices = np.random.permutation(len(data))
test_set_size = int(len(data) * test_ratio)
test_indices = shuffled_indices[:test_set_size]
train_indices = shuffled_indices[test_set_size:]
return data.iloc[train_indices], data.iloc[test_indices]
train_set, test_set = split_train_test(housing, 0.2)
当然,这个方法存在一个缺陷:每次运行会得到不同的测试集!
解决的办法有以下几种:
- 第一次运行该函数后就保存测试集,随后载入测试集;
- 调用函数
np.random.permutation()
前,设置随机数生成器的种子,比如np.random.seed(42)
,以产生相同的洗牌指数(shuffled indices). - 上述两个方法对于数据集不变的情况是有效的,但更新数据集后,都会失效。第三个解决方法就是根据每个实例的
ID
来判断其是否应该放入测试集,比如,对于图片数据集,就可以根据图片的名字(保证更新训练集不会更新图片名字)来确定其属于训练集还是测试集。
划分数据集也可以采用Scikit-Learn
库的一些函数,最简单也是最常用的就是 train_test_split
函数,它和上述split_train_test
函数作用相似,但增加了更多的功能:
-
random_state
参数可以实现设置随机生成器种子的作用; - 可以将种子传递给多个行数相同的数据集,可以在相同的索引上分割数据集。
简单使用例子如下:
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)
这里需要注意的是,我们采用的都是随机采样方法,对于大数据集,这方法通常可行。
但对于不大的数据集,这会出现采样偏差的风险。简单说,就是样本代表性不够,可能随机选择的都是同种类型的数据。
比如,当一个调查公司想要对 1000 个人进行调查,需要保证这 1000 个人对人群整体有代表性,例如,美国人口有 51.3% 是女性,48.7% 是男性。那么,在美国做这个调查,就需要保证样本也是这个比例,即选择 513 名女性,487 名男性。
这种采样称为分层采样:将人群分层均匀的子分组,称为分层,从每个分层去取合适数量的实例,以保证测试集对总人数有代表性。
所以上述调查公司的例子,就是先将人群按照性别划分两个子分组,然后分别再按照如年龄、职业等标准继续划分子分组。
分层采样的操作可以使用Scikit-Learn
的StratifiedShuffleSplit
函数,指定数据中指定的类别,代码例子如下:
from sklearn.model_selection import StratifiedShuffleSplit
split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(housing, housing["income_cat"]):
strat_train_set = housing.loc[train_index]
strat_test_set = housing.loc[test_index]
这里是给定一个房子信息数据housing
,然后指定收入分类housing["income_cat"]
,保证采样的数据集中包含根据收入分类的比例。
小结
第二篇,先介绍了几个寻找数据集的网站,和计算机视觉常用的图像数据集,然后介绍如何划分测试集,避免数据透视偏差和采样偏差的问题。
点击原文,可以查看数据集的链接。
参考:
- 《hands-on-ml-with-sklearn-and-tf》第二节
- https://towardsdatascience.com/top-sources-for-machine-learning-datasets-bb6d0dc3378b
欢迎关注我的微信公众号--机器学习与计算机视觉,或者扫描下方的二维码,大家一起交流,学习和进步!
image