Loading web-font TeX/Math/Italic

alex_bn_lee

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

【353】线性回归损失函数求导举例

参考:【351】实数对向量求导公式

参考:【352】矩阵转置性质

参考:机器学习实战教程(十一):线性回归基础篇之预测鲍鱼年龄

其他方法可参考 回归算法之线性回归

参考:通过一个例子快速上手矩阵求导


线性回归的损失函数如下:
Eb=(Xby)T(Xby)

将转置打开,像是开平方一样,运用到上面的性质:
Eb=(Xby)T(Xby)=((Xb)TyT)(Xby)=(bTXTyT)(Xby)=bTXTXbbTXTyyTXb+yTy

根据实数对向量求导的公式,对上面的实数分别对向量 b 求导。

bEb=b(bTXTXbbTXTyyTXb+yTy)=b(bTXTXb)b(bTXTy)b(yTXb)+b(yTy)=b(bT(XTX)b)b(bT(XTy))b((yTX)b)+0=(XTX+(XTX)T)bXTy(yTX)T=2XTXb2XTy=2XT(Xby)


Python 实现算法

通过 sklearn 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn import linear_model
 
x = [
    [100.0, 4.0],
    [50.0, 3.0],
    [100.0, 4.0],
    [100.0, 2.0],
    [50.0, 2.0],
    [80.0, 2.0],
    [75.0, 3.0],
    [65.0, 4.0],
    [90.0, 3.0],
    [90.0, 2.0]
]
 
y = [9.3, 4.8, 8.9, 6.5, 4.2, 6.2, 7.4, 6.0, 7.6, 6.1]
 
test_row = [50, 3]
sk = linear_model.LinearRegression()
sk.fit(x, y)
print(sk.coef_)
print(sk.intercept_)
print(sk.predict([test_row]))

[0.0611346 0.92342537]
-0.868701466781709
[4.95830457] 

1
2
3
x1, x2 = sk.coef_
print(x1)
print(x2)

0.06113459879206212
0.9234253666954272 

得到的模型为:y=0.87+0.06x1+0.92x2

参考:Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法

通过矩阵计算实现

参考:回归算法之线性回归

得到正规方程组:

说明:"$$" - 表示独占一行。
参考:在Jupyter Notebook里面写Python代码和数学公式

mb0+mi=1xi1b1+...+mi=1xinbn=mi=1yi


mi=1xi1b0+mi=1xi1xi1b1+...+mi=1xi1xinbn=mi=1xi1yi

...

mi=1xinb0+mi=1xinxi1b1+...+mi=1xinxinbn=mi=1xinyi

写成矩阵表示为:
XTXB=XTY


解得:
B=(XTX)1XTY

这一步的结果,与上面通过求偏导得到的结果一致,只需让导数为 0 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np
class MyLinearRegression(object):
    def __init__(self):
        # 添加属性,并且初始化,b 为列表
        self.b = []
        self.intercept_ = 0.0
        self.coef_ = []
         
    def fit(self, x:list, y:list):
        # 为每条训练数据前都添加 1,作为 b0 的系数
        point_num, future_num = np.shape(x)
        # 在原来 x 的维度基础上增加一列
        tmpx = np.ones(shape=(point_num, future_num + 1))
        # 将索引为 1 的列往后的部分赋值与 x 相同
        tmpx[:, 1:] = x
         
        # 矩阵 X
        x_mat = np.mat(tmpx)
        # 矩阵 y
        y_mat = np.mat(y).T
        # 获取矩阵 X 的转置矩阵 xT
        xT = x_mat.T
        # 直接按照公式计算
        self.b = (xT * x_mat).I * xT * y_mat
         
        # 从 b 中截取相应部分
        self.intercept_ = self.b[0]
        self.coef_ = self.b[1:]
         
    def predict(self, x):
        # [1] + x 表示将两个列表合并成一个连续的列表
        return np.mat([1] + x) * self.b

调用自定义的类:

1
2
3
4
5
linear = MyLinearRegression()
linear.fit(x,y)
print(linear.intercept_)
print(linear.coef_)
print(linear.predict(test_row))

[[-0.86870147]]
[[0.0611346 ]
[0.92342537]]
[[4.95830457]]

 

posted on   McDelfino  阅读(2937)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示