一、线性回归模型拟合线性方程

1实验步骤

生成线性数据并添加噪声。
用线性回归拟合,绘制数据点和回归线。

2python程序代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 或者 ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 生成线性数据
np.random.seed(42)
X = np.linspace(0, 10, 100).reshape(-1, 1)
y = 2 * X + 1 + np.random.normal(0, 1, size=(100, 1))

# 拟合模型
model = LinearRegression()
model.fit(X, y)
y_pred = model.predict(X)

# 绘图
plt.figure(figsize=(8, 5))
plt.scatter(X, y, color='blue', label='原始数据')
plt.plot(X, y_pred, color='red', linewidth=2, label='回归线')
plt.title("线性回归拟合")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.show()

3结果分析

输出图:散点图+回归线,展示拟合效果。 线性回归拟合图展示人工生成的线性数据及其回归线
横坐标(X轴):人工生成的0-10范围内的连续值
纵坐标(y轴):基于公式 y=2X+1 生成,添加了随机噪声
图例说明:蓝色散点表示原始数据点,带噪声的真实观测值;红色直线表示回归线,模型拟合的线性关系 y=ax+b
分析意义:验证线性回归能否从带噪声数据中还原真实的线性关系(本例中真实斜率为2,截距为1)。
 

二、糖尿病数据线性回归分析

1数据集

使用`sklearn.datasets.load_diabetes()`,包含10个特征和疾病进展指标(目标变量)。

2python程序代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.linear_model import LinearRegression

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 或者 ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 加载数据
data = load_diabetes()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)

# 评估指标
print(f"MSE: {mean_squared_error(y_test, y_pred):.2f}")
print(f"R²: {r2_score(y_test, y_pred):.2f}")

# 预测值 vs 真实值图
plt.figure(figsize=(8, 5))
plt.scatter(y_test, y_pred, alpha=0.6)
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'r--')
plt.xlabel("实际疾病进展值")
plt.ylabel("预测疾病进展值")
plt.title("糖尿病进展: 实际值 vs 预测值")
plt.show()

# 残差图
residuals = y_test - y_pred
plt.figure(figsize=(8, 5))
plt.scatter(y_pred, residuals, alpha=0.6)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel("预测值")
plt.ylabel("残差")
plt.title("残差图")
plt.show()

3结果分析

(1) 实际值 vs 预测值散点图测试集真实结果与模型预测结果的对比
横坐标(X轴):实际疾病进展值 (医学指标,范围约25-350)
纵坐标(y轴):预测疾病进展值  (模型输出的预测结果)
图例说明:红色虚线表示y=x的理想参考线  (预测完全准确时应与散点重合)
分析意义:散点分布较分散(R²=0.45),说明模型仅能解释45%的变异 ;在低值区域(<100)预测偏高,高值区域(>250)预测偏低,可能存在系统性偏差。点越接近红色虚线,预测越准。本例中大部分点偏离,说明模型不完美。

图一 实际值 vs 预测值散点图

(2) 残差诊断图预测误差分析
横坐标(X轴):预测值  (同图1的y轴数据)
纵坐标(y轴):残差(实际值 - 预测值)(正残差=低估,负残差=高估)*
红色虚线:残差=0的基准线  
分析意义:检查残差是否随机分布,本例残差呈"喇叭形"分布(预测值越大,误差范围越宽),违反同方差假设 ;建议尝试:对数变换、加权回归或非线性模型,残差应随机分布在0线周围,若出现模式则可能模型欠拟合。  

图二 残差图

三、岭回归与套索回归分析

1实验步骤

使用交叉验证选择最佳正则化参数(α)。
比较模型系数和性能。

2python程序代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge, Lasso, RidgeCV, LassoCV
from sklearn.model_selection import train_test_split, validation_curve
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False

# 加载糖尿病数据集
diabetes = load_diabetes()
X, y = diabetes.data, diabetes.target
feature_names = diabetes.feature_names

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 创建子图画布
fig = plt.figure(figsize=(16, 5))
fig.suptitle('糖尿病数据回归分析对比 (岭回归 vs 套索回归)', fontsize=16)

# ==================== 1. 预测性能折线图 ====================
ax1 = plt.subplot(1, 3, 1)
alphas = np.logspace(-3, 3, 100)

ridge_scores = []
lasso_scores = []

for alpha in alphas:
    ridge = Ridge(alpha=alpha).fit(X_train, y_train)
    ridge_scores.append(mean_squared_error(y_test, ridge.predict(X_test)))

    lasso = Lasso(alpha=alpha).fit(X_train, y_train)
    lasso_scores.append(mean_squared_error(y_test, lasso.predict(X_test)))

ax1.semilogx(alphas, ridge_scores, label='岭回归')
ax1.semilogx(alphas, lasso_scores, label='套索回归')
ax1.set_xlabel('正则化强度(alpha)')
ax1.set_ylabel('测试集均方误差(MSE)')
ax1.set_title('模型预测性能对比')
ax1.legend()
ax1.grid(True)

# ==================== 2. 系数路径图 ====================
ax2 = plt.subplot(1, 3, 2)

ridge_coefs = []
lasso_coefs = []
for alpha in alphas:
    ridge = Ridge(alpha=alpha).fit(X_train, y_train)
    ridge_coefs.append(ridge.coef_)

    lasso = Lasso(alpha=alpha).fit(X_train, y_train)
    lasso_coefs.append(lasso.coef_)

ridge_coefs = np.array(ridge_coefs)
lasso_coefs = np.array(lasso_coefs)

# 岭回归系数路径
for i in range(ridge_coefs.shape[1]):
    ax2.plot(alphas, ridge_coefs[:, i], linestyle='--', label=f'岭:{feature_names[i]}')

# 套索回归系数路径
for i in range(lasso_coefs.shape[1]):
    ax2.plot(alphas, lasso_coefs[:, i], linestyle='-', label=f'套索:{feature_names[i]}')

ax2.set_xscale('log')
ax2.set_xlabel('正则化强度(alpha)')
ax2.set_ylabel('系数值')
ax2.set_title('系数路径图')
ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
ax2.grid(True)


# ==================== 4. 特征权重图 ====================
ax4 = plt.subplot(1, 3, 3)

# 使用交叉验证选择最佳alpha
ridge_cv = RidgeCV(alphas=alphas, cv=5).fit(X_train, y_train)
lasso_cv = LassoCV(alphas=alphas, cv=5).fit(X_train, y_train)

# 获取最佳模型的特征系数
ridge_coef = ridge_cv.coef_
lasso_coef = lasso_cv.coef_

x = np.arange(len(feature_names))
width = 0.35

ax4.bar(x - width / 2, ridge_coef, width, label='岭回归')
ax4.bar(x + width / 2, lasso_coef, width, label='套索回归')

ax4.set_xticks(x)
ax4.set_xticklabels(feature_names, rotation=45)
ax4.set_ylabel('系数值')
ax4.set_title('特征权重对比 (最优alpha)')
ax4.legend()
ax4.grid(True)

plt.tight_layout()
plt.show()

# 模型选择解释
print("模型选择分析:")
print("1. 预测性能折线图:")
print("   - 当alpha较小时,两种模型表现相似,随着alpha增大,岭回归性能下降更平缓")
print("   - 套索回归在中等alpha值时可能找到更优的稀疏解")

print("\n2. 系数路径图:")
print("   - 岭回归系数逐渐收缩但不会为零,所有特征都被保留")
print("   - 套索回归系数会在特定alpha时变为零,实现特征选择")

print("\n3. 特征权重图:")
print(f"   - 岭回归最优alpha: {ridge_cv.alpha_:.4f}")
print(f"   - 套索回归最优alpha: {lasso_cv.alpha_:.4f}")
print("   - 套索回归产生了稀疏解,自动选择了部分重要特征")

3结果分析

(1) 预测性能折线图

横轴:正则化强度alpha(对数尺度)
纵轴:测试集均方误差(MSE)
意义:展示不同正则化强度下模型的预测性能。曲线最低点对应最优alpha(平衡偏差与方差),套索回归在中等alpha时可能达到更低误差,需要精细调参,但岭回归对alpha选择更稳定,曲线更平缓。

(2) 系数路径图

横轴:正则化强度alpha(对数尺度)
纵轴:各特征的系数值
意义:直观显示系数随正则化变化。套索回归(实线)会产生精确的零系数,实现特征选择;岭回归(虚线)只会渐进缩小系数。

(3) 特征权重对比图

横轴:特征名称
纵轴:最优alpha下的系数值
意义:直接对比两种模型筛选出的关键特征,套索回归的稀疏性会使得部分系数为0(图中无柱形),岭回归会保留所有特征但缩小系数值,柱形绝对值较大的特征对预测影响更强
例如:若`bmi`和`s5`的系数明显高于其他特征,说明它们与糖尿病进展相关性更强, `s5`(血清指标)在两种模型中系数均最大 → 强相关特征, `age`在套索回归中系数为0 → 可能被判定为冗余特征,`bmi`在岭回归中为正,但在套索回归中系数较小 → 需结合业务判断是否保留
模型选择建议:
- 当特征间高度相关时,岭回归通常更稳定
- 当存在许多无关特征时,套索回归能自动选择重要特征
- 从验证曲线可确定每种模型的最佳正则化强度
- 套索回归的稀疏性使其模型更易解释,但可能丢失一些微弱信号

套索倾向于让部分系数为0,较小的正则化强度就可以实现特征选择,岭回归只是缩小系数,可能需要更大的alpha平衡方差和偏差,需要较大的正则化强度来平衡模型的复杂度。

问题总结

在Python中,要让Matplotlib图形中的标题、坐标轴标签和图例显示中文,在代码前加入:

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 或者 ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐