共计 2082 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点:新手常踩的 3 个坑
刚接触线性回归时,我遇到了不少问题,后来发现很多新手都会犯类似的错误。这里总结三个最常见的坑:

- 梯度下降不收敛:学习率设得太大导致震荡,或者太小导致收敛过慢
- 特征处理不当:没做归一化导致某些特征权重过大,或者忽略了线性对数转换
- 代码实现混乱:把数据预处理、模型训练和评估的代码混在一起,难以调试
技术实现:分步拆解线性回归
1. 数据预处理
首先我们需要准备数据。假设我们有一组房价数据,特征是面积,目标是价格。
- 加载数据并分割为特征 X 和目标 y
- 对特征做标准化:(X – mean)/std
- 添加偏置项(全 1 列)
- 如果数据有指数分布特征,可以尝试对数转换
import numpy as np
# 加载数据
X = np.array([...]) # 特征
Y = np.array([...]) # 目标
# 标准化
X = (X - np.mean(X)) / np.std(X)
# 添加偏置项
X = np.c_[np.ones(X.shape[0]), X]
2. 损失函数计算
线性回归使用均方误差 (MSE) 作为损失函数:
def compute_cost(X, y, theta):
m = len(y)
predictions = X.dot(theta)
cost = (1/(2*m)) * np.sum(np.square(predictions - y))
return cost
3. 梯度下降实现
这是最核心的部分,注意学习率的选择:
def gradient_descent(X, y, theta, learning_rate, iterations):
m = len(y)
cost_history = []
for _ in range(iterations):
predictions = X.dot(theta)
errors = predictions - y
gradient = (1/m) * X.T.dot(errors)
theta -= learning_rate * gradient
cost_history.append(compute_cost(X, y, theta))
return theta, cost_history
4. 模型评估
训练完成后,我们需要评估模型效果:
- 计算 R 平方值
- 绘制学习曲线
- 检查残差分布
from sklearn.metrics import r2_score
# 预测
y_pred = X.dot(theta)
# R 平方
r2 = r2_score(y, y_pred)
print(f'R-squared: {r2:.3f}')
完整代码示例
import numpy as np
from sklearn.metrics import r2_score
class LinearRegression:
def __init__(self, learning_rate=0.01, iterations=1000):
self.learning_rate = learning_rate
self.iterations = iterations
self.theta = None
self.cost_history = []
def fit(self, X, y):
# 添加偏置项
X = np.c_[np.ones(X.shape[0]), X]
# 初始化参数
self.theta = np.zeros(X.shape[1])
# 梯度下降
m = len(y)
for _ in range(self.iterations):
predictions = X.dot(self.theta)
errors = predictions - y
gradient = (1/m) * X.T.dot(errors)
self.theta -= self.learning_rate * gradient
self.cost_history.append(self._compute_cost(X, y))
return self
def _compute_cost(self, X, y):
m = len(y)
predictions = X.dot(self.theta)
return (1/(2*m)) * np.sum(np.square(predictions - y))
def predict(self, X):
X = np.c_[np.ones(X.shape[0]), X]
return X.dot(self.theta)
def score(self, X, y):
y_pred = self.predict(X)
return r2_score(y, y_pred)
避坑指南
- 学习率选择:先用 0.01 试运行,观察 cost 变化,太大就减小,太小就增大
- 特征缩放:务必将特征标准化,否则梯度下降会很慢
- 迭代次数:绘制 cost 曲线,当曲线变平时就可以停止了
性能考量
- 批量大小 :小批量(32-256) 通常效果不错
- 迭代次数:一般 1000-5000 次足够
- 学习率衰减:可以尝试随着迭代逐步减小学习率
思考题
- 如果特征和目标之间是非线性关系(比如二次方),该如何处理?
- 当特征数量很多时,如何防止过拟合?(提示:正则化)
总结
实现线性回归模型看似简单,但要注意很多细节。通过本文的步骤,你应该已经掌握了从数据预处理到模型评估的全流程。建议动手实现一遍代码,遇到问题时再回来看各个注意事项。记住,实践出真知!
正文完
发表至: 未分类
近两天内
