从零实现线性回归用Python揭开机器学习黑箱当你第一次接触机器学习时线性回归往往是入门的第一课。但太多教程止步于调用sklearn的几行代码把最关键的原理变成了一个黑箱。今天我们要用Python和NumPy亲手拆解这个黑箱从数学推导到代码实现完整走一遍线性回归的构建过程。1. 线性回归的本质与数学基础线性回归的核心思想非常简单找到一条直线在高维空间中是超平面使得所有数据点到这条直线的垂直距离之和最小。但这条简单的直线背后蕴含着丰富的数学原理。关键概念解析假设函数$h_\theta(x) \theta_0 \theta_1x_1 \theta_2x_2 ... \theta_nx_n$参数(θ)模型需要学习的权重值特征(x)输入数据的各个维度在实际应用中我们通常会遇到两种求解线性回归参数的方法方法类型求解方式优点缺点解析解最小二乘法直接通过矩阵运算求解一次计算得到最优解大数据集计算成本高数值解梯度下降迭代逼近最优解适合大规模数据需要选择学习率等超参数2. 实现最小二乘法解析解最小二乘法是线性回归最直接的求解方式它通过矩阵运算直接计算出最优参数θ。让我们看看如何用NumPy实现import numpy as np class LinearRegression: def __init__(self): self.theta None def fit(self, X, y): # 添加偏置项x01 X_b np.c_[np.ones((X.shape[0], 1)), X] # 计算解析解(X^T X)^-1 X^T y self.theta np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) return self def predict(self, X): X_b np.c_[np.ones((X.shape[0], 1)), X] return X_b.dot(self.theta)实现细节说明np.c_用于将一列1与原始特征矩阵拼接对应偏置项θ0np.linalg.inv计算矩阵的逆矩阵乘法遵循(X^T X)^-1 X^T y的数学公式注意当特征矩阵X^T X不可逆时需要添加小的正则项或使用伪逆3. 梯度下降法实现对于大规模数据集矩阵求逆可能计算量太大。这时梯度下降这种迭代方法就派上用场了。梯度下降通过不断沿损失函数梯度方向更新参数逐步逼近最优解。批量梯度下降实现def fit_gradient_descent(self, X, y, learning_rate0.01, n_iters1000): n_samples, n_features X.shape self.theta np.zeros(n_features 1) # 初始化参数 X_b np.c_[np.ones((n_samples, 1)), X] for _ in range(n_iters): gradients 2/n_samples * X_b.T.dot(X_b.dot(self.theta) - y) self.theta - learning_rate * gradients return self梯度下降有几个关键点需要注意学习率选择太大导致震荡太小收敛慢迭代次数需要足够让算法收敛特征缩放不同特征尺度差异大时需要归一化梯度下降变体对比类型每次迭代样本数收敛速度内存需求批量梯度下降全部样本稳定但慢高随机梯度下降1个样本快但不稳定低小批量梯度下降小批量样本折中中等4. 模型评估指标实现模型建好了如何评估它的表现呢最常用的两个指标是均方误差(MSE)和R²分数。MSE实现def mse_score(y_true, y_pred): return np.mean((y_true - y_pred) ** 2)R²分数实现def r2_score(y_true, y_pred): ss_res np.sum((y_true - y_pred) ** 2) ss_tot np.sum((y_true - np.mean(y_true)) ** 2) return 1 - (ss_res / ss_tot)这两个指标各有侧重MSE直接反映预测值与真实值的平均平方误差R²表示模型解释的方差比例范围通常在0-1之间提示在实际项目中建议同时计算多个评估指标从不同角度评估模型性能5. 完整案例演示让我们用一个完整的例子把所有这些概念串联起来。假设我们有一组房屋面积与价格的数据# 生成示例数据 np.random.seed(42) X 2 * np.random.rand(100, 1) y 4 3 * X np.random.randn(100, 1) # 划分训练测试集 X_train, X_test X[:80], X[80:] y_train, y_test y[:80], y[80:] # 训练模型 lin_reg LinearRegression() lin_reg.fit(X_train, y_train) # 预测并评估 y_pred lin_reg.predict(X_test) print(MSE:, mse_score(y_test, y_pred)) print(R²:, r2_score(y_test, y_pred)) # 可视化结果 import matplotlib.pyplot as plt plt.scatter(X, y) plt.plot(X, lin_reg.predict(X), colorred) plt.xlabel(房屋面积) plt.ylabel(价格) plt.show()这个完整流程展示了从数据准备到模型评估的全过程。在实际项目中你还需要考虑数据预处理缺失值、异常值处理特征工程特征选择、多项式特征模型调参正则化、学习率调整6. 进阶话题与优化方向掌握了线性回归的基础实现后有几个重要的进阶方向值得探索正则化方法岭回归(L2正则)解决特征共线性问题Lasso回归(L1正则)自动进行特征选择多项式回归 通过增加特征的高次项线性回归可以拟合非线性关系from sklearn.preprocessing import PolynomialFeatures poly_features PolynomialFeatures(degree2, include_biasFalse) X_poly poly_features.fit_transform(X)数值稳定性优化使用np.linalg.pinv代替逆矩阵计算添加小的正则项保证矩阵可逆实现QR分解等更稳定的求解方法在实现这些优化时你会发现线性回归这个看似简单的模型其实蕴含着丰富的优化空间和技巧。
别再死记硬背公式了!用Python手写线性回归,从MSE、R²到梯度下降一次搞懂
从零实现线性回归用Python揭开机器学习黑箱当你第一次接触机器学习时线性回归往往是入门的第一课。但太多教程止步于调用sklearn的几行代码把最关键的原理变成了一个黑箱。今天我们要用Python和NumPy亲手拆解这个黑箱从数学推导到代码实现完整走一遍线性回归的构建过程。1. 线性回归的本质与数学基础线性回归的核心思想非常简单找到一条直线在高维空间中是超平面使得所有数据点到这条直线的垂直距离之和最小。但这条简单的直线背后蕴含着丰富的数学原理。关键概念解析假设函数$h_\theta(x) \theta_0 \theta_1x_1 \theta_2x_2 ... \theta_nx_n$参数(θ)模型需要学习的权重值特征(x)输入数据的各个维度在实际应用中我们通常会遇到两种求解线性回归参数的方法方法类型求解方式优点缺点解析解最小二乘法直接通过矩阵运算求解一次计算得到最优解大数据集计算成本高数值解梯度下降迭代逼近最优解适合大规模数据需要选择学习率等超参数2. 实现最小二乘法解析解最小二乘法是线性回归最直接的求解方式它通过矩阵运算直接计算出最优参数θ。让我们看看如何用NumPy实现import numpy as np class LinearRegression: def __init__(self): self.theta None def fit(self, X, y): # 添加偏置项x01 X_b np.c_[np.ones((X.shape[0], 1)), X] # 计算解析解(X^T X)^-1 X^T y self.theta np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) return self def predict(self, X): X_b np.c_[np.ones((X.shape[0], 1)), X] return X_b.dot(self.theta)实现细节说明np.c_用于将一列1与原始特征矩阵拼接对应偏置项θ0np.linalg.inv计算矩阵的逆矩阵乘法遵循(X^T X)^-1 X^T y的数学公式注意当特征矩阵X^T X不可逆时需要添加小的正则项或使用伪逆3. 梯度下降法实现对于大规模数据集矩阵求逆可能计算量太大。这时梯度下降这种迭代方法就派上用场了。梯度下降通过不断沿损失函数梯度方向更新参数逐步逼近最优解。批量梯度下降实现def fit_gradient_descent(self, X, y, learning_rate0.01, n_iters1000): n_samples, n_features X.shape self.theta np.zeros(n_features 1) # 初始化参数 X_b np.c_[np.ones((n_samples, 1)), X] for _ in range(n_iters): gradients 2/n_samples * X_b.T.dot(X_b.dot(self.theta) - y) self.theta - learning_rate * gradients return self梯度下降有几个关键点需要注意学习率选择太大导致震荡太小收敛慢迭代次数需要足够让算法收敛特征缩放不同特征尺度差异大时需要归一化梯度下降变体对比类型每次迭代样本数收敛速度内存需求批量梯度下降全部样本稳定但慢高随机梯度下降1个样本快但不稳定低小批量梯度下降小批量样本折中中等4. 模型评估指标实现模型建好了如何评估它的表现呢最常用的两个指标是均方误差(MSE)和R²分数。MSE实现def mse_score(y_true, y_pred): return np.mean((y_true - y_pred) ** 2)R²分数实现def r2_score(y_true, y_pred): ss_res np.sum((y_true - y_pred) ** 2) ss_tot np.sum((y_true - np.mean(y_true)) ** 2) return 1 - (ss_res / ss_tot)这两个指标各有侧重MSE直接反映预测值与真实值的平均平方误差R²表示模型解释的方差比例范围通常在0-1之间提示在实际项目中建议同时计算多个评估指标从不同角度评估模型性能5. 完整案例演示让我们用一个完整的例子把所有这些概念串联起来。假设我们有一组房屋面积与价格的数据# 生成示例数据 np.random.seed(42) X 2 * np.random.rand(100, 1) y 4 3 * X np.random.randn(100, 1) # 划分训练测试集 X_train, X_test X[:80], X[80:] y_train, y_test y[:80], y[80:] # 训练模型 lin_reg LinearRegression() lin_reg.fit(X_train, y_train) # 预测并评估 y_pred lin_reg.predict(X_test) print(MSE:, mse_score(y_test, y_pred)) print(R²:, r2_score(y_test, y_pred)) # 可视化结果 import matplotlib.pyplot as plt plt.scatter(X, y) plt.plot(X, lin_reg.predict(X), colorred) plt.xlabel(房屋面积) plt.ylabel(价格) plt.show()这个完整流程展示了从数据准备到模型评估的全过程。在实际项目中你还需要考虑数据预处理缺失值、异常值处理特征工程特征选择、多项式特征模型调参正则化、学习率调整6. 进阶话题与优化方向掌握了线性回归的基础实现后有几个重要的进阶方向值得探索正则化方法岭回归(L2正则)解决特征共线性问题Lasso回归(L1正则)自动进行特征选择多项式回归 通过增加特征的高次项线性回归可以拟合非线性关系from sklearn.preprocessing import PolynomialFeatures poly_features PolynomialFeatures(degree2, include_biasFalse) X_poly poly_features.fit_transform(X)数值稳定性优化使用np.linalg.pinv代替逆矩阵计算添加小的正则项保证矩阵可逆实现QR分解等更稳定的求解方法在实现这些优化时你会发现线性回归这个看似简单的模型其实蕴含着丰富的优化空间和技巧。