线性回归w、b更新异常致欠拟合,求代码问题排查
线性回归参数更新异常与欠拟合问题排查
我在进行线性回归时遇到w、b参数更新异常问题:增加训练轮次后,w、b的结果仍无法贴合训练集,预测直线存在严重欠拟合情况。现将代码拆分为以下模块,恳请帮忙排查问题:
1. 数据读取与归一化
df = pd.read_csv('ML/cleaned_data_utf8.csv') df.head() df.dtypes rmv_list = ['$',','] for i in rmv_list: df['budget']=df['budget'].str.replace(i,'',regex=False) df['movie_gross_domestic']=df['movie_gross_domestic'].str.replace(i,'',regex=False) df['movie_gross_worldwide']=df['movie_gross_worldwide'].str.replace(i,'',regex=False) df['budget']=df['budget'].astype(float)/(10**9) df['movie_gross_domestic']=df['movie_gross_domestic'].astype(float)/(10**9) df['movie_gross_worldwide']=df['movie_gross_worldwide'].astype(float)/(10**9) df.head() df.dtypes
2. 数据处理生成总票房字段
sum_gross = df['movie_gross_domestic'] + df['movie_gross_worldwide'] df['Total_gross'] = sum_gross df.head()
3. 梯度下降及w/b更新函数实现
def gradient_descent(w,b,list_x,list_y,alpha,current_index): diff_w = 0 diff_b = 0 training_size = len(list_x) for i in range(training_size): f_of_wb = w * list_x[i]+ b diff_w_i = (f_of_wb - list_y[i]) * list_x[i] diff_b_i = (f_of_wb - list_y[i]) diff_w += diff_w_i diff_b += diff_b_i w = w-(alpha*diff_w)*(1/training_size) b = b-(alpha*diff_b)*(1/training_size) sigma = 0 for i in range(training_size): sigma += (list_y[i]-(w*list_x[i]+b))**2 loss = sigma/training_size if current_index%1000 == 0: print(loss) return (w,b) def update_w_b(num_loop,w,b,alpha,list_x,list_y): current_index = 0 for i in range(num_loop): (w,b) = gradient_descent(w,b,list_x,list_y,alpha,current_index) current_index += 1 return (w,b)
4. 初始参数下的训练执行
w,b = update_w_b(num_loop = 10000 ,w = 2 ,b = 0 ,alpha=1.5,list_x = list(df['budget']),list_y = list(df['Total_gross']))
5. 预测直线与训练数据的可视化对比(欠拟合)
x_axis = df['Total_gross'] y_axis = df['budget'] plt.xlabel("Total_gross($)") plt.ylabel("budget($)") plt.title("Relation between movie budget vs movie gross") # line plot y_predict = [round(w,2)*i/10 + round(b,2) for i in range(5)] x_predict = [i/10 for i in range(5)] # plot plt.scatter(x_axis,y_axis,s=4) plt.plot(x_predict,y_predict) print(list(map(lambda x : round(x,2),y_predict))) print(x_predict) # show plot plt.show() print(round(w,2),round(b,2))
核心问题排查
学习率设置过大
你设置的alpha=1.5远超梯度下降的合理范围(通常在0.001-0.1之间)。过大的学习率会导致参数更新时在损失函数最小值附近震荡甚至发散,无法收敛到最优解,即使增加训练轮次也没用。可视化逻辑完全颠倒
训练逻辑是用budget(自变量x)预测Total_gross(因变量y),但可视化时却把Total_gross设为x轴、budget设为y轴,同时预测直线的生成逻辑也搞反了:训练的模型是Total_gross = w*budget + b,但你画的是budget = w*(i/10) + b,完全不符合训练的模型,直接导致“欠拟合”的错误观感。梯度下降损失计算时机错误
在gradient_descent函数中,你先更新w、b再计算损失,打印的是更新后参数的损失,无法准确观察当前迭代步的收敛情况,不利于调试。正确顺序应该是先计算当前参数的损失,再更新参数。预测直线取值范围不合理
生成的x_predict仅覆盖0-0.4的范围,大概率远小于实际budget的取值区间,导致画出的直线只显示很小一段,看起来无法覆盖数据,加剧了“欠拟合”的错觉。
修复建议
- 把学习率调整为
alpha=0.1或更小(比如0.01),观察损失值是否稳定下降。 - 修正可视化逻辑:
import numpy as np x_axis = df['budget'] y_axis = df['Total_gross'] plt.xlabel("budget($)") plt.ylabel("Total_gross($)") plt.title("Relation between movie budget vs movie gross") # 生成覆盖实际数据范围的预测直线 x_min, x_max = df['budget'].min(), df['budget'].max() x_predict = np.linspace(x_min, x_max, 100) y_predict = w * x_predict + b plt.scatter(x_axis, y_axis, s=4) plt.plot(x_predict, y_predict, color='red') plt.show() - 调整梯度下降函数中损失计算的顺序,先算当前损失再更新参数。
- 训练前先查看
budget和Total_gross的分布,如果本身是非线性关系,线性回归自然会欠拟合,此时需要考虑加入多项式特征或换用其他模型。
内容的提问来源于stack exchange,提问作者Mad_S_Eyes
相关产品推荐
相关产品推荐

