动手实现linear Regression

算法思想

线性回归的目标是通过对训练样本的学习,得到从样本特征到样本标签之间的映射,可以类比logistic regression的思路,但不同的是,逻辑回归是一种分类算法,其样本标签是离散值,而线性回归处理的是回归问题,其样本标签是连续值,比如本篇博客要用到的sklearn中的波士顿房价的数据,其对应的房价标签是一系列连续值。

对于线性回归,其目的就是要找到这样的一个映射关系,W是需要训练的回归系数,其中w0为偏置项:
这里写图片描述

对于真实的样本标签y,通过上述映射求出的预测值y_hat,其误差为
这里写图片描述
但由于上述绝对值函数并非处处可导,所以一般地要使用平方损失作为线性回归模型的损失函数,即:
这里写图片描述
其中y_hat=WX,二分之一系数是为了求偏导的时候和指数2约掉,方便计算,接下来要做的事情就是要找到对应的W,使得损失函数达到最小。


求权重W

1.最小二乘法
对于线性回归的损失函数,我们可以写成矩阵的表达形式,即:
这里写图片描述
然后对W求导,得
这里写图片描述
这样就得出W的正规方程解,其中X,Y都是已知的

2.梯度下降法
与逻辑回归类似,线性回归也可以用梯度下降法优化W,一般地将优化函数设为
这里写图片描述
对应的梯度用向量化表示为:
这里写图片描述
注意个矩阵的维度!
这样我们就可以通过梯度下降法,不断迭代,求出使得损失函数达到最小值时的W
思路可以参考这篇博客


关键代码

1.最小二乘法
对照最小二乘法的正规方程解,我们可以很容易得写出求解weight的函数

# 最小二乘法
def least_square(data, y):

    X = np.hstack([np.ones((len(data), 1)), data])
    weight = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)

    return weight
# 预测
def predict(weight, X_predict):
    X = np.hstack([np.ones((len(X_predict), 1)), X_predict])

    return X.dot(weight)

MSE,RMSE,MAE,R Squared对应四种线性回归衡量指标:
MSE(均方误差):
这里写图片描述
RMSE(均方根误差):
这里写图片描述
MAE(平均绝对误差):
这里写图片描述
MSE,RMSE,MAE越小,误差也越小,准确度更高
R Squared(R^2):
这里写图片描述
其中:R^2<=1,R^2越大模型表现越优

# MSE
def mean_squared_error(y, y_predict):

    return np.sum((y - y_predict) ** 2) / len(y)

# RMSE
def root_mean_squared_error(y, y_predict):

    return sqrt(mean_squared_error(y, y_predict))

# MAE
def mean_absolute_error(y, y_predict):

    return np.sum(np.absolute(y - y_predict)) / len(y)

# R Squared
def r_square_score(y, y_predict):

    return 1 - mean_squared_error(y, y_predict) / np.var(y)

def score(weight, X_predict, y):

    y_predict = predict(weight, X_predict)

    return r_square_score(y, y_predict)

这里写图片描述

2.梯度下降法

def error_rate(weight, X, y):
    # X(nx3) weight(3x1)
    return X.T.dot(X.dot(weight) - y) / len(y)

def gradAscent(data, y):  # 梯度下降求最优参数
    alpha = 0.01  # 步长
    maxCycles = 1000  # 设置迭代的次数
    X = np.hstack([np.ones((len(data), 1)), data])
    weights = np.ones(X.shape[1])  # 设置初始的参数,并都赋默认值为1
    for k in range(maxCycles):
        error = error_rate(weights, X, y)
        weights = weights - alpha * error  # 迭代更新权重

    return weights

运行代码会出现溢出的问题,是因为数据不在一个量纲,对数据进行归一化即可解决:
这里写图片描述

X_train_standard = standardScaler.transform(X_train)
X_test_standard = standardScaler.transform(X_test)

这里写图片描述

这是随机梯度下降法的结果,随机梯度下降法请参见

这里写图片描述


总结

对于线性回归,最小二乘法求解权重虽说简单直观,一个公式即可解决,但是它需要是矩阵间的运算,在高维度的矩阵中随之带来的是相当高的计算复杂度(O(n^3)),所以当数据维数非常庞大的时候,梯度下降法会是个不错的选择,当然若要求更高的预测准确率,随机梯度下降法也是可以使用的。

猜你喜欢

转载自blog.csdn.net/Joker_sir5/article/details/82693495
今日推荐