线性回归算法

线性回归是用一条直线(或多维里的一个平面)拟合「输入和输出」的关系。先把模型怎么学写清楚,再用一段可运行的 Python 把拟合结果算出来。

线性回归用一条直线描述一个输入和一个输出的关系。给定若干对 (x, y),它要找出权重 w 和偏置 b,使预测值尽量贴近真实值:

y_hat = w * x + b

多个输入时,每个特征各有一个权重:

y_hat = w1 * x1 + w2 * x2 + ... + b

「尽量贴近」用均方误差衡量。对 n 个样本,损失是预测误差平方的平均:

loss = (1 / n) * Σ (y_hat - y)²

损失越小,直线越贴合这些点。求这条直线有两种做法。样本不多时可以直接用正规方程一次算出 w 和 b。样本很多、特征很多时,用梯度下降:先随便取一组 w、b,沿损失下降的方向小步更新,重复多次。一元时每一步是:

dw = (2 / n) * Σ (y_hat - y) * x

db = (2 / n) * Σ (y_hat - y)

w = w - learning_rate * dw

b = b - learning_rate * db

下面用 8 个点拟合 y ≈ x + 1,只依赖 Python 标准库。learning_rate 是步长,epochs 是重复次数。

xs = 1, 2, 3, 4, 5, 6, 7, 8

ys = 2.1, 2.9, 4.2, 5.1, 5.8, 7.2, 8.1, 8.9

n = len(xs)

w, b = 0.0, 0.0

learning_rate = 0.01

epochs = 2000

for epoch in range(1, epochs + 1):

dw = db = loss = 0.0

for x, y in zip(xs, ys):

y_hat = w * x + b

err = y_hat - y

dw += err * x

db += err

loss += err * err

dw = (2 / n) * dw

db = (2 / n) * db

loss /= n

w -= learning_rate * dw

b -= learning_rate * db

if epoch in (1, 100, 500, 2000):

print(f"epoch={epoch} loss={loss:.4f} w={w:.4f} b={b:.4f}")

def predict(x):

return w * x + b

for x in (2, 5, 9):

print(x, round(predict(x), 2))

跑完后,损失从 35.85 降到 0.0195,参数停在 w = 0.9917、b = 1.0747。代入新的 x:

x 预测 y
2 3.06
5 6.03
9 10.00

同一批数据用正规方程得到 w = 0.9917、b = 1.0750,和梯度下降几乎重合。决定系数 R² 是 0.9962,表示这些点的波动几乎都能被这条直线解释。

看结果时先看损失是否还在下降。损失震荡或变成 inf,把 learning_rate 调小,例如改成 0.001。损失下降很慢,就加长 epochs,或把步长略调大。R² 接近 1 只说明直线贴合了这批样本;用没参与训练的数据再预测一次,才能看出能不能用到新数据上

相关推荐
Coder-magician1 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil2081 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b2 小时前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
别动我齐刘海2 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
青少儿编程课堂3 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
不会就选b3 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展
没有钱的钱仔4 小时前
协方差矩阵含义
算法·机器学习·矩阵
垆边人似月.4 小时前
华为机试题 :和为 K 的子数组个数
算法·leetcode·华为