《Scikit-Learn与TensorFlow机器学习实用指南》笔记02章

一个完整的机器学习项目

这一章中,书中的作者让我们作为房地产公司的雇佣的数据科学家,实现了一个预测房价的项目。(为什么书中第一个介绍的都是预测问题,不懂不懂,哈哈~~)

感觉这一章与我之前学习过的一篇博文有异曲同共之妙呢,之前学习过的博文的地址是:https://blog.csdn.net/qq_40027052/article/details/78912963

这一篇博文可能来源与书籍(《机器学习——Python实践》)(感觉发现了不同书籍入门的相似之处???吼吼侯)

言归正传。在这一章中处理问题分为以下几步:

1.项目概述

2获取数据

3.可视化数据,发现数据中的规律

4.为机器学习或者深度学习准备数据

5.选择模型,进行训练

6.微调模型

7.给出解决方案

8.部署、监控、维护系统

目前作为一个学生,第一步和最后一步可能涉及不多。

我理解第一步的意义是,可能在生产实践中,一个问题的产生和解决方案和很多因素有关,要弄清楚项目的用途,以确定需要结果的准确度,以及使用什么种类的模型
最后一步是将自己的成果上线,维护。

我作为一个学生,一般问题都是给定的,我所作的基本就是使用模型,然后最好能微调他,(现在还不太会,,,),让结果达到一个高度工作基本就结束了。

介绍一个各个步骤:

1.划定问题

询问老板的第一个问题应该是商业目标是什么?建立模型可能不是最终目标。公司要如何使用、并从模型受益?这非常重要,因为它决定了如何划定问题,要选择什么算法,评估模型性能的指标是什么,要花多少精力进行微调。

老板告诉你,你的模型的输出(一个区的房价中位数)会传给另一个机器学习系统(见图2-2),也有其它信号会传入后面的系统。这一整套系统可以确定对某个区投资值不值。确定投资与否非常重要,它直接影响利润。

房地产投资机器学习管道
注意:
一系列的数据处理组件被称为数据管道。管道在机器学习系统中很常见,因为有许多数据要处理和转换。

组件通常是异步运行的。每个组件吸纳进大量数据,进行处理,然后将数据传输到另一个数据容器中,而后管道中的另一个组件收入这个数据,然后输出,这个过程依次进行下去。每个组件都是独立的:组件间的接口只是数据容器。这样可以让系统更便于理解(记住数据流的图),不同的项目组可以关注于不同的组件。进而,如果一个组件失效了,下游的组件使用失效组件最后生产的数据,通常可以正常运行(一段时间)。这样就使整个架构相当健壮。

另一方面,如果没有监控,失效的组件会在不被注意的情况下运行一段时间。数据会受到污染,整个系统的性能就会下降。

下一个要关注的问题是:现在的解决方案的效果如何,通常会给出一个性能参考。比如现有的方法时间为多少,成本为多少,错误率为多少。等

现在,有了上边这些信息,可以进行设计系统了。首先确定这是一个监督的,回归的,批量学习任务。

使用的数据集可以在:
https://github.com/ageron/handson-ml/tree/master/datasets/housing
获得。

选择性能指标

回归问题的典型指标是均方根误差(RMSE)。均方根误差测量的是系统预测误差的标准差。

RMSE
我学习到的翻译是:

RMSE等于50000,意味着,68%的系统预测值位于实际值的50000以内。95%的预测值位于实际值的100000以内。

这里没太看懂,如果有大佬看懂了,欢迎指导~~~~

有时可能会用到绝对平均误差:
绝对平均误差

ps:书中给的下载数据的代码没调通,所以我直接去github上下载使用的。链接在上边啦

下载数据后,对数据进行了一通观察:
包括这样:
前五行数据

这样:
信息
这样:
数值属性概括
以及这样:

>>> housing["ocean_proximity"].value_counts()
<1H OCEAN     9136
INLAND        6551
NEAR OCEAN    2658
NEAR BAY      2290
ISLAND           5
Name: ocean_proximity, dtype: int64

和这样查看每个属性的分布:

%matplotlib inline   # only in a Jupyter notebook
import matplotlib.pyplot as plt
housing.hist(bins=50, figsize=(20,15))
plt.show()

属性柱状图
可以从这些基本的查看中,了解一共有多少个属性,各个属性的类型,及分布,为以后的分析打下基础。如这里的ocean_proximity属性的字符的,后期算中位数就要对他作处理,因为只有数值才能计算中位数。

创建测试集

在这个阶段就分割数据,听起来很奇怪。毕竟,你只是简单快速地查看了数据而已,你需要再仔细调查下数据以决定使用什么算法。这么想是对的,但是人类的大脑是一个神奇的发现规律的系统,这意味着大脑非常容易发生过拟合:如果你查看了测试集,就会不经意地按照测试集中的规律来选择某个特定的机器学习模型。再当你使用测试集来评估误差率时,就会导致评估过于乐观,而实际部署的系统表现就会差。这称为数据透视偏差。

可以使用sklearn.model_selection中的train_test_split 划分训练集和测试集。
使用方法大概如下:
x_train_,x_valid,y_tain_,y_valid=train_test_split(x_train,y_train,test_size=0.2)

但这是随即选择了20%作为测试集。如果在样本分布不均匀的数据集中,这种办法可能会产生问题,这时的方法是分层采样。

将数据集分成均匀的子分组,称为分层,从每个分层取出合适数量的实例,以保证测试集对总体有代表性。

如果我们已经知道某个属性很重要,就要保证数据集中包含了这个属性的各个值的分布,这点很重要。
进行分层采样可以使用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]

n_splits:是将训练数据分成train/test对的组数,可根据需要进行设置,默认为10
test_size和train_size: 是用来设置train/test对中train和test所占的比例。
random_state:随机数种子,和random中的seed种子一样,保证每次抽样到的数据一样,便于调试.

查找关联关系

因为数据集并不是非常大,你可以很容易地使用corr()方法计算出每对属性间的标准相关系数(也称作皮尔逊相关系数):

corr_matrix = housing.corr()

相关系数的范围是-1到1。当接近1时,意味强正相关;当相关系数接近-1时,意味强负相关,相关系数接近0,意味没有线性相关性。

另一种检测属性间相关系数的方法是使用Pandas的scatter_matrix函数,它能画出每个数值属性对每个其它数值属性的图。现在共有11个数值属性,你可以得到112=121张图。

属性组合实验:

不同的属性组合可能产生意想不到的结果

数据清洗

大多机器学习算法不能处理特征丢失,因此先创建一些函数来处理特征丢失的问题。

处理缺失值,这里给出了几个解决方法:

去掉对应的分区;

去掉整个属性;

进行赋值(0、平均值、中位数等等)。

(简单粗暴。。。。。。。)

Scikit-Learn提供了一个方便的类来处理缺失值:Imputer。下面是其使用方法:首先,需要创建一个Imputer实例,指定用该属性的中位数替换它的每个缺失值:

from sklearn.preprocessing import Imputer

imputer = Imputer(strategy="median")

imputer.fit(XXX) //fit某某某,将imputer实例拟合到训练数据

X = imputer.transform(XXX)//使用这个“训练过的”imputer来对训练集进行转换,通过将缺失值替换为中位数
ps:Scikit-Learn设计

Scikit-Learn设计的API设计的非常好。它的主要设计原则是:
一致性:所有对象的接口一致且简单:
估计量(estimator)。任何可以基于数据集而对一些参数进行估计的对象都被设计成估计量(比如,imputer就是个估计量)。估计本身是通过fit()方法,只需要一个数据集作为参数(对于监督学习算法,需要两个数据集;第二个数据集包含标签)。任何其它用来指导估计过程的参数都被当做超参数(比如imputer的strategy),并且超参数要被设置成实例变量(通常是通过构造器参数)。
转换量(transformer)。一些估计量(比如imputer)也可以转换数据集,这些估计量被称为转换量。API也是相当简单:转换是通过transform()方法,被转换的数据集作为参数。返回的是经过转换的数据集。转换过程依赖学习到的参数,比如imputer的例子。所有的转换都有一个便捷的方法fit_transform(),等同于调用fit()再transform()(但有时fit_transform()经过优化,运行的更快)。
预测量(predictor)。最后,一些估计量可以根据给出的数据集做预测,这些估计量称为预测量。例如,上一章的LinearRegression模型就是一个预测量:它根据一个国家的人均GDP预测生活满意度。预测量有一个predict()方法,可以用新实例的数据集做出相应的预测。预测量还有一个score()方法,可以根据测试集(和相应的标签,如果是监督学习算法的话)对预测进行衡量。

可检验。所有估计量的超参数都可以通过公共实例变量直接访问(比如,imputer.strategy),并且所有估计量学习到的参数也可以通过公共实例变量添加下划线后缀访问(比如,imputer.statistics_)。

类不可扩散。数据集被表示成NumPy数组或SciPy稀疏矩阵,而不是自制的类。超参数只是普通的Python字符串或数字。

可组合。尽可能使用现存的模块。例如,用任意的转换量序列加上一个估计量,就可以做成一个Pipeline,后面会看到例子。

合理的默认值。Scikit-Learn给大多数参数提供了合理的默认值,很容易就能创建一个系统。

特征缩放

数据要做的最重要的转换之一是特征缩放。除了个别情况,当输入的数值属性量度不同时,机器学习算法的性能都不会好。

有两种常见的方法可以让所有的属性有相同的量度:线性函数归一化(Min-Max scaling)和标准化(standardization)。

线性函数归一化(许多人称其为归一化(normalization))很简单:值被转变、重新缩放,直到范围变成0到1。我们通过减去最小值,然后再除以最大值与最小值的差值,来进行归一化。Scikit-Learn提供了一个转换量MinMaxScaler来实现这个功能。它有一个超参数feature_range,可以让你改变范围,如果不希望范围是0到1。

标准化就很不同:首先减去平均值(所以标准化值的平均值总是0),然后除以方差,使得到的分布具有单位方差。与归一化不同,标准化不会限定值到某个特定的范围,这对某些算法可能构成问题(比如,神经网络常需要输入值得范围是0到1)。但是,标准化受到异常值的影响很小。例如,假设一个分区的收入中位数是100。归一化会将其它范围是0到15的值变为0-0.15,但是标准化不会受什么影响。Scikit-Learn提供了一个转换量StandardScaler来进行标准化。

转换Pipeline

你已经看到,存在许多数据转换步骤,需要按一定的顺序执行。幸运的是,Scikit-Learn提供了类Pipeline,来进行这一系列的转换。下面是一个数值属性的小pipeline:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

num_pipeline = Pipeline([
        ('imputer', Imputer(strategy="median")),
        ('attribs_adder', CombinedAttributesAdder()),
        ('std_scaler', StandardScaler()),
        ])

housing_num_tr = num_pipeline.fit_transform(housing_num)

当你调用pipeline的fit()方法,就会对所有转换量顺序调用fit_transform()方法,将每次调用的输出作为参数传递给下一个调用,一直到最后一个评估量,它只执行fit()方法。

选择并训练模型

你在前面限定了问题、获得了数据、探索了数据、采样了一个测试集、写了自动化的转换pipeline来清理和为算法准备数据。现在,你已经准备好选择并训练一个机器学习模型了。

使用交叉验证做更佳的评估:

下面的代码采用了K折交叉验证(K-fold cross-validation):它随机地将训练集分成十个不同的子集,成为“折”,然后训练评估决策树模型10次,每次选一个不用的折来做评估,用其它9个来做训练。结果是一个包含10个评分的数组:

from sklearn.model_selection import cross_val_score
scores = cross_val_score(tree_reg, housing_prepared, housing_labels,
                         scoring="neg_mean_squared_error", cv=10)
rmse_scores = np.sqrt(-scores)

模型微调

假设你现在有了一个列表,列表里有几个有希望的模型。你现在需要对它们进行微调。让我们来看几种微调的方法。

网格搜索:

使用Scikit-Learn的GridSearchCV来做这项搜索工作。你所需要做的是告诉GridSearchCV要试验有哪些超参数,要试验什么值,GridSearchCV就能用交叉验证试验所有可能超参数值的组合。例如,下面的代码搜索了RandomForestRegressor超参数值的最佳组合:

from sklearn.model_selection import GridSearchCV

param_grid = [
    {'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
    {'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]},
  ]

forest_reg = RandomForestRegressor()

grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
                           scoring='neg_mean_squared_error')

grid_search.fit(housing_prepared, housing_labels)

grid_search.best_params_#最好的参数
grid_search.best_estimator_#最好的估计量
grid_search.cv_results_#得到估计值
grid_search.best_estimator_.feature_importances_#指出每个属性对作出准确预测的重要性

最后就是评估系统,上线啦。(上线是不可能上线的,,,)

学习感悟:

1.习惯于一拿到数据就直接喂到模型里,像书中所作的分析,各种可视化观察规律基本没有做过,觉得很浪费时间。但这可能不太好。对数据越熟悉可能越有利于后续的分析。跑了一系列模型最后在来看数据的规律才真的是浪费时间。

2.书中说先试模型,有一个大概可用的模型备选方案。不要在一开始就在微调模型上花费太多的时间。我作为一个新手,最近参加了一个新手比赛。感觉就范了这个错误。跑出一个模型后,就一直想调他,关键还不会!!就在那瞎试,浪费了很多时间。

3.要学习的还有很多,希望我能坚持把这本书学完~~~~~~~~

这里只是学习的记录,不是很详细,建议大家去看原文~~~

我学习的地址是:

https://www.jianshu.com/p/aa79408073b6

前辈翻译的很好,感谢您的辛苦工作~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值