一个完整的项目流程图_完整走完一个机器学习项目(end-to-end machine learning project)中...

Chapter 2 End-to-End Machine Learning Project

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

  1. 对所需解决的问题有一个总体的思路

2. 获取数据

3. 通过数据可视化来得到对数据潜在规律的一些思考

4. 在训练模型之前先对数据进行预处理

5. 选择一个合适的模型进行训练

6. 调整并找到最合适的模型参数

7. 长期监督并维护你的学习系统

上一篇写了1和2,这篇来写后面的。(怎么感觉这篇也写不完???哈哈哈算了先写着吧)

3. 通过数据可视化来得到对数据潜在规律的一些思考:

上一篇文章我们已经对数据集有了大致的了解,第三步我们要做的是把测试集扔在一边不要管,然后来探索一下训练集的数据潜在逻辑,我们复制一份训练集数据以免破坏原数据:

housing = strat_train_set.copy()

我们观察到数据集中包含了一个地理信息(经纬度),让我们可视化来看看:

5e6095d73e3ab068b6c69eb941b5deed.png

这样其实还是不好分辨他的分布规律,我们可以设置参数 alpha:

9d2027e2cc5ae34da2f70b097c1ac027.png

我这里的 alpha 设置的是0.2,原书是0.1,大家可以自己试试别的数值,越接近零,透明度越高;设置了 alpha 以后,分布规律就变得很显然了,颜色深的地方密度更大。

现在我们加入更多的属性来看,设置每个圆点半径表示某地区的人口,圆点颜色表示房价,用一个定义好的colormap(jet)来表示房价的高低:

bb5e9557f3fa1be7f79ec9ad5ed3dc96.png

这一轮探索让我们发现房价跟地理位置以及人口数量的关系。

接下来我们进一步探索属性之间的相关性,可以用 corr() 方法来简单的计算 Pearson 相关系数,然后查看每个属性与房价的相关性:

67e4f45f53ec57b48dfa3287d1efda20.png

能看到中值收入(median_income)跟房价的相关性很高。

另一种查看相关性的方法是用 Pandas 库的 scatter_matrix 函数,它会画出每个数值型属性之间的散点图,因为属性太多,我们只选择几个相关度较高的属性来进一步探索:

5c5fd504ffd0e74faa275d3c4eef439a.png

对角线上如果画出散点图应该是一条直线,就没什么意义,所以 Pandas 就画出该属性的直方图来替代。从上面的散点图来看,很显然是中值收入(median_income)跟房价的相关性最高,所以接下来我们专注于这一个属性来进行探索:

cacbf8594bc15b456f163589e0344a43.png

可以看到收入和房价的相关度很高,散点图中点比较聚集,呈现正向趋势;并且房价有一个很明显的上限在 $500000 左右,除此之外,其实我们也能发现在 $450000 和 $350000 的位置也有一条水平线,后来的这两条水平线很有可能是我们想要消除的数据噪音,这一点有待大家深入探索。

在进行数据预处理前我们的最后一步是尝试去组合出新的特征,在这个例子中,我们可能会想要用总房间数(total_rooms)和房屋数(households)组合出每个房屋的房间数量(rooms_per_household),还有类似的每个房间的卧室数量(bedrooms_per_room),每个房屋的人数(population_per_household)等,下面我们来尝试组合出这些特征并查看分析他们与房价的相关性:

8f8e2dee4f6bfddeec8ccbac853b39b8.png

看起来还不错,新特征每个房间的卧室数量(bedrooms_per_room)与房价的相关度比房间总数以及卧室总数都要高,呈现的是负相关;每个房屋的房间数量(rooms_per_household)与房价的相关度也明显比组合前要高。

4. 在训练模型之前先对数据进行预处理:

处理之前我们先把训练集的特征和标签(房价)分离开:

housing = strat_train_set.drop("median_house_value", axis=1) 
housing_labels = strat_train_set["median_house_value"].copy()

之前我们发现属性 total_bedrooms 有一些空值,我们有三个方法来解决这个问题;一是删除有空值的行,二是删除有空值的列(这里就是删除total_bedrooms这一列),三是给空值填充一些合适的值(例如零值、平均值、中值等):

housing.dropna(subset=["total_bedrooms"])  #方法一 删除有空值的行
housing.drop("total_bedrooms",axis=1)  #方法二 删除有空值的列
median = housing["total_bedrooms"].median()
housing["total_bedrooms"].fillna(median)  #方法三 给空值填充一些合适的值

如果我们选择第三种方法,要记得把中值保存以便后续给测试集填充。

sklearn 提供了一个类 Imputer 让我们更方便的填充空值:

a90664fe6b13eaeeb926ed306987845a.png

我们可以看到,我们先是创建了一个类 Imputer,然后用它去 fit 我们的数据集,fit 以后的这个 Imputer 就从数据集中学习到了一些参数,这时候就可以用来 transform 了;这是 sklearn 库的统一的接口设计。

transform 之后我们得到的值是 Numpy 的 array 类型,我们可以转化成 Pandas 的 Dataframe 类型:

housing_tr = pd.DataFrame(X, colums=housing_num.colums)

接下来我们来看一下怎么处理文本型或者确定类别型属性。

我们需要先把这些属性转化成数值,sklearn 提供了 LabelEncoder 类:

06ffd8a80d1c2b713335444e8fcdbb96.png

这个例子中,’<1H OCEAN’ 被编码为0,'INLAND’为1,'ISLAND’为2,'NEAR BAY’为3,‘NEAR OCEAN’为4。

但是用这个方法有个问题,机器学习算法通常认为数值相近表示这两个属性相似,但事实上用以上方法编码并不能表示这一点;sklearn 提供了另一个类 OneHotEncoder 来做二分类解决这个问题,它使用的是独热编码(one-hot encoding),它编码出来的是一个矩阵:

3275c79f770867024f2676de6a44ae01.png

我们得到的是一个稀疏矩阵,每行只有一个1,表示在这个位置的值是存在的,其他都是零表示其他都不存在。例如第一行就表示’<1H OCEAN’为1,‘INLAND’、’‘ISLAND’、‘NEAR BAY’、'NEAR OCEAN’都为0。

sklearn 还提供了一个类可以一步解决上面的两步:

30b104dfdb761bbbca47dd81a183cfd4.png

虽然 sklearn 提供了很多转换函数(transformers),但有时我们还是需要自定义我们自己的 transformer,比如之前我们尝试的构造新的属性或者自定义的数据清洗。为了跟 sklearn 其他类或函数无缝结合(可以互相调用),我们自定义的类应该包含三个方法:fit(),transform(),fit_transform()(如果你使用 TransformerMixin 作为基类就可以不用手动定义第三个方法 fit_transform),同时也建议使用 BaseEstimator 作为基类,那你就会获得两个方法(get_params() 和 set_params()),这两个方法能帮助你调节超参数。现在,让我们来自定义一个类组合出新的特征:

ce0b20d20ff27efa49d809b2dd2bcbb6.png

这个类即实现了我们之前尝试的三个新组合的特征:每个房屋的房间数量(rooms_per_household),每个房间的卧室数量(bedrooms_per_room),每个房屋的人数(population_per_household)。在这里我们的超参数是是否要添加新特征每个房间的卧室数量(bedrooms_per_room),你还可以设置其他超参数,大家可以自由探索。

接下来是数据预处理里最重要的一步转换:特征缩放(feature scaling)。由于不同特征有不同的尺度,机器学习算法面对这些不同尺度的特征总是不能表现的很好;比如,在本书的房价预测例子中,总房间数尺度为6-39320,而中值收入的尺度为0-15;我们需要使得这些特征尺度一致,才能让我们的算法更好的做预测。

Min-Max 归一化是比较简单的一种,数值被线性的缩放到0-1;sklearn 提供了一个类 MinMaxScaler 实现这个转换,你可以调节超参数 feature_range 实现别的范围(如果你不想要0-1)。

标准化(standardization)可以使得特征值的平均值为零,并且方差为单位方差。标准化不会把值限制在0-1,这有时候可能是个问题(神经网络常常需要0-1的输入值);但标准化是更稳固的,他不容易受到异常值的影响,所以标准化应用相对广泛些。

最后,我们可以利用 sklearn 提供的 Pipeline 类把之前做的所有的数据预处理过程封装为一个转换流程(原书写的是 transformation pipeline,我也不知道该怎么翻译合适,大家明白就好)。下面给了一个例子,把之前我们提的三个过程封装起来了(用中值填充特征空值,组合出新的特征,标准化特征):

e2318f78eb6b25b4069758dfa374dc53.png

在这个 pipeline 里,你开始 fit 的时候,他就会按照顺序首先训练第一个 tranformer 并把参数传给下一个,依次进行。

这样你可以一次性处理完所有的数值型特征,但是如果你要同时处理类别型特征呢?sklearn 提供了一个 FeatureUnion 类,它允许你把多个 transformer 或 pipeline 组合起来,调用 transform 的时候所有的 transformer 会同时运行,等结果出来以后再将所有的结果连接起来。下面的例子是把我们之前的数值型的 pipeline 和类别型的编码转换器组合起来:

ca7a1c38913e0c0c5a62d4fcdf285124.png

这篇写完了3和4啦,下篇应该是真的可以写完这一章了。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值