• [从0开始机器学习]2.多元一次函数线性回归


    🐺本博主博客:ζั͡ ั͡雾 ั͡狼 ั͡✾的博客

    🎀专栏:机器学习

    🎀专栏:爬虫

    🎀专栏:OpenCV图像识别处理

    🎀专栏:Unity2D


    ⭐本节课理论视频:

    P12-P17 矩阵及其矩阵特点

    P18-P22 多元函数回归

    ⭐本节课推荐其他人笔记:吴恩达机器学习系列课程笔记——第四章

    🐺机器学习通过文字描述是难以教学学会的,每一节课我会推荐这个理论的网课,一定要看上面的理论视频!一定要看上面的理论视频!一定要看上面的理论视频!所以我只是通过代码实现,并通过注释形式来详细讲述每一步的原因,最后通过画图对比的新式来看结果比较。

    ⭐机器学习推荐博主:GoAI的博客_CSDN博客-深度学习,机器学习,大数据笔记领域博主

    😊如果你什么都不懂机器学习,那我推荐GoAI的入门文章:机器学习知识点全面总结_GoAI的博客-CSDN博客_机器学习笔记

    (1)对上节课一元一次回归进行扩展成矩阵形式

    1. import numpy as np
    2. import matplotlib.pyplot as plt
    3. # 全局变量
    4. # 生成数据
    5. #X中每一行代表一条数据i,代表着一个等式,其中列数代表着变量数,每个变量的系数是不知道的
    6. #每一行数据是y=k0x0+k1x1+k2x2+k3x3+k4x4,
    7. #k是我们要回归的系数向量,x1,x2,x3,x4是每一行数据其中
    8. # k0代表常数,x0恒为1
    9. X =np.array([[5,100,58,-3],
    10. [7,120,59,-3],
    11. [3,140,50,-5],
    12. [10,80,45,-1],
    13. [6,96,55,-7],
    14. [15,200,52,-11],
    15. [11,125,65,-5],
    16. [12,63,100,-3],
    17. [20,500,66,-10]])
    18. #假设K系数为这个,咱们的算法就是逼近这个结果,当然,如果有自己的数据就更好了
    19. preK=[12,-1,2,8]+np.random.random((1,4))
    20. #Y中的数据量等于X矩阵的行数
    21. Y=(np.dot(preK,X.T)+np.random.random()*15).ravel()#加的一项是随机常数项,最后将矩阵转换成数组向量
    22. #开始
    23. # 学习率,在代价函数斜率线上移动的距离步子大小
    24. A = 0.000001
    25. # 迭代次数
    26. time = 100000
    27. #X矩阵中第一列加入x0=1参数
    28. X=np.insert(X,0,np.ones((1,len(X))),axis=1)
    29. #数据个数
    30. m=len(X)
    31. #参数个数
    32. n=len(X[0])
    33. #输出
    34. print(f"有{n}个参数,就是X列数算上常数项所乘的单位1")
    35. print(f"有{m}条数据,就是加常数后X行数")
    36. #系数变量K矩阵就是多元参数的系数,就是我们要递归的重点变量,先给这个矩阵的每个值都赋予初始值1
    37. K=np.ones(n)
    38. # 假设函数,假设是个多元线性函数,每个参数的系数和常数不知道,是要回归算的变量
    39. #返回系数矩阵乘参数矩阵
    40. #下面的变量Xi代表一条数据,既X矩阵的一行
    41. def H(Xi):
    42. global K
    43. return np.dot(K,Xi.T)#xi需要转置,才能得到内积和
    44. # 代价函数L=求和((H(x)-y(x))^2),其中H是关于K矩阵中所有系数参数的函数
    45. # 代价函数就是你估算的值与实际值的差的大小,使得代价函数最小,这样就能不断逼近结果
    46. # 使得代价函数最小,就要使得初始点在斜率线上不断往低处移动,呈现出系数的不断微小移动
    47. # 固定公式格式,推导原理看吴恩达P11
    48. def dL_K(): # 代价函数对矩阵中系数参数k求导
    49. global X,Y,K,m,n
    50. dL_Karr=np.empty(n)#数组用来存放L对每个k求导后的结果
    51. for j in range(n):
    52. ans = 0
    53. for i in range(m):
    54. ans += ((H(X[i]) - Y[i]) * X[i][j]) # 由于k的系数是x,所以求导后还要乘x
    55. dL_Karr[j]=ans
    56. return dL_Karr
    57. def itreation(time): # 迭代,使O1,O2的代价函数趋于最低点
    58. global K
    59. for i in range(time):
    60. #一次迭代过程中代价函数对系数k的导数数组
    61. dL_Karr=dL_K()
    62. # 同时变化,减法原因是正斜率使得O更小,负斜率使得O更大,不断往低处移动即代价函数最小
    63. K=K-A*dL_Karr
    64. if (i % 10000== 0): # 每100次输出一次
    65. print(f"迭代了{i}次,变量的系数矩阵K为{K}")
    66. if __name__ == "__main__":
    67. print(X)
    68. print(Y)
    69. itreation(time)
    70. print(preK)

     A学习率要调的足够小,K系数矩阵结果才不会发散,但太小迭代的很慢,还有可能超出数组的大小限制,并且结果并不容易找到,所以要做一下吴恩达老师说的归一化步骤是很重要的

    (2)加上归一化步骤

    1. import numpy as np
    2. import matplotlib.pyplot as plt
    3. # 全局变量
    4. # 生成数据
    5. #X中每一行代表一条数据i,代表着一个等式,其中列数代表着变量数,每个变量的系数是不知道的
    6. #每一行数据是y=k0x0+k1x1+k2x2+k3x3+k4x4,
    7. #k是我们要回归的系数向量,x1,x2,x3,x4是每一行数据其中
    8. # k0代表常数,x0恒为1
    9. X =np.array([[5,100,58,-3],
    10. [7,120,59,-3],
    11. [3,140,50,-5],
    12. [10,80,45,-1],
    13. [6,96,55,-7],
    14. [15,200,52,-11],
    15. [11,125,65,-5],
    16. [12,63,100,-3],
    17. [20,500,66,-10]])
    18. #假设K系数为这个,咱们的算法就是逼近这个结果,当然,如果有自己的数据就更好了
    19. preK=[12,-1,2,8]+np.random.random((1,4))
    20. #Y中的数据量等于X矩阵的行数
    21. Y=(np.dot(preK,X.T)+np.random.random()*15).ravel()#加的一项是随机常数项,最后将矩阵转换成数组向量
    22. #进行归一化操作
    23. #获取每列平均值
    24. u=np.average(X,axis=0)
    25. #获取没列的标准差
    26. s=np.std(X,axis=0)
    27. #按行复制,构成X同形状矩阵
    28. U=np.repeat([u],len(X),axis=0)
    29. S=np.repeat([s],len(X),axis=0)
    30. #归一化,注意归一化所求的系数矩阵K是(X-U)/S的系数,真正系数,需要将x参数前面的系数合并
    31. X=(X-U)/S
    32. #开始
    33. # 学习率,在代价函数斜率线上移动的距离步子大小
    34. A = 0.0001
    35. # 迭代次数
    36. time = 100000
    37. #X矩阵中第一列加入x0=1参数
    38. X=np.insert(X,0,np.ones((1,len(X))),axis=1)
    39. #数据个数
    40. m=len(X)
    41. #参数个数
    42. n=len(X[0])
    43. #输出
    44. print(f"有{n}个参数,就是X列数算上常数项所乘的单位1")
    45. print(f"有{m}条数据,就是加常数后X行数")
    46. #系数变量K矩阵就是多元参数的系数,就是我们要递归的重点变量,先给这个矩阵的每个值都赋予初始值1
    47. K=np.ones(n)
    48. # 假设函数,假设是个多元线性函数,每个参数的系数和常数不知道,是要回归算的变量
    49. #返回系数矩阵乘参数矩阵
    50. #下面的变量Xi代表一条数据,既X矩阵的一行
    51. def H(Xi):
    52. global K
    53. return np.dot(K,Xi.T)#xi需要转置,才能得到内积和
    54. # 代价函数L=求和((H(x)-y(x))^2),其中H是关于K矩阵中所有系数参数的函数
    55. # 代价函数就是你估算的值与实际值的差的大小,使得代价函数最小,这样就能不断逼近结果
    56. # 使得代价函数最小,就要使得初始点在斜率线上不断往低处移动,呈现出系数的不断微小移动
    57. #注意归一化所求的系数矩阵K是(X-U)/S的系数,真正系数,需要将x参数前面的系数合并
    58. # 固定公式格式,推导原理看吴恩达P11
    59. def dL_K(): # 代价函数对矩阵中系数参数k求导
    60. global X,Y,K,m,n
    61. dL_Karr=np.empty(n)#数组用来存放L对每个k求导后的结果
    62. for j in range(n):
    63. ans = 0
    64. for i in range(m):
    65. ans += ((H(X[i]) - Y[i]) * X[i][j]) # 由于k的系数是x,所以求导后还要乘x
    66. dL_Karr[j]=ans
    67. return dL_Karr
    68. def itreation(time): # 迭代,使O1,O2的代价函数趋于最低点
    69. global K
    70. for i in range(time+1):
    71. #一次迭代过程中代价函数对系数k的导数数组
    72. dL_Karr=dL_K()
    73. # 同时变化,减法原因是正斜率使得O更小,负斜率使得O更大,不断往低处移动即代价函数最小
    74. K=K-A*dL_Karr
    75. if (i % 10000== 0): # 每100次输出一次
    76. print(f"迭代了{i}次,变量的系数矩阵K为{K}")
    77. if __name__ == "__main__":
    78. print('归一化X',X)
    79. print(Y)
    80. itreation(time)
    81. print('归一化系数(第一个是常数)',K,)
    82. #注意归一化所求的系数矩阵K是(X-U)/S的系数,真正系数,需要将x参数前面的系数合并
    83. #忽略前一位常数,计算真正系数
    84. K[1:]=K[1:]/s
    85. #利用真正系数,计算真正常数
    86. K[0]=K[0]-np.sum(K[1:]*u)
    87. print('真正系数矩阵',K)
    88. print('目标系数',preK)

    可见,归一化后,A可以大一些,10000次K已经变化微小了,递归更快,更准

  • 相关阅读:
    TensorFlow自定义训练函数
    常用xshell中使用的linux命令
    PROBIS铂思金融破产后续:ASIC牌照已注销
    spring实战笔记
    Python获取 只因 弹幕数据+制作词云分析.........就差唱、跳、rap不会了
    POSTGIS数据库操作
    groovy在SpringBoot中的使用
    【深度学习实验】前馈神经网络(七):批量加载数据(直接加载数据→定义类封装数据)
    Qt4升级到Qt5中文乱码问题的解决
    SpringBoot3学习笔记01
  • 原文地址:https://blog.csdn.net/qq_54263076/article/details/127457509