#encoding=utf8 import numpy as np def mse_score(y_predict,y_test): ''' input:y_predict(ndarray):预测值 y_test(ndarray):真实值 ouput:mse(float):mse损失函数值 ''' #********* Begin *********# mse = np.mean(y_predict - y_test) #或者带上平方也是可以的 #mse = np.mean((y_predict - y_test)**2) #********* End *********# return mse class LinearRegression : def __init__(self): '''初始化线性回归模型''' self.theta = None def fit_normal(self,train_data,train_label): ''' input:train_data(ndarray):训练样本 train_label(ndarray):训练标签 ''' #********* Begin *********#以下均以矩阵的形式表示 x = np.hstack([np.ones((len(train_data),1)),train_data])#将训练数组改为一行数据,即X=(1,x1,...,xn) self.theta =np.linalg.inv(x.T.dot(x)).dot(x.T).dot(train_label)#公式如下:由损失函数得到的最优解heta=(X^T * X )^(-1) * x ^T *Y #********* End *********# return self.theta def predict(self,test_data): ''' input:test_data(ndarray):测试样本 ''' #********* Begin *********# x = np.hstack([np.ones((len(test_data),1)),test_data]) return x.dot(self.theta)# 预测函数Y = heta * X #********* End *********#
时间: 2025-05-05 18:48:25 浏览: 57
<<
您的代码实现了使用正规方程法(Normal Equation)进行线性回归,并定义了MSE评分函数。但存在几个潜在的问题或改进空间:
### 1. **`mse_score` 函数中的错误**
在 `mse_score` 中计算 MSE 的方式存在问题:
```python
mse = np.mean(y_predict - y_test)
```
这里直接对差值取平均,而不是先求平方再取平均,导致结果不正确。
正确的方式应为:
```python
mse = np.mean((y_predict - y_test) ** 2)
```
---
### 2. **`fit_normal` 方法的数值稳定性**
使用 `(X^T * X)^(-1)` 可能会导致数值不稳定的情况,特别是在特征之间高度共线时。建议改用更稳定的替代方法,例如 NumPy 提供的 `pinv` 或者 `lstsq` 来代替矩阵逆运算。
改进后的实现可以是:
```python
self.theta = np.linalg.pinv(x.T.dot(x)).dot(x.T).dot(train_label)
```
或者更高效地:
```python
self.theta = np.linalg.lstsq(x, train_label, rcond=None)[0]
```
---
### 完整修正版代码
```python
# encoding=utf8
import numpy as np
def mse_score(y_predict, y_test):
'''
计算均方误差 (Mean Squared Error)
input:
y_predict(ndarray): 预测值
y_test(ndarray): 真实值
output:
mse(float): 均方误差值
'''
# 均方误差公式:(预测值 - 实际值) 平方后取平均
mse = np.mean((y_predict - y_test) ** 2)
return mse
class LinearRegression:
def __init__(self):
''' 初始化线性回归模型 '''
self.theta = None # 模型参数 θ
def fit_normal(self, train_data, train_label):
'''
根据训练集拟合线性回归模型(正规方程法)
input:
train_data(ndarray): 训练样本
train_label(ndarray): 训练标签
return:
theta(ndarray): 学到的模型参数
'''
# 添加偏置项列 [1, x1, ..., xn] -> [1, x1, ..., xn]^T
x = np.hstack([np.ones((len(train_data), 1)), train_data])
# 解正规方程:θ = (X^T * X)^(-1) * X^T * Y
try:
self.theta = np.linalg.inv(x.T.dot(x)).dot(x.T).dot(train_label)
except np.linalg.LinAlgError:
print("Matrix is singular or nearly singular, using pseudo-inverse instead.")
self.theta = np.linalg.pinv(x.T.dot(x)).dot(x.T).dot(train_label)
return self.theta
def predict(self, test_data):
'''
对新数据进行预测
input:
test_data(ndarray): 测试样本
output:
predictions(ndarray): 预测结果
'''
# 同样添加偏置项列 [1, x1, ..., xn]
x = np.hstack([np.ones((len(test_data), 1)), test_data])
# 返回预测值 Y = X * θ
return x.dot(self.theta)
# 示例运行代码
if __name__ == "__main__":
# 构造简单示例数据
X_train = np.array([[1], [2], [3]])
y_train = np.array([2, 4, 6])
model = LinearRegression()
model.fit_normal(X_train, y_train)
X_test = np.array([[4], [5]])
y_pred = model.predict(X_test)
print(f"Learned parameters: {model.theta}")
print(f"Predictions on test data: {y_pred}")
```
---
### 给出解释
#### 问题修复与优化点分析:
1. **关于 `mse_score`:**
原始实现中没有对差值做平方处理,仅计算的是 "平均偏差" 而非正确的均方误差 (MSE),这可能导致负数被抵消的现象,从而使结果失真。
2. **正则化方程的数值稳定性和效率:**
直接调用 `np.linalg.inv()` 不够健壮,在某些情况下可能会出现奇异阵异常(Singular Matrix)。我们推荐使用伪逆 (`pinv`) 或最小二乘解 (`lstsq`) 替代之。
3. **代码结构清晰度提升:**
将每个步骤都封装得更加模块化、便于调试以及后续扩展。比如单独写出了加偏置的方法等。
---
###
阅读全文
相关推荐















