您的位置:首页 > 编程语言 > Python开发

【Python机器学习实战】一个案例迅速入门所有的Scikit-learn回归模型

2019-01-11 18:14 561 查看

简介

本文旨在通过经典的波士顿放假预测问题来实战运行一下sk-learn中所有常见的回归算法,因此不涉及过多的算法讲解。下面,先对本文中会用到的算法进行简单的介绍:

  • 线性回归器: 线性回归器是最简单、易用的回归模型。由于预测目标直接是实数域上的数值,因此优化目标非常简单,即最小化预测结果和真实值间的差异。本文中我们将使用一种精确计算的解析算法(Linear Regression)和一种快速的随机梯度下降(Stochastic Gradient Descend)算法。
  • 支持向量机(回归): 支持向量机(回归)与其分类模型作用机理有些类似,同样是从训练数据中选取一部分更有效的支持向量,只是这少部分的训练样本提供的不是类别目标,而是具体的预测数值。本文本文将使用三种不同的核函数配置SVM:线性核函数,多项式核函数(Polunomial),径向基核函数(Radial basis function)。核函数简单来说,就是通过某种函数计算,将原有的特征映射到更高维度的空间,从而尽可能达到新的高维度特征线性可分的程度,因此可以很好发挥支持向量机的模型优势。
  • K近邻(回归): KNN是一种不需要训练参数的模型。在回归任务中,KNN模型同样是借助周围K个最近训练样本的目标数值,对待测样本的回归值进行预测。那么就衍生出了不同的预测方式,是使用普通的算术平均算法,还是同时考虑距离的差异进行加权平均?因此本文同时使用了平均回归和根据距离加权回归的两种配置的KNN。
  • 回归树: 回归树在选择不同特征作为分裂节点的策略上与决策树的思路类似。不同之处在于,回归树的叶节点的数据类型不是离散型(即类别)而是连续型。决策树每个叶节点依照训练数据表现的概率倾向决定了其最终的预测类别,而回归树的叶节点却是一个个具体的值。严格上来说,回归树叶节点返回的是“一团”训练数据的均值,而不是具体的、连续的预测值,因此严格的讲,回归树并不能算“回归算法”。
  • 随机森林和极端随机树(Extremely Randomized Trees),ET是普通随机森林的一个变种,与之不同的是,ET在每当构建一棵树的分裂节点(node)的时候,不会任意的选取特征,而是先随机选取一些特征,然后利用信息熵和基尼不纯性等指标选择最佳的节点特征。本文将使用sklearn中三种集成模型:RandomForestRegressor,ExtraTreesRegressor,Gradient Boosting Regressor。

问题引出

本文使用的是sklearn集成的‘美国波士顿地区房价预测’的数据,下面我们先通过代码看下数据描述:

from sklearn import datasets

boston = datasets.load_boston()
print(boston.DESCR)

输出结果如下:

**Data Set Characteristics:**

:Number of Instances: 506

:Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.

:Attribute Information (in order):
- CRIM     per capita crime rate by town
- ZN       proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS    proportion of non-retail business acres per town
- CHAS     Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX      nitric oxides concentration (parts per 10 million)
- RM       average number of rooms per dwelling
- AGE      proportion of owner-occupied units built prior to 1940
- DIS      weighted distances to five Boston employment centres
- RAD      index of accessibility to radial highways
- TAX      full-value property-tax rate per $10,000
- PTRATIO  pupil-teacher ratio by town
- B        1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town
- LSTAT    % lower status of the population
- MEDV     Median value of owner-occupied homes in $1000's

:Missing Attribute Values: None

从数据描述中可以看出,该数据共有506条数据样本,每条数据包括13项特征,没有缺失的属性/特征值(Missing Attribute Values),方便了进一步的分析。

代码实例

数据也了解了,下面我们将通过上述介绍的算法,对波士顿房价数据进行拟合和预测,下面直接上代码:

import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor, GradientBoostingRegressor

boston = datasets.load_boston()
# print(boston.DESCR)

X = boston.data
y = boston.target
# print(X.shape, y.shape)

#将X,y标准化,后面可以通过标准化器中的inverse_transform还原
ss_X = StandardScaler()
ss_y = StandardScaler()
X = ss_X.fit_transform(X)
y = ss_y.fit_transform(y.reshape(-1, 1)) #这里必须用reshape(-1,1)不然会报错
y = y.ravel()   #把y从一列变为一行,不然下面会报错

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2)

#创建一个Series对象用于储存不同回归模型的性能即R-Squared
r_squared = pd.Series()

#使用线性回归拟合数据并预测
lr = LinearRegression()
lr.fit(X_train, y_train)
y_lr_predict = lr.predict(X_test)
r_squared['linear Regression'] = lr.score(X_test, y_test)

#使用随机梯度下降回归拟合数据分类器
sgdr = SGDRegressor()
sgdr.fit(X_train, y_train)
y_sgdr_predict = sgdr.predict(X_test)
r_squared['SGD Regressor'] = sgdr.score(X_test, y_test)

#使用线性核函数配置的SVM进行回归训练
linear_svr = SVR(kernel='linear')
linear_svr.fit(X_train, y_train)
y_linear_svr_predict = linear_svr.predict(X_test)
r_squared['linear SVM'] = linear_svr.score(X_test, y_test)

#使用多项式核函数配置的SVM进行回归训练
poly_svr = SVR(kernel='poly')
poly_svr.fit(X_train, y_train)
y_poly_svr_predict = poly_svr.predict(X_train)
r_squared['Polynomial SVM'] = poly_svr.score(X_test, y_test)

#用径向基核函数配置的SVM进行回归训练
rbf_svr = SVR(kernel='rbf')
rbf_svr.fit(X_train, y_train)
y_rbf_svr_predict = rbf_svr.predict(X_test)
r_squared['RBF SVM'] = rbf_svr.score(X_test, y_test)

#使用KNN回归模型拟合数据,调整参数,使得预测方式为平均回归
uni_knr = KNeighborsRegressor(weights='uniform')
uni_knr.fit(X_train, y_train)
y_uni_knr_predict = uni_knr.predict(X_test)
r_squared['uniform weighted KNN'] = uni_knr.score(X_test, y_test)

#使用KNN回归模型拟合数据,调整参数,使得预测方式为根据距离加权回归
dis_knr = KNeighborsRegressor(weights='distance')
dis_knr.fit(X_train, y_train)
y_dis_knr_predict = dis_knr.predict(X_test)
r_squared['distance weighted KNN'] = dis_knr.score(X_test, y_test)

#用回归树模型拟合数据并预测
dtr = DecisionTreeRegressor()
dtr.fit(X_train, y_train)
y_dtr_predict = dtr.predict(X_test)
r_squared['Dicision Tree Regressor'] = dtr.score(X_test, y_test)

#使用集成模型——随机森林回归器拟合数据并预测
rfr = RandomForestRegressor()
rfr.fit(X_train, y_train)
y_rfr_predict = rfr.predict(X_test)
r_squared['Random Forest Regressor'] = rfr.score(X_test, y_test)

#使用集成模型——极端随机树(Extremely Randomized Trees)拟合数据并预测
etr = ExtraTreesRegressor()
etr.fit(X_train, y_train)
y_etr_predict = etr.predict(X_test)
r_squared['Extra Trees Rrgressor'] = etr.score(X_test, y_test)

#使用集成模型——梯度提升回归树拟合数据并预测
gbr = GradientBoostingRegressor()
gbr.fit(X_train, y_train)
y_gbr_predict = gbr.predict(X_test)
r_squared['Gradient Boosting Regressor'] = gbr.score(X_test, y_test)

#输出线性回归模型的性能,有以下三种评估方式,排序用的是R-Squared
print('R-Squared of Linear Regression:', lr.score(X_test, y_test))
print('Mean Squared Error of Linear Regression:', mean_squared_error(ss_y.inverse_transform(y_test), ss_y.inverse_transform(y_lr_predict)))
print('Mean Absolute Error of Linear Regression:', mean_absolute_error(ss_y.inverse_transform(y_test), ss_y.inverse_transform(y_lr_predict)))

#输出所有的回归模型的预测性能,并倒序排序
print('------------回归模型的R-Squared排序-------------')
print(r_squared.sort_values(ascending=False))

输出结果:

线性回归模型的性能,有以下三种评估方式:
R-Squared of Linear Regression: 0.7503116174489232
Mean Squared Error of Linear Regression: 22.160198304875518
Mean Absolute Error of Linear Regression: 3.241656596795042

------------回归模型的R-Squared排序-------------
Gradient Boosting Regressor    0.901122
Random Forest Regressor        0.869124
Extra Trees Rrgressor          0.863499
RBF SVM                        0.834929
Polynomial SVM                 0.796276
linear Regression              0.750312
SGD Regressor                  0.741797
linear SVM                     0.733410
distance weighted KNN          0.718520
Dicision Tree Regressor        0.704389
uniform weighted KNN           0.669170
dtype: float64

小结

从上述结果我们可以看出来,使用非线性回归树模型,特别是集成模型,能够取得更高的性能表现。

  • 线性回归器虽然简单易用,但是其对特征与回归的线性假设局限了其应用范围,特别是现实生活中绝大多数实例数据不能保证严格的线性关系。但尽管如此,在不清楚特征间关系的前提下,我们仍然可以使用线性回归模型作为大多数科学实验的基线系统(Baseline System)
  • 随机梯度下降法虽然性能比解析方法的线性回归要差,但是在面对数据规模十分庞大的任务时,随机梯度法不论面对回归还是分类表现都十分高效,在不损失过多性能的前提下,节省了大量的运算时间。因此如果数据规模大于10万,建议选择随机梯度法。
  • SVM在不同的核函数配置模型下性能表现不同,因此可以在实际使用中多尝试几种配置,进而获得更好的性能。
  • K近邻(回归)和K近邻(分类)一样,均属于无参数模型,没有参数训练过程,由于其模型计算方法非常直观,因此深受初学者喜爱。
  • 对于决策树和回归树来说,树模型的优点在于可以解决非线性特征问题,不要求特征标准化和统一量化,即数值和类别型特征都可以直接用于模型构建和预测;而其缺点在于,容易由于模型搭建过于复杂而过拟合导致泛化能力差,同时,由于树模型从上至下的预测流程会因为数据细微的更改而发生较大的结构变化,因此预测稳定性较差。
  • 集成模型往往在工业界被用作基准的性能表现,与新设计的其他模型性能进行比对。虽然集成模型在训练过程中要耗费更多的时间,但是往往可以提供更高的表现性能和更好的稳定性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: