Python基于面积单变量梯度下降线性回归预测房价问题求助
线性回归梯度下降代码问题排查
现存问题
- 迭代次数不足:当前仅循环了40次(等于样本数量m),梯度下降远未达到收敛状态,参数t0、t1还没拟合到最优值,是预测值偏差大的核心原因之一。
- 学习率设置不合理:输入特征x的量级在600~2200之间,alpha=0.001的步长过大,会导致参数更新时震荡甚至梯度爆炸,参数数值越来越大,最终得到的hx远大于真实值,甚至触发数值溢出报错。
- 未做特征标准化:输入特征量级过大,会大幅降低梯度下降的收敛效率,放大学习率不合适带来的负面影响。
- 数据读取未做空值处理:从csv读取数据时如果存在缺失值,计算过程中会出现nan报错。
- 绘图逻辑问题:原始x是无序的样本值,直接plt.plot(x, hx)会画出杂乱的折线,不是平滑的拟合直线。
- 缺少预测流程:没有对新输入特征做和训练集一致的预处理,无法直接完成预测。
修复后完整代码
import numpy as np import pandas as pd import matplotlib.pyplot as plt # 保留从csv读取逻辑的话,建议加空值清理 # db = pd.read_csv("train.csv").dropna() # x = np.array(db.iloc[:40,5]) # y = np.array(db.iloc[:40,11]) # 直接使用提供的数据集演示 x = np.array([1300.236407 , 1275. , 933.1597222, 929.9211427, 999.009247 , 1250. , 1495.053957 , 1181.012946 , 1040. , 879.1208791, 1350.308642 , 1333.010179 , 927.1779023, 1122.171946 , 649.9837504, 1394.117647 , 1800.08471 , 2124.896706 , 1100. , 2178.649237 , 881.1435285, 944.8818898, 1310.147689 , 630.00063 , 1219.80971 , 780.141844 , 1600. , 1180.412371 , 1000. , 1000. , 1400.107701 , 943.1266076, 1150.146382 , 864.0674394, 857.7861968, 1174.210077 , 1020.087884 , 1650.165017 , 1000. , 1300.052002 ]) y = np.array([ 55. , 51. , 43. , 62.5, 60.5, 42. , 66.5, 52. , 41.6, 36. , 35. , 110. , 48. , 62. , 20. , 71.1, 85. , 180. , 22. , 120. , 45. , 42. , 55. , 300. , 50. , 27.5, 46. , 22.9, 39. , 12.5, 52. , 33. , 55. , 82. , 240. , 55. , 65. , 65. , 35. , 75. ]) m = len(x) # 特征标准化,把x缩放到均值0方差1的区间,加快收敛 x_mean = np.mean(x) x_std = np.std(x) x_scaled = (x - x_mean) / x_std t0 = 0 t1 = 1 # 调小学习率适配特征量级 alpha = 0.00001 # 增加迭代次数保证收敛 iterations = 100000 for i in range(iterations): hx = t0 + t1 * x_scaled dt0 = (-2/m) * np.sum(hx - y) dt1 = (-2/m) * np.sum(x_scaled * (hx - y)) t0 = t0 - dt0 * alpha t1 = t1 - dt1 * alpha # 预测功能实现:新输入需要做和训练集相同的标准化处理 x_test = 1000 # 示例:预测1000平方英尺的房价 x_test_scaled = (x_test - x_mean) / x_std pred_y = t0 + t1 * x_test_scaled print(f"1000平方英尺的预测房价:{pred_y:.2f}") print(f"拟合参数t0:{t0:.4f}, t1:{t1:.4f}") # 绘图前先对x排序,得到平滑的拟合直线 sort_idx = np.argsort(x) plt.scatter(x, y, label="真实样本") plt.plot(x[sort_idx], (t0 + t1 * x_scaled[sort_idx]), c='red', label="拟合直线") plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者Omkar Kamble
相关产品推荐
相关产品推荐

