# -------------------------- 导入依赖库(含中文配置) --------------------------
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.lines import Line2D
# -------------------------- 关键:解决matplotlib中文显示问题(Windows系统) --------------------------
# 设置中文字体为"黑体"(Windows自带,无需额外安装)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 替换为 'Microsoft YaHei' 也可(微软雅黑)
# 解决负号显示异常的问题
plt.rcParams['axes.unicode_minus'] = False
# -------------------------- 生成双特征的模拟数据集 --------------------------
X1 = 2 * np.random.rand(100, 1) # 特征1:100个[0,2)区间随机数(100×1)
X2 = 2 * np.random.rand(100, 1) # 特征2:100个[0,2)区间随机数(100×1)
X = np.c_[X1, X2] # 双特征矩阵(100×2):每行[X1, X2]
# 真实模型:y = 4 + 3X1 + 5X2 + 噪声(模拟带噪声的线性关系)
y = 4 + 3 * X1 + 5 * X2 + np.random.randn(100, 1)
# -------------------------- 训练线性回归模型 --------------------------
reg = LinearRegression(fit_intercept=True) # 初始化模型(拟合截距)
reg.fit(X, y) # 训练模型
# 打印参数(验证是否接近真实值:w0=4, w1=3, w2=5)
print("模型截距(w0):", reg.intercept_[0].round(2))
print("特征系数(w1, w2):", reg.coef_[0].round(2))
# -------------------------- 预测新样本 --------------------------
X_new = np.array([[0, 0], # 新样本1:X1=0, X2=0
[2, 1], # 新样本2:X1=2, X2=1
[2, 4]]) # 新样本3:X1=2, X2=4
y_predict = reg.predict(X_new) # 预测标签
print("\n新样本预测值:", y_predict.round(2))
# -------------------------- 3D可视化(完美运行:无报错+中文正常显示) --------------------------
fig = plt.figure(figsize=(10, 8)) # 画布大小
ax = fig.add_subplot(111, projection='3d') # 创建3D坐标轴
# 1. 绘制原始数据(蓝色散点):保存句柄用于图例
scatter1 = ax.scatter(X1[:, 0], X2[:, 0], y[:, 0],
c='blue', alpha=0.7, label='原始数据')
# 2. 生成拟合平面的网格数据
x1_grid = np.linspace(X1.min(), X1.max(), 50) # X1网格(50个点)
x2_grid = np.linspace(X2.min(), X2.max(), 50) # X2网格(50个点)
X1_grid, X2_grid = np.meshgrid(x1_grid, x2_grid) # 二维网格(50×50)
X_grid = np.c_[X1_grid.ravel(), X2_grid.ravel()] # 网格特征矩阵(2500×2)
y_grid = reg.predict(X_grid).reshape(X1_grid.shape) # 拟合平面z值(50×50)
# 3. 绘制拟合平面(红色半透明,不参与图例)
ax.plot_surface(X1_grid, X2_grid, y_grid,
rstride=1, cstride=1, color='red', alpha=0.3)
# 4. 绘制预测点(绿色大圆点):保存句柄用于图例
scatter2 = ax.scatter(X_new[:, 0], X_new[:, 1], y_predict[:, 0],
c='green', s=100, edgecolors='black', label='预测点')
# 5. 手动创建图例(用Line2D兼容3D场景)
legend_elements = [
Line2D([0], [0], color='red', alpha=0.3, linewidth=10, label='拟合平面'),
scatter1, # 原始数据散点图例
scatter2 # 预测点散点图例
]
ax.legend(handles=legend_elements, fontsize=10, loc='upper left')
# 6. 图表美化(中文标签正常显示)
ax.set_xlabel('特征 X1', fontsize=12)
ax.set_ylabel('特征 X2', fontsize=12)
ax.set_zlabel('标签 y', fontsize=12)
ax.set_title('双特征线性回归3D可视化(拟合平面+原始数据+预测点)', fontsize=14)
ax.view_init(elev=20, azim=45) # 3D视角(可调整仰角/方位角)
# 显示图表
plt.tight_layout()
plt.show()
'''
模型截距(w0): 3.78
特征系数(w1, w2): [3.11 4.96]
新样本预测值: [[ 3.78]
[14.96]
[29.83]]
进程已结束,退出代码为 0
'''
