本文介绍利用Python和Python的机器学习库scikit-learn完成一个端到端的机器学习项目。
俗话说,“师傅领进门,修行在个人”。本文就是扮演领进门这种角色,至于各位看官能够修行到什么境界,全凭自己。
- 1 设置环境
- 2 导入所需库和模块
- 3 加载数据集
- 4 数据集划分为训练集和测试集
- 5 数据预处理
- 6 参数调优
- 7 模型优化(交叉验证)
- 8 全数据拟合
- 9 模型评估
- 10 模型保存
1 设置环境
检查电脑是否安装了Python以及相应库numpy/pandas/scikit-learn。 若是没有,推荐一键式安装Anaconda(安装教程)。 安装好后,测试一下版本号。 Code:
代码语言:javascript复制import sysprint("Python版本:%s" %sys.version)
import numpyprint("numpy版本:%s" %numpy.__version__)
import matplotlibprint("matplotlib版本:%s" %matplotlib.__version__)
import pandasprint("pandas版本:%s" %pandas.__version__)
import sklearnprint("sklearn版本:%s" %sklearn.__version__)
Result:
2 导入所需库和模块
科学计算库numpy 数据处理和分析库pandas 数据集划分模块train_test_split 数据预处理模块preprocessing 数据算法模块RandomForestRegressor 模型优化模块make_pipeline和GridSearchCV 模型评估模块mean_squared_error和r2_score 模型保存模块joblib
Code:
代码语言:javascript复制import numpy as np
import pandas as pd
from sklearn.model_selection
import train_test_splitfrom sklearn
import preprocessingfrom sklearn.ensemble
import RandomForestRegressorfrom sklearn.pipeline
import make_pipelinefrom sklearn.model_selection
import GridSearchCVfrom sklearn.metrics
import mean_squared_error, r2_scorefrom sklearn.externals
import joblib
3 加载数据集
俗话说“巧妇难为无米之炊”。 “数据”是原材料。 本教程使用wine data数据集。 加载数据集和数据简单探索性分析。 Code:
代码语言:javascript复制dataset_url = "http://mlr.cs.umass.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"data = pd.read_csv(dataset_url, sep = ";")print(data.head())print(data.shape)print(data.describe())
4 数据集划分为训练集和测试集
数据集划分目的用来评估模型的性能和效果。 Code:
代码语言:javascript复制y = data.qualityX = data.drop("quality", axis = 1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 123, stratify=y)
train_test_split模块的参数说明:
- test_size: 设置测试集占总样本的比例
- random_state: 设置随机种子,便于可重复性试验
- stratify=y:让训练集和测试集具有相似性,服务模型评估
5 数据预处理
使用Transformer API 做数据预处理,具体步骤如下:
- 对训练数据集拟合生成一个转换器(保存均值和标准差)
- 利用转换器对训练集做预处理
- 利用转换器对测试集做预处理(使用了与训练集相同的均值和标准差)
代码如下:
有时候,我们设置交叉验证管道(pipeline)时,不需要手工设置Transformer API,我们可以创建一个管道对象,如下:
这个pipeline对象首先使用StandardScaler()对数据做预处理,然后用随机森林回归算法拟合生成一个模型。
pipeline = make_pipeline(preprocessing.StandardScaler(),
RandomForestRegressor(n_estimators=100))
scaler = preprocessing.StandardScaler().fit(X_train)
X_train_scaled = scaler.transform(X_train)
print(X_train_scaled.mean(axis=0))
print(X_train_scaled.std(axis=0))
X_test_scaled = scaler.transform(X_test)
print(X_test_scaled.mean(axis=0))
print(X_test_scaled.std(axis=0))
6 参数调优
一个模型里面包括两个方面的参数:
- 方面一:模型参数,从数据中最终可以学习到的参数,例如回归算法的系数。
- 方面二:超参数,从数据中学习不到的参数,在做模型之前需要事先设置好的参数。
举例说明:随机森林回归算法的超参数 随机森林需要生成多少棵树? 随机森林中树产生的标准?(MSE或者MAE) 下面罗列随机森林回归算法的超参数 代码如下:
代码语言:javascript复制print(pipeline.get_params())
与超参数相关结果如下:
代码语言:javascript复制RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,max_features='auto', max_leaf_nodes=None,min_impurity_split=1e-07, min_samples_leaf=1,min_samples_split=2, min_weight_fraction_leaf=0.0,n_estimators=100, n_jobs=1, oob_score=False, random_state=None,verbose=0, warm_start=False)
交叉验证时设置需要调整的超参数 代码如下:
代码语言:javascript复制hyperparameters = { 'randomforestregressor__max_features' : ['auto', 'sqrt', 'log2'],'randomforestregressor__max_depth': [None, 5, 3, 1]}
7 模型优化(交叉验证)
交叉验证是模型性能评估的一种可靠方法。 常用10-折交叉验证为例。
- 把数据集划分成10等分;
- 利用9等分训练模型;
- 剩下的1等分评估模型效果;
- 重复2和3步10次,每次采用不同的1等分用来做模型验证;
- 聚合10次模型评估性能,当做模型性能最终值;
基于管道对象实现交叉验证 代码
代码语言:javascript复制clf = GridSearchCV(pipeline, hyperparameters, cv=10)clf.fit(X_train, y_train)print(clf.best_params_)
结果发现超参数默认值为最佳。
8 全数据拟合
当使用交叉验证方法找到最佳的超参数后,为了进一步改善模型的性能需要对全部训练数据做模型拟合。 GridSearchCV已经用最佳超参数对全部训练数据集做了模型拟合,代码查看如下。
代码语言:javascript复制print(clf.refit)
结果为True
9 模型评估
在测试集上做模型评估 代码如下
代码语言:javascript复制y_pred = clf.predict(X_test)print(r2_score(y_test, y_pred))print(mean_squared_error(y_test, y_pred))
结果如下: 0.465495005751 0.344901875
截止到目前,基于随机森林回归模型,已经完成了。这个模型是否为解决问题的最佳模型呢?可以从以下三方面思考。
- 模型能否解决好问题?
- 模型的性能相对于基准线是什么情况?
- 模型的性能优化点有哪些?
改善模型性能的常用方法总结。
- 收集更多的数据
- 花更多时间做好特征工程
- 尝试其他模型和算法(正则化回归、提升树等)
- 吸收更多有用的领域知识
- 采用集成学习的思想
10 模型保存
模型保存,以便后续使用和模型部署与实施。 代码
代码语言:javascript复制joblib.dump(clf, 'rf_regressor.pkl')
clf2 = joblib.load('rf_regressor.pkl')
clf2.predict(X_test)
附录:完整代码参考
代码语言:javascript复制## Python玩机器学习简易教程##开始时间:2017年8月24日##结束时间:2017年9月16日## 第一步:设置环境
import sysprint("Python版本:%s" %sys.version)
import numpyprint("numpy版本:%s" %numpy.__version__)
import matplotlibprint("matplotlib版本:%s" %matplotlib.__version__)
import pandasprint("pandas版本:%s" %pandas.__version__)
import sklearnprint("sklearn版本:%s" %sklearn.__version__)
## 第二步:导入所需库
import numpy as np
import pandas as pd
from sklearn.model_selection
import train_test_splitfrom sklearn
import preprocessingfrom sklearn.ensemble
import RandomForestRegressorfrom sklearn.pipeline
import make_pipelinefrom sklearn.model_selection
import GridSearchCVfrom sklearn.metrics
import mean_squared_error, r2_scorefrom sklearn.externals
import joblib
## 第三步:加载数据集
dataset_url = "http://mlr.cs.umass.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
data = pd.read_csv(dataset_url, sep = ";")
print(data.head())print(data.shape)
print(data.describe())
## 第四步:数据集划分
y = data.qualityX = data.drop("quality", axis = 1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 123, stratify=y)
## 第五步:数据预处理## 对训练集的所有特征进行标准化处理
pipeline = make_pipeline(preprocessing.StandardScaler(), RandomForestRegressor(n_estimators=100))
## 第六步:参数调优
print(pipeline.get_params())
hyperparameters = { 'randomforestregressor__max_features' : ['auto', 'sqrt', 'log2'], 'randomforestregressor__max_depth': [None, 5, 3, 1]}
## 第七步:模型优化(交叉验证)
clf = GridSearchCV(pipeline, hyperparameters, cv=10)
clf.fit(X_train, y_train)print(clf.best_params_)
## 第八步:全数据拟合print(clf.refit)
## 第九步:模型评估
y_pred = clf.predict(X_test)
print(r2_score(y_test, y_pred))
print(mean_squared_error(y_test, y_pred))
## 第十步:模型保存
joblib.dump(clf, 'rf_regressor.pkl')
clf2 = joblib.load('rf_regressor.pkl')
# 加载模型预测新的数据集clf2.predict(X_test)