机器学习入门(一),线性回归

一、线性回归

数据计算原理

复制代码
例:通过多个特征预测成绩
线性回归的本质是加权求和(w*权重):
 预测成绩 = (w1 × 学习时长) + (w2 × 作业均分) + (w3 × 互动次数) +
       (w4 × 预习时间) + (w5 × 复习时间) + 截距
 预测成绩 = (0.15 × 125) + (0.8 × 86) + (0.05 × 18) +
            (0.1 × 32) + (0.12 × 28) + 50.0
          = 18.75 + 68.8 + 0.9 + 3.2 + 3.36 + 50.0
          ≈ 85.01

你的数据(简化为3个学生,2个特征):

学生 学习时长(x₁) 作业分(x₂) 真实成绩(y)
A 10小时 80分 85分
B 20小时 90分 95分
C 15小时 85分 90分

分步计算过程,权重截距计算

第1步:写成矩阵

复制代码
     [10  80]        [85]
X =  [20  90]    y = [95]
     [15  85]        [90]

第2步:计算 XᵀX(X转置乘X)

复制代码
Xᵀ = [10  20  15] 
     [80  90  85]

XᵀX = [10  20  15] × [10  80] = [10×10+20×20+15×15   10×80+20×90+15×85]
      [80  90  85]   [20  90]   [80×10+90×20+85×15   80×80+90×90+85×85]
                     [15  85]

      = [725   4175]
        [4175  24125]

第3步:计算 (XᵀX)⁻¹(求逆矩阵)

复制代码
逆矩阵计算复杂,这里直接给结果:
(XᵀX)⁻¹ ≈ [ 0.0241  -0.0042]
          [-0.0042   0.0007]

第4步:计算 Xᵀy

复制代码
Xᵀy = [10  20  15] × [85] = [10×85 + 20×95 + 15×90] = [4250]
      [80  90  85]   [95]   [80×85 + 90×95 + 85×90]   [24150]
                     [90]

第5步:计算权重 w = (XᵀX)⁻¹Xᵀy

复制代码
w = [ 0.0241  -0.0042] × [4250] 
    [-0.0042   0.0007]   [24150]

  = [0.0241×4250 + (-0.0042)×24150] 
    [(-0.0042)×4250 + 0.0007×24150]

  = [102.425 - 101.43] ≈ [0.995]
    [-17.85 + 16.905]    [-0.945]

所以:w₁ = 0.995, w₂ = -0.945

第6步:计算截距 b

复制代码
b = y的平均值 - (w₁×x₁平均值 + w₂×x₂平均值)

y平均值 = (85+95+90)/3 = 90
x₁平均值 = (10+20+15)/3 = 15
x₂平均值 = (80+90+85)/3 = 85

b = 90 - (0.995×15 + (-0.945)×85)
  = 90 - (14.925 - 80.325)
  = 90 - (-65.4)
  = 155.4
复制代码
预测成绩 = 0.995×学习时长 - 0.945×作业分 + 155.4

为什这么计算可以通过多个特征实现预测

  1. 代数逻辑: 寻找"误差最小"的那个点(求导为0)。

  2. 几何逻辑: 上帝视角的"垂直投影"。

第一层理解:它是在"解方程组",不是在"猜"

不管是 1 个特征还是 100 个特征,本质上你都是在解一个超级方程组

假设有 3 个数据点(刚才举的例子):

复制代码
10 * w1 + 80 * w2 = 85 
20 * w1 + 90 * w2 = 95 
15 * w1 + 85 * w2 = 90 

这就是一个 X⋅w=Y 的方程组。

如果数据完美,你用初中数学就能解出 w1​,w2​。但现实是残酷的: 数据有噪声,方程组通常无解(直线不可能同时完美穿过所有点)。既然找不到让等式左右两边完全相等的 w,那我就找一个让左右两边'差距最小'的 w。

第二层理解(核心):那两步运算到底在算什么?

公式是: w = (XᵀX)⁻¹Xᵀy

第一步:算 Xᵀy ------ "寻找相关性"

把特征矩阵 Xᵀ 转置,去乘结果 用y, 这是在做内积(Dot Product)

这就好比你在问数据:"喂,特征 x1(学习时长)变大的时候,结果 y (成绩)是不是也变大?

  • 如果它们步调一致,乘积就是正的巨款。

  • 如果它们反着来,乘积就是负的。

  • Xᵀy 得到了一个"粗糙的权重":它告诉了我们每个特征和结果的"原始亲密度"。

第二步:算 (XᵀX)⁻¹ ------ "消除内部内卷"

把特征矩阵自己乘自己,然后求逆(相当于除法)。(XᵀX)⁻¹ 算的是特征之间的协方差(相关性)

这就好比你在问:"特征 x1​(学习时长)和特征 x2​ (作业分)是不是其实是一回事?"

  • 如果 x1 变大,x2 也跟着变大,说明这两个特征重复了(信息冗余)

  • 如果不除以这个重复度,你的权重就会算重,预测就会偏大。

  • 求逆 (...)−1 就是"除法",目的就是把这些重复的、内卷的信息剔除掉。

    复制代码
    `w=`(特征和结果的亲密度)`÷`(特征之间的重复度)`这就是线性回归的本质!`

第三层理解:上帝的"垂直投影"

  1. 想象一个空间: 你的特征 x1,x2 张成了一个平面(或者超平面)。

  2. 现实的残酷: 真实结果 Y 是一个向量,它飘在这个平面之外(因为有误差,不可能完美拟合)。

  3. 我们的目标: 我们要在平面上找一个向量(预测值 Y ),让它离真实的 Y 最近

  4. 最近的距离是什么?垂直距离 ! 也就是从 Y 往平面上打一束光,留下的那个"影子"。那个矩阵运算公式,就是在计算这个"影子"的坐标。 垂直,意味着误差最小(勾股定理)。

基于python scikit-learn 简单的代码实现

例一

python 复制代码
"""
## (一)回归任务预测
# 1.导入依赖包
# 2.准备数据
# 3.实例化 线性回归模型
# 4.模型训练
# 5.模型预测

x = [[80, 86], [82, 80], [85, 78], [90, 90], [86, 82], [82, 90], [78, 80], [92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]
"""
# 1.导入依赖包
from sklearn.linear_model import LinearRegression


def dm01_linear_regression_pred():
    # 2.准备数据 平时成绩 期末成绩 最终成绩
    x = [[80, 86], [82, 80], [85, 78], [90, 90], [86, 82], [82, 90], [78, 80], [92, 94]]
    y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]

    # 3.实例化 线性回归模型
    estimator = LinearRegression()
    print('estimator-->', estimator)

    # 4.模型训练
    # 打印 线性回归模型参数 coef_ intercept_
    estimator.fit(x, y)
    print('estimator.coef_-->', estimator.coef_)
    print('estimator.intercept_-->', estimator.intercept_)

    # 5.模型预测
    mypred = estimator.predict([[90, 80]])
    print('mypred-->', mypred)

列二

python 复制代码
"""
## (二)回归任务保存和加载模型
# 1.导入依赖包
# 2.准备数据
# 3.实例化 线性回归模型
# 4.模型训练
# 5.模型预测
# 6.模型保存 joblib.dump(estimator, xxpath)
# 7.模型加载 joblib.load(xxpath)
# 8.模型预测

x = [[80, 86], [82, 80], [85, 78], [90, 90], [86, 82], [82, 90], [78, 80], [92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]

"""
# 1.导入依赖包
import joblib


def dm02_linear_regression_pred():
    # 2.准备数据 平时成绩 期末成绩 最终成绩
    x = [[80, 86], [82, 80], [85, 78], [90, 90], [86, 82], [82, 90], [78, 80], [92, 94]]
    y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]

    # 3.实例化 线性回归模型
    estimator = LinearRegression()
    print('estimator-->', estimator)

    # 4.模型训练
    estimator.fit(x, y)

    # 5.模型预测
    mypred = estimator.predict([[90, 80]])
    print('mypred-->', mypred)

    # 6.模型保存
    print('\n模型保存和模型重新加载')
    joblib.dump(estimator, './model/my_linear_regression_model01.bin')

    # 7.模型加载
    myestimator2 = joblib.load('./model/my_linear_regression_model01.bin')
    print('myestimator2-->', myestimator2)

    # 8.模型预测
    mypred2 = myestimator2.predict([[90, 80]])
    print('mypred2-->', mypred2)

例三

python 复制代码
def dm03_linear_regression_pred():
    # 1.导入模型
    from sklearn.linear_model import LinearRegression
    import numpy as np

    # 2.准备数据 - 扩展更多数据,确保复习时间与成绩负相关
    # [学习时长(h), 作业均分, 互动次数, 预习时间(h), 复习时间(h)]
    x = np.array([
        # 原始8个学生数据
        [120, 85, 15, 30, 25],  # 学生1
        [100, 78, 10, 20, 20],  # 学生2
        [150, 92, 25, 40, 35],  # 学生3
        [80, 70, 8, 15, 15],  # 学生4
        [130, 88, 20, 35, 30],  # 学生5
        [110, 82, 12, 25, 22],  # 学生6
        [140, 90, 22, 38, 32],  # 学生7
        [95, 75, 9, 18, 18],  # 学生8

        # 新增数据 - 确保复习时间与成绩的负相关趋势
        # 第一组:复习时间少但成绩好的学生(负相关证据)
        [125, 90, 20, 32, 15],  # 学生9:复习15h,但成绩好
        [115, 88, 18, 28, 16],  # 学生10:复习16h
        [135, 91, 22, 35, 17],  # 学生11:复习17h
        [105, 85, 16, 24, 14],  # 学生12:复习14h

        # 第二组:复习时间多但成绩一般的学生(负相关证据)
        [95, 72, 8, 20, 40],  # 学生13:复习40h,成绩一般
        [85, 68, 6, 18, 38],  # 学生14:复习38h
        [100, 75, 10, 22, 42],  # 学生15:复习42h
        [90, 70, 7, 19, 45],  # 学生16:复习45h

        # 第三组:中等复习时间的学生(平衡数据)
        [110, 80, 14, 26, 25],  # 学生17
        [130, 87, 19, 34, 28],  # 学生18
        [120, 83, 17, 30, 22],  # 学生19
        [140, 89, 21, 37, 30],  # 学生20

        # 第四组:强化负相关趋势
        [160, 93, 28, 42, 18],  # 学生21:学习努力但复习少
        [70, 65, 5, 12, 48],  # 学生22:学习差但拼命复习
        [145, 92, 24, 39, 19],  # 学生23
        [125, 86, 18, 32, 16],  # 学生24

        # 第五组:更多样本
        [115, 81, 13, 27, 24],  # 学生25
        [135, 89, 20, 36, 26],  # 学生26
        [105, 77, 11, 23, 35],  # 学生27:复习多但成绩差
        [150, 94, 26, 41, 20],  # 学生28

        # 第六组:最后一批
        [155, 95, 27, 43, 21],  # 学生29
        [125, 84, 16, 31, 23],  # 学生30
        [140, 88, 21, 36, 27],  # 学生31
        [130, 85, 19, 33, 29],  # 学生32
    ])

    # 目标值:期末总评成绩 - 确保复习时间与成绩负相关
    y = np.array([
        # 原始8个学生的成绩
        88.5, 76.2, 94.8, 71.5, 90.2, 81.6, 92.5, 73.8,

        # 新学生成绩 - 设计为复习时间与成绩负相关
        # 第一组:复习少但成绩好
        92.3, 89.7, 93.1, 87.9,

        # 第二组:复习多但成绩一般
        70.2, 65.8, 72.5, 64.9,

        # 第三组:中等复习时间
        82.4, 88.6, 84.3, 90.1,

        # 第四组:强化负相关
        95.5, 58.3, 92.8, 89.4,

        # 第五组:更多样本
        83.7, 89.2, 74.6, 93.7,

        # 第六组:最后一批
        94.8, 85.2, 88.9, 86.3,
    ])

    # 3.实例化
    estimator = LinearRegression()
    print(f'模型对象: {estimator}')

    # 4. 模型训练
    estimator.fit(x, y)

    # 5. 查看模型参数(重要!)
    print(f'\n=== 模型参数 ===')
    # 每个特征对应的"重要性分数" coef_ = [0.15, 0.8, 0.05, 0.1, 0.12]
    # 正负号表示正向/负向影响
    print(f'权重系数 (coef_): {estimator.coef_}')
    print(f'权重系数个数: {len(estimator.coef_)}')
    # 截距项 intercept_:所有特征为0时的基准成绩,例如 intercept_ = 50.0,表示即使所有特征都是0,也能得50分
    print(f'截距项 (intercept_): {estimator.intercept_:.4f}')

    # 6. 模型预测 - 预测一个新学生的成绩
    # 新学生数据:[学习时长, 作业均分, 互动次数, 预习时间, 复习时间]
    new_student = np.array([[125, 86, 18, 32, 28]])
    prediction = estimator.predict(new_student)
    print(f'\n=== 预测结果 ===')
    print(f'新学生特征: {new_student[0]}')
    print(f'预测成绩: {prediction[0]:.2f}')

    # 7. 模型评估(简单示例)
    # 计算训练集上的R²分数
    score = estimator.score(x, y)
    print(f'模型R²分数: {score:.4f}') #模型R²分数: 0.9785

    # 8. 保存模型
    import joblib
    joblib.dump(estimator, './model/multi_feature_lr_model.bin')
    print('\n模型已保存为: ./model/multi_feature_lr_model.bin')

    # 9. 验证模型加载和预测
    loaded_model = joblib.load('./model/multi_feature_lr_model.bin')
    test_pred = loaded_model.predict(new_student)
    print(f'加载模型后的预测验证: {test_pred[0]:.2f}')

注:R²分数解读指南(score = estimator.score(x, y))

R²范围 训练集上 测试集上 含义
< 0 灾难 灾难 模型比直接猜均值还差
0~0.3 很差 实际 模型解释力很弱,但有方向性
0.3~0.5 一般 不错 有一定预测能力,可用
0.5~0.7 较好 很好 模型相当可靠
0.7~0.9 很好 优秀 解释力很强
> 0.9 危险信号! 极好 可能过拟合了
相关推荐
ar01231 小时前
AR远程协助如何提升能源行业运维效率
人工智能·ar
爱写代码的小朋友1 小时前
AI教育产品市场中的用户信任危机与治理策略研究:基于多利益相关者视角的分析
人工智能
北京阿法龙科技有限公司1 小时前
AR眼镜仓储物流分拣技术应用与落地方案
运维·人工智能·ar·xr
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2025-12-05
人工智能·经验分享·深度学习·神经网络·产品运营
BruceWooCoder1 小时前
从零打造云端AI视频生成服务:基于CogVideoX和MCP协议的完整实践
人工智能·音视频
大千AI助手1 小时前
汉明距离:度量差异的基石与AI应用
人工智能·机器学习·距离度量·汉明距离·大千ai助手·hammingdistance·纠错码
我很哇塞耶1 小时前
AWS AgentCore重磅升级,三大新功能重塑AI代理开发体验
人工智能·ai·大模型
说私域1 小时前
社群媒体时代下“开源AI智能名片链动2+1模式S2B2C商城小程序”对社群运营的重要性研究
人工智能·开源·媒体
Akamai中国1 小时前
加速采用安全的企业级 Kubernetes 环境
人工智能·云计算·云服务·云存储