多元回归求解 机器学习_机器学习:多元线性回归

一、多元线性回归基础

简单线性回归算法只有一个特征值(x),通常线性回归算法中有多个特征值,有的甚至有成千上万个特征值;

多元线性回归中有多种特征,每一种特征都与 y 呈线性关系,只是线性关系的系数不同;

多元线性回归的模型可以解决一元线性回归问题;

多元线性回归模型中,每一种特征都与值(也就是 y)呈线性关系,从 θ1 到 θn ,以此为第一个特征到第 n 个特征与值的线性关系系数,θ1 是第一个特征(X 中的第一列)的系数。

1)多元线性回归问题的解决思路

求解思路与简单线性回归的思路一样

yi = θ0 + θ1X1i + θ2X2i + θ3X3i + ... + θnXni:第 i 个样本对应的预测值;

X = array([X1, X2, X3, ..., Xm])T:数据集,m 个样本,m 行 n 列个数据;

Xi:数据集中的第 i 个向量,也是该数据集中的第 i 个样本;

Xi = array([x1, x2, x3,  ... , xn])

xn:每一行(一个样本)的一个元素(特征值)

多元回归求解 机器学习_机器学习:多元线性回归_第1张图片

多元回归求解 机器学习_机器学习:多元线性回归_第2张图片

2)多元线性回归的公式推导

A)原始公式

多元回归求解 机器学习_机器学习:多元线性回归_第3张图片

θ:参数向量,必须为列向量,才能与数据集矩阵X相乘:X*θ,得到的也是一个列向量

ý(i):模型的预测值

X(i):变形后的一个样本,也是变形后的数据集矩阵的第 i 行

X0(i):第 i 行的第0号元素;  #  原因:为了让计算式的每一项的格式统一,并且和θ0结合在一起,方便整个公式的推导,虚构为X(i)的第0个特征;

X0(i) ≡ 1:此元素恒等于1,变形后的公式与原公式一样

B)变形数据集矩阵

多元回归求解 机器学习_机器学习:多元线性回归_第4张图片

新的数据集矩阵:Xb,比原矩阵X多了一列:X0,全部为1

变形后的数学模型:ý = Xb * θ

ý为列向量,每一个元素(ý(i))为每一个样本X(i)讲过预测后得到的预测值

矩阵相乘有先后,不能写成θ * Xb

C)优化目标函数

多元回归求解 机器学习_机器学习:多元线性回归_第5张图片

数学推导(对矩阵求导(非本科学校内容)):得到θ的表达式

目标函数中的Xb:有X_test变形而来

预测时,Xb的列数(也就是特征种类)与θ中的元素个数相等

最终的参数表达式:

7f79a89202edc6eb075382599a71de7d.png

此公式为多元线性回归的正规方程解(Normal Equation)

公式缺点:时间复杂度高:O(n3),即使通过手段优化后:O(n2.4) ,效率低;

优点:不需要对数据做归一化处理;  # 因为数据集中的数据直接参数运算;

Xb:有X_train变形而来

(XbTXb)-1:其中 -1 表示矩阵的逆矩阵

逆矩阵:AB = BA = E,矩阵A、B均为方阵,E为单位矩阵

方阵:n x n 的矩阵;

单位矩阵:一个对角为1,E[0, 0] = E[1, 1] = E[2, 2] = ... = E[n, n] = 1,其余元素为0;

二、实现多元线性回归

多元回归求解 机器学习_机器学习:多元线性回归_第6张图片

θ中有 n + 1 个数值,实际样本中只有 n 个维度

θ0是截距(intercept),θ1 ~ θn是系数(coefficients)

一般对用户做汇报时,不是直接汇报θ,而是将θ分开为截距、系数两部分

分开汇报的原因:系数部分中的每一个θ值,都对应着原来样本中的一个特征,某种程度上,系数中的一个θ值可以用来描述特征对于最终样本的确定做的贡献程度,θ0和特征没有关系,只是一个偏移;

1)自己的算法实现

具体代码

importnumpy as npfrom sklearn.metrics importr2_scoreclassLinearRegression:def __init__(self):"""初始化Linear Regression模型"""

#coef_:截距

#interception:系数

#_theta:θ,为私有变量

#私有变量:变量名首字母为一个"_"

#私有函数:函数名首字母为两个"_"

self.coef_ =None

self.interception_=None

self._theta=Nonedeffit_normal(self, X_train, y_train):"""根据孙连数据集X_train, y_train训练Linear Regression模型"""

#fit的过程也是调参的过程,计算出参数θ,得到Linear Regression模型

assert X_train.shape[0] ==y_train.shape[0], \"the size of X_train must be equal to the size of y_train"

#np.ones((m, n)):创建一个m行n列的全部为1的矩阵;(m, n)必须为tuple格式

#np.hstack([array1, array2]):将两个矩阵在行的方向相加,增加列数,两个矩阵放在[]内

X_b = np.hstack([np.ones((len(X_train), 1)), X_train])

self._theta=np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

self.interception_=self._theta[0]

self.coef_= self._theta[1:]returnselfdefpredict(self, X_predict):"""给定待预测数据集X_predict, 返回表示X_predict的结果向量"""

assert self.interception_ is not None and self.coef_ is notNone, \"must fit before predict"

assert X_predict.shape[1] ==len(self.coef_), \"the feature number of X_predict must be equal to X_train"

#此处的X_b有预测数据集X_predict变形而来

X_b = np.hstack([np.ones((X_predict.shape[0], 1)), X_predict])returnX_b.dot(self._theta)defscore(self, X_test, y_test):"""根据训练数据集 X_test 和 y_test 确定当前模型的准确度"""y_predict=self.predict(X_test)returnr2_score(y_test, y_predict)def __repr__(self):return "LinearRegression()"

在Jupyter NoteBook中使用自己的代码

importnumpy as npimportmatplotlib.pyplot as pltfrom sklearn importdatasets

boston=datasets.load_boston()

X=boston.data

y=boston.target#取结果小于50的数据

X = X[y < 50.0]

y= y[y < 50.0]#1)分割原始数据

from ALG.data_split importtrain_test_split

X_train, X_test, y_train, y_test= train_test_split(X, y, seed=666)#2)导入-实例化-fit自己的算法

from LR.L_R importLinearRegression

reg=LinearRegression()

reg.fit_normal(X_train, y_train)#3)预测#得到准确度

reg.score(X_test, y_test)#输出:0.8129802602658466

2)调用scikit-learn中的算法

使用线性回归算法

#导入 - 实例化 - fit

from skleaen.linear_model importLinearRegression

lin_reg=LinearRegression()

lin_reg.fit(X_train, y_train)#查看截距

lin_reg.interception_#查看系数

in_reg.coef_#查看模型预测准确度

lin_reg.score(X_test, y_test)#输出:0.8129802602658476

使用kNN Regressor的算法KneighborsRegressor()

只使用默认参数k == 5

from sklearn.neighbors importKNeighborsRegressor

knn_reg=KNeighborsRegressor()

knn_reg.fit(X_train, y_train)

knn_reg.score(X_test, y_test)#输出:0.5865412198300899

对KNeighborsRegressor进行调参(网格搜索):

使用GridSearchCV下的best_score_参数,获取网格搜索后的模型的准确度

from sklearn.model_selection importGridSearchCV

param_grid=[

{"weights": ["uniform"],"n_neighbors": [i for i in range(1, 11)]

},

{"weights": ["distance"],"n_neighbors": [i for i in range(1, 11)],"p": [i for i in range(1, 6)]

}

]

knn_reg=KNeighborsRegressor()#grid_search是一个网格搜索(GridSearchCV)的对象,fit之后才会确认最佳模型及其参数

grid_search = GridSearchCV(knn_reg, param_grid, n_jobs=-1, verbose=1)

grid_search.fit(X_train, y_train)#查看最佳的取值结果

grid_search.best_params_#输出:{'n_neighbors': 5, 'p': 1, 'weights': 'distance'}

#使用GridSearchCV下的best_score_参数,获取网格搜索后的模型的准确度

grid_search.best_score_#输出:0.634093080186858

对kNeighborsRegressor进行调参(网格搜索):

调用最优模型的score()函数(也就是KNeighborsRegressor()算法的score()函数),获取足有算法模型的准确度

#获取网格搜索后的最优的KNeighborsRegressor()算法的模型

grid_search.best_estimator_#输出:KNeighborsRegressor(algorithm='auto', leaf_size=30, metric='minkowski',

metric_params=None, n_jobs=1, n_neighbors=5, p=1,

weights='distance')#调用最优模型的score()函数,获取足有算法模型的准确度grid_search.best_estimator_.score(X_test, y_test)#输出:0.7044357727037996

3)总结

获取原始数据

数据分割

数据归一化

导入、实例化算法

网格搜索:设置参数范围——实例化GridSearchCV()——fit

获取准确度:grid_search.best_score_、grid_search.best_estimator_.score(X_test, y_test); # grid_search,GridSearchCV()的实例对象

grid_search.best_score_:使用GridSearchCV()的best_score_参数,查看最佳模型的准确度;

grid_search.best_estimator_:返回最佳模型,也就是算法KNeighborsRegressor()的模型;

grid_search.best_estimator_.score(X_test, y_test):调用算法KNeighborsRegressor()的score()函数,获取最佳模型的准确度

scikit-learn中的LinearRegression算法与自己的算法得到的结果略有不同,因为scikit-learn中对原始数据集分割时,随机序列(对index乱序后分割)的生成上是不同的,导致生成的训练、测试数据集不同

kNN算法中,最佳模型和参数,是根据对比GridSearchCV()内部的逻辑运算(best_score_)所得到的准确度而确定的,不是kNN算法(KNeighborsClassifier()、KneighborsRegressor()等)中的score()函数;两种方式的内部逻辑是不同的;

使用机器学习算法解决问题时,会用不同的算法得到不同的准确度,比较算法优劣时,不能很武断的做判断,要细心考虑不同算法对准确度计算方式,因为同一个算法通过不同的方式可以得到不同的准确度:grid_search.best_score_、grid_search.best_estimator_.score(X_test, y_test),同一个算法模型,使用不同的方式得出的准确度不同。

你可能感兴趣的:(多元回归求解,机器学习)