动手学线性回归算法
动手学线性回归算法
在统计学中,线性回归(linear regression)是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归(multivariable linear regression)。
在线性回归中,数据使用线性预测函数来建模,并且未知的模型参数也是通过数据来估计。这些模型被叫做线性模型。最常用的线性回归建模是给定 X 值的 y 的条件均值是X的仿射函数。不太一般的情况,线性回归模型可以是一个中位数或一些其他的给定 X 的条件下 y 的条件分布的分位数作为X的线性函数表示。像所有形式的回归分析一样,线性回归也把焦点放在给定 X 值的 y 的条件概率分布,而不是 X 和 y 的联合概率分布(多元分析领域)。
线性回归的“回归”指的是回归到平均值。
参考:
https://zh.wikipedia.org/wiki/%E7%B7%9A%E6%80%A7%E5%9B%9E%E6%AD%B8
一、基本原理
1. 模型表示
线性回归假设目标变量 和自变量 之间存在线性关系,模型可以表示为:
其中, 是模型的参数, 是误差项,用于捕捉模型无法解释的部分。
为了方便计算,通常将参数写成向量形式 ,并引入偏置项 ,对应的自变量 ,则模型可以简化为:
2. 目标函数
线性回归的目标是找到一组参数 ,使得模型的预测值与真实值之间的误差最小。通常使用均方误差(Mean Squared Error, MSE)作为损失函数,衡量模型的预测误差。均方误差定义为:
其中, 是训练样本的数量, 是第 个样本的真实值, 是模型对第 个样本的预测值。
3. 参数估计
为了最小化均方误差,需要对参数 进行估计。常用的参数估计方法有:
最小二乘法(Ordinary Least Squares, OLS) :通过求解损失函数的最小值来估计参数。最小二乘法的解析解为:
其中, 是训练样本的特征矩阵, 是训练样本的目标值向量。需要注意的是,矩阵 需要是可逆的(即满秩),否则需要使用正则化方法(如岭回归)解决。
梯度下降(Gradient Descent) :通过迭代更新参数,沿梯度方向最小化损失函数。梯度下降的更新规则为:
其中, 是学习率,控制每次更新的步长。
二、优点
简单易懂 :线性回归模型的结构简单,易于理解,能够直观地解释变量之间的关系。 计算效率高 :尤其是对于小规模数据集,线性回归的计算速度较快,能够在较短时间内得到结果。 适用于多种问题 :可以用于预测连续数值型变量,如房价预测、销售额预测等,应用范围广泛。
三、缺点
线性假设限制 :线性回归假设自变量和目标变量之间存在线性关系,对于非线性关系的数据,模型的性能可能会较差。 对异常值敏感 :由于使用均方误差作为损失函数,线性回归对异常值比较敏感,异常值可能会对模型的参数估计产生较大影响。例如,若数据中某个房屋价格异常高(如价格记录错误为原值的10倍),则 MSE 会受到极大影响,导致模型的参数估计偏离合理范围。此时可以考虑使用均值绝对误差(MAE)作为替代损失函数,以减少异常值的影响。 过拟合问题 :当自变量数量较多或数据中存在多重共线性时,线性回归模型可能会出现过拟合现象,导致模型在训练数据上表现良好,但在测试数据上性能较差。
四、应用场景
预测问题 :如房价预测、股票价格预测、销售预测等,预测目标是一个连续数值型变量。 趋势分析 :用于分析数据的变化趋势,如人口增长趋势、经济增长趋势等。 因果关系推断 :在满足一定假设条件下,可以利用线性回归模型推断自变量对目标变量的因果影响,如研究广告投入对销售额的影响。
五、扩展
多项式回归(Polynomial Regression) :在自变量和目标变量之间存在非线性关系时,可以通过引入多项式项(如二次项、三次项等)来扩展线性回归模型,提高模型的拟合能力。 岭回归(Ridge Regression)和套索回归(Lasso Regression) :在存在多重共线性或自变量数量较多时,为了防止过拟合,可以使用岭回归和套索回归,这两种方法在普通线性回归的基础上添加了正则化项,分别对参数的 L2 范数和 L1 范数进行约束。
六、案例:房价预测
数据集描述
我们使用一个包含 47 条房屋数据的数据集:
特征变量 (X) :
:房屋面积(平方英尺) :卧室数量 目标变量 (y) :房屋价格(美元)
示例数据:
Python 代码实现
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport pandas as pdimport numpy as npfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LinearRegressionfrom sklearn.preprocessing import StandardScaler # 新增标准化模块from sklearn.metrics import mean_squared_error, r2_scoreimport matplotlib.pyplot as pltfrom matplotlib import rcParams# 配置 matplotlib 使用字体rcParams['font.sans-serif'] = ['Heiti TC']rcParams['axes.unicode_minus'] = False # 解决负号显示问题# 1. 加载数据集data = pd.read_csv('house_prices.csv') # 假设数据集文件名为 house_prices.csv,列名需与实际数据匹配(如英文列名:'sqft', 'bedrooms', 'price')# 预览数据集的前几行,检查数据格式print("数据集前几行:\n", data.head())# 2. 数据预处理# 特征变量和目标变量X = data[['sqft', 'bedrooms']] # 若列名为中文,需调整为实际列名(如“面积”)y = data['price']# 特征标准化(解决量纲差异问题)scaler = StandardScaler()X_scaled = scaler.fit_transform(X) # 将特征标准化为均值为0,标准差为1# 3. 数据集划分X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)# 4. 创建线性回归模型model = LinearRegression()# 5. 训练模型model.fit(X_train, y_train)# 6. 预测y_pred = model.predict(X_test)# 7. 输出模型参数print("模型参数:")print("截距 (theta0): {:.2f}".format(model.intercept_))print("标准化后的系数 (theta1, theta2): {}".format(model.coef_))# 8. 评估模型mse = mean_squared_error(y_test, y_pred)r2 = r2_score(y_test, y_pred)print("\n模型评估:")print("均方误差 (MSE): {:.2f}".format(mse))print("决定系数 (R^2): {:.2f}".format(r2))# 9. 可视化结果plt.scatter(y_test, y_pred)plt.xlabel("实际价格")plt.ylabel("预测价格")plt.title("实际价格 vs 预测价格")plt.plot(y_test, y_test, color='red', linewidth=2) # 对角线plt.grid()plt.show()# 10. 预测新数据# 假设有一套面积为 2000 平方英尺,3 个卧室的房子new_house = pd.DataFrame([[2000, 3]], columns=['sqft', 'bedrooms']) # 创建一个包含特征名称的 DataFramenew_house_scaled = scaler.transform(new_house) # 标准化新数据predicted_price = model.predict(new_house_scaled)print("\n新房子预测价格:${:.2f}".format(predicted_price[0]))
结果输出与解释
假设数据集文件名为 house_prices.csv,运行上述代码后,输出结果如下:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line数据集前几行:sqft bedrooms price0 1860 4 3523631 2294 4 3803322 2130 2 3477603 2095 4 3825364 2638 4 425915模型参数:截距 (theta0): 380496.07标准化后的系数 (theta1, theta2): [71305.9841922 11566.3096624]模型评估:均方误差 (MSE): 126378189.15决定系数 (R^2): 0.98新房子预测价格:$346999.60