完整走完一个机器学习项目(end-to-end machine learning project)上

Hands on Machine Learning with Scikit-learn and TensorFlow 读书笔记

Chapter 2 End-to-End Machine Learning Project

在这一章,你将会走完一个完整的机器学习项目。主要步骤如下:

  1. 对所需解决的问题有一个总体的思路
  2. 获取数据
  3. 通过数据可视化来得到对数据潜在规律的一些思考
  4. 在训练模型之前先对数据进行预处理
  5. 选择一个合适的模型进行训练
  6. 调整并找到最合适的模型参数
  7. 长期监督并维护你的学习系统

接下来我们将详细的走完这一整个项目:

  1. 对所需解决的问题有一个总体的思路:
    本章节给的任务是一个房价预测问题,训练数据中包含了每个区的人口、中值收入以及该区的中值房价等。
    我们首先要弄清楚这个任务的商业目的是什么,公司想要从这个模型中得到什么;这个问题很重要,因为他决定了你怎么设计你的流程,怎样选择算法,怎样选择性能度量指标,以及要花多少时间力气来调整它。
    其次我们要知道该问题现有的解决方案以及这些解决方案的实行效果,这可以作为一个性能度量参考。
    有了以上信息以后,我们要开始考虑,这是个问题是监督、非监督、还是强化学习?他是一个分类任务还是回归任务?我们要用批量学习还是在线学习?
    这个任务很显然是一个监督学习任务,因为我们的训练数据是有标签的(每个实例都是对应的中值房价);他也是一个回归任务,因为我们需要去预测出一个房价,这是一个准确的值而不是某个分类;在这个任务中我们选用批量学习,因为数据量较小并且输入数据并不总是很快的变化。

    做好了以上决定,我们接下来要选择一个合适的性能度量指标,一个经典的用于回归问题的度量指标是RMSE(Root Mean Square Error),它表示的是,模型预测错误的标准差;但有时如果存在很多异常值,我们会偏向选择MAE(Average Absolute Deviation)。

  2. 获取数据
    从这里开始会有大量代码,这本书中的代码全都可以在这里找到,我们用书中提供的网址下好数据(他是一个CSV文件),然后用pandas读入数据:

     import pandas as pd
     def load_housing_data(housing_path=HOUSING_PATH):
        csv_path = os.path.join(housing_path, "housing.csv")
     return pd.read_csv(csv_path)
     housing = load_housing_data()
    

    然后我们来看一下数据:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第1张图片
    可以看到每条数据有10个属性,一共有20640条数据;我们能注意到 total_bedrooms 属性只有20433行,说明这个特征有一些空值;我们还注意到几乎所有的属性都是数值型,只有 ocean_proximity 的类型是 object,并且我们能发现这个特征里有很多重复的值,因此它能够作为一个类别性特征,相同值编码为同一数值,下图能看到每个类别有多少条数据。
    完整走完一个机器学习项目(end-to-end machine learning project)上_第2张图片
    我们还能用 describe() 方法来看看数据的统计特征:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第3张图片
    count、mean大家都明白的,值得关注的是,min、25%、50%、75%、max 代表的是以某一特征为准,所有数据的最小值、25%的值、中值、75%的值以及最大值。
    当然也可以通过画直方图来快速并且直观的得到这些特性:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第4张图片
    我们需要用训练中没有使用过的新数据来对我们的模型进行测试,所以把数据分成训练数据和测试数据两部分是有必要的;当我们把训练好的模型应用到测试数据上时,这个错误率就是我们常说的泛化误差(generalization error)。
    Scikit-Learn 提供了一些函数为我们切分数据集,最简单的函数是 train_test_split:
    在这里插入图片描述
    参数 random_state 是用来设置随机种子的,先生成一组随机数然后把这组随机数传入不同数据集,那么这些数据集都会使用同样一组随机数作为索引进行切分;test_size 是测试集的大小。
    这个方法使用的是纯随机采样方法。事实上如果你的数据集足够大这样是OK的,但如果数据集不够大,这样的采样方法很可能会引入相当的采样偏差。举个例子,假设一家公司想随机找1000人做一个问卷调查,他们会很希望这1000个人是具有代表性的; 如果这个国家人口52%是男性48%是女性,他们会希望所找的这1000人中也是52%男性48%女性;当然除了性别也存在别的属性是需要我们考虑是否要按某种比例来采样的,这种采样方法就叫做分层采样(stratified sampling)。
    从本章的预测房价的例子来看,假设我们通过跟专家的谈话得知,中值收入(median income)是一个对房价预测很重要的属性,因此我们希望根据中值收入来进行分层采样。因为中值收入是一个连续数值型属性,所以我们首先需要创建一个中值收入的类别型属性。我们先来看一看中值收入这个属性的分布:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第5张图片
    大多数行的中值收入集中在2-5(单位是万美元),但也有一部分是远大于的6的。分层采样很重要的一点是要保证每个层都有足够的数据量,因此我们不应该有太多层;本书选择的方法是把中值收入除以1.5,然后通过ceil函数向上取整使其变成离散整数值,最后把所有大于5的值全部归位一类(即都归为5.0);通过value_counts()可以查看这个新创建的属性:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第6张图片
    分好层以后,我们就可以用这个新的属性来进行分层采样了,sklearn 提供了一个 StratifiedShuffleSplit 类:
    完整走完一个机器学习项目(end-to-end machine learning project)上_第7张图片
    可以看到用分层采样的方法切分数据集得到的测试集,它的每个层级占总测试集的比例跟总数据集(切分前)每个层级所占比例相同。
    分好训练集和测试集之后我们需要移除我们新创建的属性,使得整个数据集回到他最初的样子:

    for set in (strat_train_set, strat_test_set):
       set.drop(["income_cat"], axis=1, inplace=True)
    

    这一章内容太多啦,先写一部分,下篇文章见~

你可能感兴趣的:(机器学习)