一.数据集的介绍
波士顿房价数据集是统计的20世纪70年代中期波士顿郊区房价的中位数,统计了当时教区部分的犯罪率、房产税等共计13个指标,统计出房价,试图能找到那些指标与房价的关系。本例子明显的是属于回归模型的案例。在数据集中包含506组数据,其中404是训练样本,剩下的102组数据作为验证样本。使用sklearn.datasets.load_boston即可加载相关数据。该数据集是一个回归问题。每条数据包含房屋以及房屋周围的详细信息。其中包含城镇犯罪率,一氧化碳浓度,住宅平均房间数,到中心区域的加权距离以及自住房平均房价等等。
CRM 城镇人均犯罪率
ZN 住宅用地所占比例,25000英尺
INDUS 城镇中非商业用地所占的比例
CHAS 查理斯河空变量(如果是河流边界,则为1,否则为0)
NOX 一氧化碳浓度
RM 住宅平均房间数
AGE 1940前建成的自用房屋比例
DIS 到波士顿5个中心区域的加权距离
RAD 辐射性公路的接近指数
TAX 每10000美元的全值财产税率
PTRATIO 城镇师生比例
B 城镇中黑人比例
LSTAT 人口中地位低下者的比例
MEDV 自助房的平均房价,以千美元记
表1:波士顿房价数据集缩写所代表的含义
二.回归问题的定义
回归问题也属于监督学习中的一类。回归用于预测输入变量和输出变量之间的关系,特别是当输入变量的值发生变化时,输出变量随之发生的变化。回归模型正是表示输入变量到输出变量之间的映射的函数。特别的当因变量与自变量。
回归问题按照输入变量的个数,可以分为一元回归和多元回归;按照输入变量与输出变量之间的关系可以分为线性回归和非线性回归。
图1:回归模型
2.1回归分析的步骤
1.根据预测目标,确定自变量和因变量。
2.建立回归预测模型。
3.进行相关分析。
4.检测回归预测模型,计算预测误差。
5.计算并确定预算误差
三.七种机器学习回归算法
3.1线性回归
线性回归(Linear Regression)是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。
线性回归利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量关系之间进行建模。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为一元回归也叫简单回归,大于一个自变量的情况叫做多元回归。
3.1.1线性回归的实际用途
1.如果目标是预测或者映射,线性回归可以用来对观测数据集的y和X的值拟合出一个预测模型。当完成这样一个模型以后,对于一个新增的X的值,在没有给定与它想配对的y的情况下,可以用这个拟合过的模型预测出一个y值。
2.给定一个变量y和一些变量X1,…,Xp,这些变量有可能与y相关,线性回归分必须可以用来量化y与Xj之间相关性的强度,评估出与y不相关的Xj,并识别出哪些Xj的子集包含了关于y的冗余信息。
3.2岭回归
对于有些矩阵,矩阵中某个元素的一个很小的变动,会引起最后计算结果误差很大,这种矩阵称为“病态矩阵”。有些时候不正确的计算方法也会使一个正常的矩阵在运算中表现出病态。对于高斯消去法来说,如果主元(即对角线上的元素)上的元素很小,在计算时就会表现出病态的特征。岭回归(Ridge Regression)是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价获得回归系数更为符合实际、更可靠的回归方法,对病态数据的拟合要强于最小二乘法。
3.2.1特点:
岭回归是对最小二乘回归的一种补充,它损失了无偏性,来换取高的数值稳定性,从而得到较高的计算精度。通常岭回归方程的R平方值会稍低于普通回归分析,但回归系数的显著性往往明显高于普通回归,在存在共线性问题和病态数据偏多的研究中有较大的实用价值。它没有忽略异常值得影响,而是给了他们较小的权重。
3.3鲁棒回归
鲁棒回归(Huber Regression)的目的是在存在异常值或模型错误的情况下拟合回归模型。同岭回归不同,它将线性损失应用于分类和异常值的样本。如果样本的绝对误差小于某一阈值,则该样本被划分为离群值。鲁棒回归没有忽略异常值的影响,而是给异常值赋予更低的权重。
3.4支持向量回归
SVR全称是support vector regression,是SVM(支持向量机support vector machine)对回归问题的一种运用。对于图2一个数据集,有两类分别使用×和○来表示。那么我们想要找到一条曲线来区分这两类。可想而知,这样的曲线存在无数条,如何找到那一条最优的曲线呢?那就是要找到间隔(Gap)最大的那一条曲线,然后我们就可以根据这条曲线来分类了。而这条曲线,我们称为超平面。图中加粗的×与○,我们则称这些向量为支持向量。
图2
使用SVR作回归分析,与SVM一样,我们需要找到一个超平面,不同的是:在SVM中我们要找出一个间隔(gap)最大的超平面,而在SVR,我们定义一个ε,如上图所示,定义虚线内区域的数据点的残差为0,而虚线区域外的数据点(支持向量)到虚线的边界的距离为残差(ζ)。与线性模型类似,我们希望这些残差(ζ)最小。所以大致上来说,SVR就是要找出一个最佳的条状区域(2ε宽度),再对区域外的点进行回归。对于非线性的模型,使用核函数(kernel function)映射到特征空间,然后再进行回归。
3.5最近邻回归
K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。
3.5.1 优点
1.简单,易于实现,无需参数,无需训练
2.适合对稀有事件进行分类
3.特别适合于多分类问题,kNN比SVM表现好
3.5.2缺点
当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。另一个不足之处是计算量较大,因为要对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。
3.6决策树回归
决策树模型是运用于分类以及回归的一种树结构。决策树由节点和有向边组成,一般一棵决策树包含一个根节点、若干内部节点和若干叶节点。决策树的决策过程需要从决策树的根节点开始,待测数据与决策树中的特征节点进行比较,并按照比较结果选择选择下一比较分支,直到叶子节点作为最终的决策结果。
·内部节点:对应于一个属性测试
·叶节点:对应于决策结果
·根节点包含样本全集;
·每个节点包括的样本集合根据属性测试的结果被划分到子节点中;
·根节点到每个叶节点的路径对应对应了一个判定测试路径;
3.6.1决策树学习算法
·特征选择
·决策树生成
·决策树减枝
3.7 神经网络回归
神经网络回归是一种非参数非线性方法,结合了神经网络和回归方面的优势。不仅可以揭示响应变量的整个条件分布,还可以模拟金融系统的非线性特征。
在图3中,x表示输入,即从网络前一层向前传递而来的特征。许多个x将被输入最后一个隐藏层的各个节点,每个x都会与一个相应的权重w相乘。节点中的所有乘积之和再与一项偏差相加,结果输入某种激活函数。此处的激活函数是一个修正线性单元(ReLU),ReLU很常用也很有用,因为它不会像sigmoid激活函数发生那样饱和区梯度过于平缓的问题。ReLU会输出每个隐藏节点对应的激活值a,所有激活值之和再进入输出节点并直接通过该节点。用于进行回归的神经网络有一个输出节点,而该节点只会将前一层的激活值之和乘以1。所得结果为ŷ,这是网络的预测结果,也是所有x映射至的应变量。
图3
四.实验分析
4.1实验设计
4.1.1导入数据
sklearn 中已经内置了波士顿房价数据集,我们可通过调用sklearn的包来获取波士顿房价数据集。
4.1.2数据可视化
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
import sklearn.datasets as datasets
#机器算法模型
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import HuberRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.svm import SVR
from sklearn.metrics import explained_variance_score
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from sklearn.metrics import median_absolute_error
#切割训练数据和样本数据
from sklearn.model_selection import train_test_split
#用于模型评分
from sklearn.metrics import r2_score
boston = datasets.load_boston()
train = boston.data
target = boston.target
#切割数据样本集合测试集
X_train,x_test,y_train,y_true = train_test_split(train,target,test_size=0.1)
knn = KNeighborsRegressor()
linear = LinearRegression()
ridge = Ridge()
huber=HuberRegressor()
decision = DecisionTreeRegressor()
svr = SVR()
knn.fit(X_train,y_train)
linear.fit(X_train,y_train)
ridge.fit(X_train,y_train)
huber.fit(X_train,y_train)
decision.fit(X_train,y_train)
svr.fit(X_train,y_train)
y_pre_knn = knn.predict(x_test)
y_pre_linear = linear.predict(x_test)
y_pre_ridge = ridge.predict(x_test)
y_pre_huber=huber.predict(x_test)
y_pre_decision = decision.predict(x_test)
y_pre_svr = svr.predict(x_test)
knn_score = r2_score(y_true,y_pre_knn)
linear_score=r2_score(y_true,y_pre_linear)
ridge_score=r2_score(y_true,y_pre_ridge)
huber_score=r2_score(y_true,y_pre_huber)
decision_score=r2_score(y_true,y_pre_decision)
svr_score=r2_score(y_true,y_pre_svr)
clf_score=r2_score(y_true,y_pre_clf)
display(knn_score,linear_score,ridge_score,lasso_score,decision_score,svr_score,clf_score)
#解释方差
linear_EV=explained_variance_score(y_true, y_pre_linear)
knn_EV=explained_variance_score(y_true, y_pre_knn)
ridge_EV=explained_variance_score(y_true, y_pre_ridge)
huber_EV=explained_variance_score(y_true, y_pre_huber)
decision_EV=explained_variance_score(y_true, y_pre_decision)
svr_EV=explained_variance_score(y_true, y_pre_svr)
linear_MAE=mean_absolute_error(y_true, y_pre_linear)
knn_MAE=mean_absolute_error(y_true, y_pre_knn)
ridge_MAE=mean_absolute_error(y_true, y_pre_ridge)
huber_MAE=mean_absolute_error(y_true, y_pre_huber)
decision_MAE=mean_absolute_error(y_true, y_pre_decision)
svr_MAE=mean_absolute_error(y_true, y_pre_svr)
linear_medAE=median_absolute_error(y_true, y_pre_linear)
knn_medAE=median_absolute_error(y_true, y_pre_knn)
ridge_medAE=median_absolute_error(y_true, y_pre_ridge)
huber_medAE=median_absolute_error(y_true, y_pre_huber)
decision_medAE=median_absolute_error(y_true, y_pre_decision)
svr_medAE=median_absolute_error(y_true, y_pre_svr)
linear_MSE=mean_squared_error(y_true, y_pre_linear)
knn_MSE=mean_squared_error(y_true, y_pre_knn)
ridge_MSE=mean_squared_error(y_true, y_pre_ridge)
huber_MSE=mean_squared_error(y_true, y_pre_huber)
decision_MSE=mean_squared_error(y_true, y_pre_decision)
svr_MSE=mean_squared_error(y_true, y_pre_svr)
print(“Linear解释方差:”,linear_EV)
print(“Linear平均绝对误差差:”,linear_MAE)
print(“Linear平均平方误差:”,linear_medAE)
print(“Linear中位绝对误差:”,linear_MSE)
print(“knn解释方差:”,knn_EV)
print(“knn平均绝对误差差:”,knn_MAE)
print(“knn平均平方误差:”,knn_medAE)
print(“knn中位绝对误差:”,knn_MSE)
print(“ridge解释方差:”,ridge_EV)
print(“ridge平均绝对误差差:”,ridge_MAE)
print(“ridge平均平方误差:”,ridge_medAE)
print(“ridge中位绝对误差:”,ridge_MSE)
print(“huber解释方差:”,huber_EV)
print(“huber平均绝对误差差:”,huber_MAE)
print(“huber平均平方误差:”,huber_medAE)
print(“huber中位绝对误差:”,huber_MSE)
print(“decison解释方差:”,decision_EV)
print(“decison平均绝对误差差:”,decision_MAE)
print(“decison平均平方误差:”,decision_medAE)
print(“decison中位绝对误差:”,decision_MSE)
print(“svr解释方差:”,svr_EV)
print(“svr平均绝对误差差:”,svr_MAE)
print(“svr平均平方误差:”,svr_medAE)
print(“svr中位绝对误差:”,svr_MSE)
from sklearn.neural_network import MLPRegressor
from sklearn import preprocessing
#神经网络数据格式化
ss_x = preprocessing.StandardScaler()
train_x_disorder = ss_x.fit_transform(X_train)
test_x_disorder = ss_x.transform(x_test)
ss_y = preprocessing.StandardScaler()
train_y_disorder = ss_y.fit_transform(y_train.reshape(-1, 1))
test_y_disorder=ss_y.transform(y_true.reshape(-1, 1))
clf = MLPRegressor(solver=‘lbfgs’, hidden_layer_sizes=(20, 20, 20), random_state=1)
#数据训练
clf.fit(train_x_disorder,train_y_disorder.ravel())
y_pre_clf = clf.predict(x_test)
print(“Netural Network”)
print(“MSE均方误差:”,mean_squared_error(y_true,y_pre_clf))
print(“MAE平均绝对误差:”,mean_absolute_error(y_true,y_pre_clf))
print(“MedAE中位绝对误差:”,median_absolute_error(y_true,y_pre_clf))
print(“EV解释误差:”,explained_variance_score(y_true,y_pre_clf))
plt.plot(y_true,label=‘true’)
plt.plot(y_pre_clf,label=‘Netural Network’)
plt.legend()
plt.show()