线性回归一般分为单变量线性回归和多变量线性回归。
线性回归的预测效果很高
一、单变量线性回归
对于单变量线性回归,我们要做的就是怎么样通过学习得到一个假设函数(h),从而能给出房子的估值??
①、假设函数的一般形式:
②、参数
③、代价函数:拟合参数的标准,这边为均方误差
④、求解代价函数为最小值时的参数
而解决最小化问题时,我们引入了 梯度下降算法。
梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。
∙ 梯度算法的思想:
开始时我们随机选择一个参数的组合(ø0,ø1,…,øn),计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。持续这样做直到找到一个局部最小值(Local Minimum),因为我们并没有尝试完所有的参数组合,所以并不能确定我们得到的局部最小值是不是全局最小值(Global Minimum),选择不同的初始参数组合,可能会找到不同的局部最小值。
∙ 梯度下降算法的公式表示:
其中α 为学习率,为正数,它表示我们沿着能让代价函数下降程度最大的方向迈出的步子有多大。若α 过小的话,我们达到最优解的计算开销会很大,若α 很大的话,代价函数会无法收敛甚至发散。虽然步长是固定的,但是当逼近一个(局部)最小值时,导数会变小,所以更新也会变小,因而梯度下降法在靠近极值点时会自动将“步子”迈小一点。
根据导数的正负性,来判断取得最小值的点在哪个方向
∙ 梯度下降算法的流程:
直至参数不变,即找到导数为0的点
其中两个参数必须是同步更新的,否则会导致参数错位导致计算错误,偏导数项为:
二、多元线性回归
解决该问题的方法和单变量线性回归类似
①、多元线性回归的假设函数:
也可以写成:
需要注意的是:其中x0 = 1.
②、参数:
③、代价函数:拟合参数的标准,这边为均方误差
④、利用梯度下降算法求解代价函数取最小值时的参数
2.1 利用梯度下降算法求解参数θ
多元梯度下降算法公式:
求解小技巧1: 特征缩放
若特征值之间的数据量级相差过大,可以除以或者乘以该特征中的最大特征值来平衡各个特征之间的量级差距。可以减少迭代的次数
也可以标准化:
其中μ为该特征中特征值的平均数,s可以是极差或者标准差
求解小技巧2:绘制迭代次数–J( θ)曲线来监测算法的运行情况
如果曲线为:
通常是因为我们的α取的过大。
通常我们绘制一系列的α值版本的迭代次数–J(θ)曲线来选取合适的α值
α通常取0.003、0.03、0.3等
求解小技巧三:特征处理和多项式回归:
有时候我们可以创建新的合适的特征来获取不同的模型
而我们也不必只用直线来拟合数据,通常会使用多项式的拟合效果更好
2.2 利用正规方程求解参数 θ
该方法不用特征缩放
对于该样本集的求解步骤:
①、构造设计矩阵X
添加新的一列x0,全为0.
则X,y为
②、带入正规方程
正规方程:
将X,y带入方程求得θ向量组。
2.3 正规方程和梯度下降比较
三、简单应用
3.1 比较线性模型和KNN模型在糖尿病数据集上的拟合效果
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
# 导入糖尿病数据集包,并实例化它
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
# 构造训练集和标签
x = diabetes.data
y = diabetes.target
# 消除数据的量纲
from sklearn.preprocessing import MinMaxScaler,StandardScaler
ss = StandardScaler()
ss_y = ss.fit_transform(y.reshape(-1,1))
# 创建线性模型对象
from sklearn.linear_model import LinearRegression
liner = LinearRegression()
from sklearn.metrics import mean_absolute_error,mean_squared_error
from sklearn.model_selection import train_test_split
# 封装计算泛化误差和经验误差的函数
def cal_score(model,X,y,count,test_size):
train_mse_list = []
test_mse_list = []
for i in range(count):
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=test_size,random_state=i)
model.fit(X_train,y_train)
train_mse_list.append(mean_squared_error(y_train,model.predict(X_train)))
test_mse_list.append(mean_squared_error(y_test,model.predict(X_test)))
return np.array(test_mse_list).mean(),np.array(train_mse_list).mean()
# 求线性模型误差
from sklearn.linear_model import LinearRegression
liner = LinearRegression()
liner_test_mse,liner_train_mse = cal_score(liner,X,ss_y,10,0.2)
display(liner_test_mse,liner_train_mse)
# 求KNN模型的误差
from sklearn.neighbors import KNeighborsRegressor
# 生成k值序列
k_list = np.arange(1,60,step=2)
k_train_mse = []
k_test_mse = []
for k in k_list:
knn = KNeighborsRegressor(n_neighbors=k)
train_scores,test_scores = cal_score(knn,X,ss_y,10,test_size=0.2)
k_train_mse.append(train_scores)
k_test_mse.append(test_scores)
# 绘制K-误差图像
plt.plot(k_list,k_train_mse,label='train',color='red')
plt.plot(k_list,k_test_mse,label='test',color='black')
plt.legend()
由图知,最佳K值大概在50.
再求解K=50时KNN模型的经验误差和泛化误差 和线性模型比较
选择最优模型的规则
1 .经验误差和泛华误差接近且更小
2.经验误差和泛华误差的标准方差更小,则更稳定
消除数据的量纲
1.标准化 Z-score StandardScaler
2 .区间缩放 MinMaxScaler
3. 归一化 Normalized
好处:减少算法迭代次数、降噪
四、通过正规方程,代码实现线性回归模型
class LinearModel(object):
def __init__(self):
# 用于存储斜率 就是系数
self.wg = None
self.xshape = None
def fit(self, X, y):
self.xshape = X.shape
xMat = np.mat(X)
yMat = np.mat(y).T
xTx = xMat.T * xMat
# 判断样本集是否可逆
if np.linalg.det(xTx) == 0:
print("Matrix inverse Error")
return
wg = xTx.I * xMat.T * yMat
self.wg = wg
def predict(self, X):
if self.xshape[1] != X.shape[1]:
print("ndim error")
return
xMat = np.mat(X)
# 点乘运算
return xMat * self.wg