机器学习之线性回归(Linear regression)学习笔记-Datawhale Task01

AuthorBryce230
e-mail2540892461@qq.com
Softwarewin10,Pycharm2019.3.3,Python3.7.7

线性回归

LR
线性回归分为单变量线性回归和多变量线性回归,一般来说,多变量线性回归在实践中比较常见。对于什么是线性回归,最直观的理解就是,坐标系里有一些散点,而这些散点分布在一条直线附近,可以说这条直线就是这些散点的回归直线,如上图所示。当然,这样的说法不够严谨,但理解起来方便。形式如下,默认 x 0 x_0 x0=1。
在这里插入图片描述

梯度下降

如何度量回归的好坏呢?需要引入平方误差,我们也称为代价函数(cost function),即:
代价函数
有时代价函数中的 1 2 m {1\over2m} 2m1可改为 1 2 {1\over2} 21。我们的目的也就是找到使代价函数最小的一组 θ \theta θ值。我们引入梯度下降算法:
在这里插入图片描述

在这里插入图片描述
求导后得到:
在这里插入图片描述注:上标表示第i个数据点,下标j表示第j个特征。

特征缩放

为什么要进行特征缩放?
如果两个特征的值不在一个数量级,一个10以内,一个上千,那么绘制出的代价函数等高线图看起来很扁,这会导致梯度下降算法需要迭代很多次才能收敛,浪费计算成本。所以我们最好是把它控制在-1到1之内。最简单的方法是令: x n = x n − μ n s n x_n = {x_n-\mu_n\over s_n} xn=snxnμn,其中, μ n \mu_n μn是平均值, s n s_n sn是标准差。
在这里插入图片描述

学习率

梯度算子总是指向函数值减小最快的方向。那么每次移动多少呢?这里就涉及到参数 α \alpha α,该值称为步长,也叫学习率。梯度下降算法的每次迭代受到学习率 α \alpha α的影响,如果学习率过小,则达到收敛所需的迭代次数会非常高;如果学习率过大,每次迭代可能不会减小代价函数,可能会越过局部最小值导致无法收敛。
在这里插入图片描述
学习率 α \alpha α一般取:0.01, 0.03, 0.1, 0.3, 1, 3, 10

梯度上升

梯度下降法比较常见,当然也有梯度上升法,算法是一样的,不过要把公式里的减法( α \alpha α前的负号)变为加法。
梯度上升算法用来求函数的最大值,而梯度下降算法用来求函数的最小值。

正规方程

我们是求代价函数最小的一组 θ \theta θ值,那么可以考虑求导法,令对 θ \theta θ的偏导等于0,求解出 θ \theta θ的值即可。我们的得到的结果是:
在这里插入图片描述
在这里插入图片描述
具体推导过程可以参考吴恩达的机器学习视频课程。

评估指标

在这里插入图片描述
在python中,Numpy库提供了相关系数的计算方法:可以通过命令corrcoef(yEstimate, yActual)来计算预测值与真实值的相关性。越接近于1,表示越相关。

print(np.corrcoef(yHat.T, yMat))

比如结果为:

[[1.         0.98647356]
 [0.98647356 1.        ]]

其中1表示自己与自己的匹配,而0.98则是真实值与预测值的相关系数。

代码实现

1)利用sklearn库求解和正规方程求解:

"""线性回归"""
#生成数据
import numpy as np
from sklearn.linear_model import LinearRegression


np.random.seed(1234) #随机数种子,产生一样的随机数
x = np.random.rand(500,3)#生成500*3的数组,如果是单个数字,则为行向量
#构建映射关系,模拟真实的数据待预测值,映射关系为y = 4.2 + 5.7*x1 + 10.8*x2
y = x.dot(np.array([4.2, 5.7, 10.8]))


# 调用模型
lr = LinearRegression(fit_intercept=True)
# 训练模型
lr.fit(x,y)
print("估计的参数值为:%s" %(lr.coef_))
# 计算R平方
print("R2:%s" %(lr.score(x,y)))
# 任意设定变量,预测目标值
x_test = np.array([2, 4, 5]).reshape(1, -1) #这里的-1被理解为unspecified value
y_hat = lr.predict(x_test)
print("预测值为:%s" %(y_hat))

class LR_LS():
    def __init__(self):
        self.w = None
    def fit(self, X, y):
        # 最小二乘法矩阵求解
        self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y) #dot表示矩阵乘法
    def predict(self, X):
        # 用已经拟合的参数值预测新自变量
        y_pred = X.dot(self.w)
        return y_pred

if __name__ == "__main__":
    lr_ls = LR_LS()  #实例化
    lr_ls.fit(x,y)
    print("估计的参数值:%s" %(lr_ls.w))
    x_test = np.array([2,4,5]).reshape(1,-1)
    print("预测值为: %s" %(lr_ls.predict(x_test)))

运行结果如下,两者结果吻合:

估计的参数值为:[ 4.2  5.7 10.8]
R2:1.0
预测值为:[85.2]
估计的参数值:[ 4.2  5.7 10.8]
预测值为: [85.2]

2)利用sklearn库求解和梯度下降算法:

"""线性回归"""
#生成数据
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt


np.random.seed(1234) #随机数种子,产生一样的随机数
x = np.random.rand(500,3)#生成500*3的数组,如果是单个数字,则为行向量
#构建映射关系,模拟真实的数据待预测值,映射关系为y = 4.2 + 5.7*x1 + 10.8*x2
y = x.dot(np.array([4.2, 5.7, 10.8]))

# 调用模型
lr = LinearRegression(fit_intercept=True)
# 训练模型
lr.fit(x,y)
print("估计的参数值为:%s" %(lr.coef_))
# 计算R平方
print("R2:%s" %(lr.score(x,y)))
# 任意设定变量,预测目标值
x_test = np.array([2, 4, 5]).reshape(1, -1) #这里的-1被理解为unspecified value
y_hat = lr.predict(x_test)
print("预测值为:%s" %(y_hat))

class LR_GD():
    def __init__(self):
        self.w = None
    def fit(self,X,y,alpha=0.02,loss = 1e-12): # 设定步长为0.002,判断是否收敛的条件为1e-12
        y = y.reshape(-1,1) #重塑y值的维度以便矩阵运算,整理成1列
        [m,d] = np.shape(X) #自变量的维度
        self.w = np.zeros((d)) #将参数的初始值定为0
        tol = 1e5
        while tol > loss:
            h_f = X.dot(self.w).reshape(-1,1)
            theta = self.w + alpha*np.mean((y - h_f)*X,axis=0) #计算迭代的参数值,axis=0 表示压缩成一行
            tol = np.sum(np.abs(theta - self.w))
            self.w = theta
    def predict(self, X):
        # 用已经拟合的参数值预测新自变量
        y_pred = X.dot(self.w)
        return y_pred

if __name__ == "__main__":
    lr_gd = LR_GD()
    lr_gd.fit(x,y)
    print("估计的参数值为:%s" %(lr_gd.w))
    x_test = np.array([2,4,5]).reshape(1,-1)
    print("预测值为:%s" %(lr_gd.predict(x_test)))

收敛的条件为1e-12,可以获得更精确的结果,如果小于1e-12,可获得近似结果,如下:

估计的参数值为:[ 4.2  5.7 10.8]
R2:1.0
预测值为:[85.2]
估计的参数值为:[ 4.2  5.7 10.8]
预测值为:[85.2]

3)梯度上升算法实现:

# 函数说明:梯度上升算法
def gradAscent(dataMatIn, classLabels):
    dataMatrix = np.mat(dataMatIn)                                  #转换成numpy的mat
    labelMat = np.mat(classLabels).transpose()                      #转换成numpy的mat,并进行转置
    m, n = np.shape(dataMatrix)                                     #返回dataMatrix的大小。m为行数,n为列数。
    alpha = 0.001                                                   #移动步长,也就是学习速率,控制更新的幅度。
    maxCycles = 500                                                 #最大迭代次数
    weights = np.ones((n,1))
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * weights)                           #梯度上升矢量化公式
        error = labelMat - h
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights.getA()                                           #将矩阵转换为数组,返回权重数组

参考资料

[1] Datawhale: Task1 Linear_regression.ipynb
[2] 吴恩达 CS229课程
[3] 《机器学习实战》[美] Peter

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值