多线性回归矩阵维度不匹配报错修复及梯度下降实现咨询
多线性回归报错排查与梯度下降实现解析
问题背景
实现多线性回归时触发维度不匹配错误:
ValueError: shapes (19,11) and (5,1) not aligned: 11 (dim 1) != 5 (dim 0)
同时存在两个疑问:
- 是否可通过将全1矩阵设为单列修复该错误?
- 当前梯度下降的实现是否正确?应该逐个处理特征还是整体运算?
原始代码
import numpy as np from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt %matplotlib inline import os path = os.getcwd() + '\farmExpense.txt' x1=[] x2=[] x3=[] x4=[] y=[] file = open("farmExpense.txt","r") while True: line = file.readline() if not line: break else: values = line.split(",") x1.append(float(values[0])) x2.append(float(values[1])) x3.append(float(values[2])) x4.append(float(values[3])) y.append(float(values[4].rstrip("\n"))) file.close() x1 = np.matrix(x1).T x2 = np.matrix(x2).T x3 = np.matrix(x3).T x4 = np.matrix(x4).T y = np.matrix(y).T x = np.hstack((x1,x2,x3,x4)) x = np.matrix(x) print(x) lm = LinearRegression() # 补充原代码遗漏的初始化 lm.fit(x,y) theta0 = lm.intercept_[0] theta1 = lm.coef_[0][0] theta2 = lm.coef_[0][1] theta3 = lm.coef_[0][2] theta4 = lm.coef_[0][3] print("The equation that best models our data is:") print("y=",theta0,"+",theta1,"*X1 +",theta2,"*X2 +",theta3,"*X3 +",theta4, "*X4") # 初始化假设函数的权重 theta0 = 1 theta1 = 0.5 theta2 = 0.2 theta3 = 0.3 theta4 = 0.6 # 学习率 alpha = 0.011 # 收敛阈值(控制停止迭代的条件) conv = 0.001 m = len(x) print(len(x)) # 构造带截距项的特征矩阵 x = np.hstack((np.ones((m,1)), x)) theta = np.matrix([[1],[0.5],[0.2],[0.3],[0.6]]) print(theta) previousCost = 0 numSteps = 0 while True: numSteps += 1 # 计算假设值矩阵 hypothesis = x.dot(theta) # 计算误差矩阵 error = hypothesis - y # 计算误差平方和 totalError = error.T.dot(error) # 计算代价函数值 cost = (1/(2*m)) * totalError # 判断是否收敛 if abs(previousCost - cost) <= conv: break else: # 仅更新前两个theta参数,导致维度不匹配 alphaError0 = error.T.dot(x[:, 0]) alphaError1 = error.T.dot(x[:, 1]) theta0 = theta0 - alpha/m * alphaError0 theta1 = theta1 - alpha/m * alphaError1 # 错误压缩theta维度为2维 theta = np.matrix([[theta0[0,0]],[theta1[0,0]]]) previousCost = cost
(注:原代码遗漏lm = LinearRegression()初始化、循环内代码缩进错误,已修正)
问题解答
1. 报错原因与修复
报错核心是theta维度被错误修改:初始化的theta是5维(对应截距+4个特征),但循环更新时只保留了theta0和theta1,将theta压缩为2维。此时x矩阵是19行5列(19个样本+1列全1+4个特征),执行x.dot(theta)时,5列的x无法与2行的theta做矩阵乘法,导致维度不匹配。
将全1矩阵设为单列是正确操作(用于拟合截距项),但这不是报错根源。真正的修复是更新所有theta参数,不能只更新前两个。
2. 梯度下降实现的正确性
当前实现错误,仅更新了theta0和theta1,遗漏了theta2、theta3、theta4,不仅会导致维度不匹配,还会让模型无法收敛到最优解。
关于处理方式:
- 优先选择整体矩阵运算:无需逐个处理特征,用矩阵公式一次性更新所有theta,代码简洁且不易出错,公式如下:
theta = theta - (alpha/m) * x.T.dot(error) - 若要逐个处理特征,必须遍历所有theta参数(从theta0到theta4),为每个参数计算对应梯度并更新,不能遗漏任何一个。
修正后的梯度下降核心代码
previousCost = 0 numSteps = 0 while True: numSteps += 1 hypothesis = x.dot(theta) error = hypothesis - y totalError = error.T.dot(error) cost = (1/(2*m)) * totalError if abs(previousCost - cost) <= conv: break else: # 整体更新所有theta参数 theta = theta - (alpha/m) * x.T.dot(error) previousCost = cost
额外优化建议
- 移除重复的矩阵转置操作,原代码中多次执行
x1 = np.matrix(x1).T,可简化为一次性处理 - 用
np.loadtxt直接读取csv文件,替代手动逐行读取,代码更简洁:data = np.loadtxt("farmExpense.txt", delimiter=",") x = data[:, :4] y = data[:, 4:] x = np.hstack((np.ones((len(x),1)), x))
内容的提问来源于stack exchange,提问作者MMM 111
相关产品推荐
相关产品推荐

