这是机器学习入门系列(2)–如何构建一个完整的机器学习项目的第二篇
上一篇机器学习入门系列(2)–如何构建一个完整的机器学习项目(一)介绍了开始一个机器学习项目需要明确的问题,比如当前任务属于有监督还是无监督学习问题,然后性能指标需要选择什么,常用的分类和回归损失函数有哪些,以及实际开发中需要明确系统的输入输出接口问题。
第二篇,会介绍下如何获取数据集和构建测试集的方法。前者,对于机器学习来说,数据集的好坏对模型性能有很大的影响。而后者,主要是避免两个偏差–数据透视偏差和采样偏差。
在我们学习机器学习的时候,最好使用真实数据,即符合真实场景的数据集,而不是人工数据集,采用这种人工数据集在实际应用中会让系统表现很糟糕,因为人工数据集一般都和真实场景下的数据有较大的差异。幸运的是,现在有非常多的开源数据集,并且涵盖了多个领域,这里介绍几个常用的可以查找数据集的网站以及一些在计算机视觉常用的图像数据集:
常用的部分图像数据集:
在找到数据集,并下载后,我们就需要开始准备开发环境,也就是需要采用的编程语言和相应的框架。
现在机器学习,一般都是采用 Python 语言,因为它简单易学,对程序员非常友好,而且也有相应很多应用于机器学习和深度学习方面的框架,比如 scikit-learn
,opencv
,深度学习方面的TensorFlow, Pytorch, Keras
等。
而为了方便可视化数据,查看代码运行效果,通常会选择采用 Jupyter
这个模块。其他必要的 Python 模块有:
此外,python 比较不友好的问题就是 2.7 版本和 3.+ 版本的不兼容问题,所以我们需要有一个包管理工具,可以单独配置不同的开发环境,这里推荐使用的是 Anaconda
。
这些模块的安装,网上都有非常多详细的教程,这里就不花时间介绍了。
在下载数据后,首先要做的是创建测试集,这是在分析数据前先排除测试集的数据,不会引入测试数据的规律,从而影响算法的选择,保证采用测试集进行测试的结果是客观可信的,而不会出现数据透视偏差的问题。
数据透视偏差:即由于选择模型时候参考了测试集的规律,导致在测试集上准确率很好,但实际应用的时候,系统表现很糟糕的情况。
一般我们会按照 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"]
,保证采样的数据集中包含根据收入分类的比例。
第二篇,先介绍了几个寻找数据集的网站,和计算机视觉常用的图像数据集,然后介绍如何划分测试集,避免数据透视偏差和采样偏差的问题。
参考:
欢迎关注我的微信公众号–机器学习与计算机视觉,或者扫描下方的二维码,大家一起交流,学习和进步!