Python玩机器学习简易教程

2018-02-28 14:13:11 浏览数 (1)

本文介绍利用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()对数据做预处理,然后用随机森林回归算法拟合生成一个模型。
    1. pipeline = make_pipeline(preprocessing.StandardScaler(), RandomForestRegressor(n_estimators=100))
    2. scaler = preprocessing.StandardScaler().fit(X_train)
    3. X_train_scaled = scaler.transform(X_train)
    4. print(X_train_scaled.mean(axis=0))
    5. print(X_train_scaled.std(axis=0))
    6. X_test_scaled = scaler.transform(X_test)
    7. print(X_test_scaled.mean(axis=0))
    8. 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-折交叉验证为例。

  1. 把数据集划分成10等分;
  2. 利用9等分训练模型;
  3. 剩下的1等分评估模型效果;
  4. 重复2和3步10次,每次采用不同的1等分用来做模型验证;
  5. 聚合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

截止到目前,基于随机森林回归模型,已经完成了。这个模型是否为解决问题的最佳模型呢?可以从以下三方面思考。

  1. 模型能否解决好问题?
  2. 模型的性能相对于基准线是什么情况?
  3. 模型的性能优化点有哪些?

改善模型性能的常用方法总结。

  • 收集更多的数据
  • 花更多时间做好特征工程
  • 尝试其他模型和算法(正则化回归、提升树等)
  • 吸收更多有用的领域知识
  • 采用集成学习的思想

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)

0 人点赞