[toc]
end to end machine learning project
这一章主要介绍了整个机器学习的过程,从获取数据处理数据开始,然后到应用到模型,调整模型。本章数据为加州某个时期房价的数据,所以主要的任务是一个回归任务,下面具体总结一下作者在这一章主要传授的观点和自己的一些收获。
Look at the big picture
也就是说,在可是意向任务之前,需要思考一下,你需要解决一个什么样的问题?期望得到的结果是什么?为了得到这样的结果需要做哪些工作?手头有哪些数据?需不需要获取额外的data?可以把这个问题抽象成一个什么样的问题?supervised or unsupervised or semi-supervised, 是回归还是分类,有没有现成的解决方案?这些解决方案够不够解决我需要的问题,不够,我需要如何改进这些方案?综合各种成本,我需要投入多少时间和精力?
Take quick look at the data structure
- 常用函数
- data.head()
- data.info() 可以快速看到数据框每列的大小、类型、以及是否有缺失值
- data[‘’].value_counts()
- data.describe()
- 画出所有数值类型的条形图,可以直观的看书数值类型的分布情况。
1
2
3
4%matplotlib inline
import matplotlib.pyplot as plt
data.hist(bins=50,figsize=(20,15))
plt.show()
划分训练集和测试集
书中的观点是提起把测试集划分出来,并不参与训练集的数据预处理部分,只是在后面重新把数据预处理重新应用在测试集上面,我的观点是是否可以放在一起作数据预处理,后面训练模型的时候再划分开数据集
数据集可视化
学到一条厉害的命令1
2
3
4
5
6
7
8
9housing.plot(kind='scatter',x='longitude',y='latitude')
# 这条命令也是直接在数据框上面操作的,用之前也需要导入上面提到的包等,这个图最终画出的是一条散点图。
# 由于样本点还是挺多的,所以画散点图的时候,有些店会有重叠,故可以添加一个alpha参数,透明
housing.plot(kind='scatter',x='longitude',y='latitude',alpha = 0.3)
# 为了完善图像,还需要添加一些图例等东西
housing.plot(kind='scatter',x='longitude',y='latitude',alpha = 0.3,s = housing['population']/100,label='population',c='media_house_value', cmap=plt.get_cmap('jet'),colorbar=True,)
plt.legend()
# 上面的参数,s: 散点的大小, c: 颜色, cmap暂时还没搞清楚
# 这个图的最终的结果可以看出4个维度的东西,1,2:点的位置,3: 根据点的大小能看出population的大小,4: 根据点的颜色可以看出media_house_value的大小,厉害!!
探索特征之间的相关性
housing.corr(): 返回特征与特征之间的相关系数,取值为【-1,1】,但是要注意的是,这个数值描述的只是变量之间的线性相关性,不能体现出他们之间的非线性关系,如corr(a,b)=0, 不能说a与b是完全独立的,有可能它们之间存在非线性的关系
可视化1
2
3
4from pandas.tools.plotting import scatter_matrix
attributes = ['v1','v2',...,'v_m']
scatter_matrix(housing[attributes],figsize=(12,8))
# 这个函数会画出m*m个散点图,对角线上是频率直方图
属性之间的连接关系
也就是说属性与属性之间可以作乘除等一些变换,具体需要根据实际的业务场景,单个特征也可以做一些非线性的变换,比如log
为算法模型准备标准化的数据
这一个步骤主要集中在对数据的预处理方面,比如说,数据清洗、缺失值处理,离散数据或者非数值型数据的编码、数据的缩放、标准化等
data cleaning
sklearn 提供了一个处理缺失值的类Imputer,其实在实际应用中,这一个步骤还是需要灵活应用,具体根据实际情况来处理1
2
3
4
5
6
7from sklearn.preprocessing import Imputer
imputer = Imputer(strategy = 'median') # 根据中位数填充
# 让数框只包含数值类型
housing_num = housing.drop('ocean_proximity',axis=1)
imputer.fit_transform(housing_num)
# 后续处理的时候,只需要
# imputer.transform(housing_new)
文本、字符型、category特征的处理
对待这类特征,首先大部分的模型只能处理数值型的向量,所以需要量化这些特征,但量化后就会存在一个问题,有了数字,那么在计算机的眼里,这些category就有了大小,同时就会产生不同的度量,比如颜色红、黄、蓝,不能说谁比谁大,但是数值编码红黄蓝分别为1,2,3,那你就默认了黄与红之间差1,红与蓝差2,这样在实际中是不存在这种关系的,一种好的解决办法就是hotonecode—热编码。
sklearn提供的编码机制1
2
3
4
5
6
7
8
9
10
11
12
13# 普通的数值化编码
form sklearn.preprocesing import LabelEncoder
encoder = LabelEncoder()
housing_cat_encoded = encoder.fit_transform(housing_cat)
# 热编码
form sklearn.preprocesing import OneHotEncoder
encoder = OneHotEncoder()
# 这地方将上面数值化编码后的变量再次使用热编码,但是需要注意的地方是,此处传入的参数需要是一个二维数组,返回的是一个稀疏矩阵
housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(-1,1))
# 直接热编码
form sklearn.preprocesing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(housing_cat)
特征缩放
这里是将数值型(到了这一步,应该都已经是数字型)的变量统一映射到一个范围,这样做对基于度量的一些模型是很有必要的。主要有两种方法
- MinMaxScaler 统一映射到一个范围,但是对outlier比较敏感
- StandardScaler 每个特征都标准化成均值为0,方差为1的数值,但是特征之间的映射范围可能不会一致,对outlier不敏感
Pipline
学会使用pipline,序列化地数据处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandarScaler
num_attribes = list['数值型特征']
num_pipeline = Pipeline([
('selector',DataFrameSelectot(num_attribes)),
('Imputer',Imputer(strategy='median')),
('std_scaler',StandarScaler()),
])
# 传入数据之后,按照顺序依次处理,上一个执行的输出是下一个执行的输入
housing_num_tr = num_pipeline.fit_transform(housing_num)
# 还可以并行执行
from sklearn.pipeline import FeatureUnion
cat_attribes = list['ocean_proximity']
cat_pipeline = Pipeline([
('selector',DataFrameSelectot(cat_attribs)),
('label_binarizer',cat_pipeline),
])
full_pipeline = FeatureUnion(transform_list = [
('num_pipeline',num_pipeline),
('cat_pipeline',cat_pipeline),
])
housing_prepared = full_pipeline.fit_transform(housing)
模型选择
这一步,开始可以多尝试几个模型,选择一两个效果较好的重点调整。调整模型的参数以及观察模型的效果主要靠交叉验证。
方式一直接做交叉验证,得出结果
1
2
3
4
5from sklearn.model_selection import cross_val_score
cross_val_score(clf,housing_prepared,housing_labels,
scoring='neg_mean_squared_error',cv=10)
# clf : 分类器、学习器
# 直接输出10次交叉验证的结果方式二 方便调整模型的参数
1
2
3
4
5from sklearn.model_selection import GridSearchCV
# 设置调整的参数
param_grid = [{'opt1':value1,'opt2':value2}{'opt3':value3,'opt4':value4}]
grid_search = GridSearchCV(clf,param_grid,cv=5,scoring='')
grid_search.fit(housing_prepared,housing_labels)方式三
1
2
3
4
5
6from sklearn.model_selection import StratifiedKFold
cv = StratifiedKFold(n_splits=k)
for train_index,test_index in cv :
clf.fit()
proba = clf.predict_proba()
保存最终的模型
1 | from sklearn.externals import joblib |