鱼C论坛

 找回密码
 立即注册
查看: 2361|回复: 3

[技术交流] python实现线性回归

[复制链接]
发表于 2020-11-14 10:23:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 糖逗 于 2020-11-14 13:01 编辑

参考书籍:《机器学习实战》

1.传统线性回归
  1. import numpy as np

  2. def loadDataSet(fileName):
  3.     numFeat = len(open(fileName).readline().split('\t')) - 1
  4.     dataMat = []
  5.     labelMat = []
  6.     fr = open(fileName)
  7.     for line in fr.readlines():
  8.         lineArr = []
  9.         curLine = line.strip().split('\t')
  10.         for i in range(numFeat):
  11.             lineArr.append(float(curLine[i]))
  12.         dataMat.append(lineArr)
  13.         labelMat.append(float(curLine[-1]))
  14.     return dataMat, labelMat


  15. def standRegres(xArr, yArr):
  16.     xMat = np.mat(xArr)
  17.     yMat = np.mat(yArr).T
  18.     xTx = xMat.T * xMat
  19.     if np.linalg.det(xTx) == 0:#矩阵不可逆,矩阵行列式为0
  20.         print("This matrix is singular, cannot do inverse")
  21.         return
  22.     ws = np.linalg.inv(xTx)*(xMat.T * yMat)
  23.     return ws




  24. if __name__ == "__main__":
  25.     import matplotlib.pyplot as plt

  26.     xArr, yArr = loadDataSet(r'C:\...\ex0.txt')
  27.     ws = standRegres(xArr, yArr)
  28.     xMat = np.mat(xArr)
  29.     yMat = np.mat(yArr)
  30.     yHat = xMat * ws

  31.     fig = plt.figure()
  32.     ax = fig.add_subplot(111)
  33.     #https://blog.csdn.net/lilong117194/article/details/78288795
  34.     ax.scatter(xMat[:, 1].flatten().A[0], yMat.T[:, 0].flatten().A[0])
  35.    
  36.     xCopy = xMat.copy()
  37.     xCopy.sort(0)#升序
  38.     yHat = xCopy * ws
  39.     ax.plot(xCopy[:, 1], yHat)
  40.     plt.show()
复制代码



2.局部加权线性回归
  1. import numpy as np

  2. def loadDataSet(fileName):
  3.     numFeat = len(open(fileName).readline().split('\t')) - 1
  4.     dataMat = []
  5.     labelMat = []
  6.     fr = open(fileName)
  7.     for line in fr.readlines():
  8.         lineArr = []
  9.         curLine = line.strip().split('\t')
  10.         for i in range(numFeat):
  11.             lineArr.append(float(curLine[i]))
  12.         dataMat.append(lineArr)
  13.         labelMat.append(float(curLine[-1]))
  14.     return dataMat, labelMat

  15. def lwlr(testPoint, xArr, yArr, k = 1.0):
  16.     xMat = np.mat(xArr)
  17.     yMat = np.mat(yArr).T
  18.     m = np.shape(xMat)[0]
  19.     weights = np.mat(np.eye((m)))
  20.     for j in range(m):                     
  21.         diffMat = testPoint - xMat[j,:]     
  22.         weights[j,j] = np.exp(diffMat * diffMat.T/(-2.0*k**2))#径向基核函数
  23.     xTx = xMat.T * (weights * xMat)
  24.     if np.linalg.det(xTx) == 0.0:
  25.         print("This matrix is singular, cannot do inverse")
  26.         return
  27.     ws = np.linalg.inv(xTx) * (xMat.T * weights * yMat)
  28.     return testPoint * ws

  29. def lwlrTest(testArr, xArr, yArr, k = 1.0):  
  30.     m = np.shape(testArr)[0]
  31.     yHat = np.zeros(m)
  32.     for i in range(m):
  33.         yHat[i] = lwlr(testArr[i],xArr,yArr,k)
  34.     return yHat

  35. if __name__ == "__main__":
  36.     xArr, yArr = loadDataSet(r'C:\...\ex0.txt')
  37.     lwlr(xArr[0], xArr, yArr, 1)#单个点的估计
  38.     yHat = lwlrTest(xArr, xArr, yArr, 0.003)
  39.     xMat = np.mat(xArr)
  40.     srtInd = xMat[:, 1].argsort(0)
  41.     xSort = xMat[srtInd][:, 0, :]
  42.     import matplotlib.pyplot as plt
  43.     fig = plt.figure()
  44.     ax = fig.add_subplot(111)
  45.     ax.plot(xSort[:, 1], yHat[srtInd])
  46.     ax.scatter(xMat[:, 1].flatten().A[0], np.mat(yArr).T.flatten().A[0],
  47.                s = 2, c = 'red')
  48.     plt.show()
复制代码



3.岭回归
  1. import numpy as np

  2. def loadDataSet(fileName):
  3.     numFeat = len(open(fileName).readline().split('\t')) - 1
  4.     dataMat = []
  5.     labelMat = []
  6.     fr = open(fileName)
  7.     for line in fr.readlines():
  8.         lineArr = []
  9.         curLine = line.strip().split('\t')
  10.         for i in range(numFeat):
  11.             lineArr.append(float(curLine[i]))
  12.         dataMat.append(lineArr)
  13.         labelMat.append(float(curLine[-1]))
  14.     return dataMat, labelMat

  15. def ridgeRegres(xMat, yMat, lam = 0.2):
  16.     xTx = xMat.T * xMat
  17.     denom = xTx + np.eye(np.shape(xMat)[1]) * lam
  18.     if np.linalg.det(denom) == 0:
  19.         print("This matrix is singular, cannot do inverse")
  20.         return
  21.     ws = np.linalg.inv(denom) * (xMat.T * yMat)
  22.     return ws

  23. def ridgeTest(xArr, yArr):
  24.     xMat = np.mat(xArr)
  25.     yMat = np.mat(yArr).T
  26.     yMean = np.mean(yMat,0)
  27.     yMat = yMat - yMean   
  28.     xMeans = np.mean(xMat,0)
  29.     xVar = np.var(xMat,0)      
  30.     xMat = (xMat - xMeans)/xVar
  31.     numTestPts = 30#30个不同的lambda
  32.     wMat = np.zeros((numTestPts, np.shape(xMat)[1]))
  33.     for i in range(numTestPts):
  34.         ws = ridgeRegres(xMat, yMat, np.exp(i-10))
  35.         wMat[i, :] = ws.T
  36.     return wMat

  37. if __name__ == "__main__":
  38.     abX, abY = loadDataSet(r'C:\...\abalone.txt')
  39.     ridgeWeights = ridgeTest(abX, abY)
  40.     import matplotlib.pyplot as plt
  41.     fig = plt.figure()
  42.     ax = fig.add_subplot(111)
  43.     ax.plot(ridgeWeights)#一共有八条线,代表不同lambda下8个特征的取值情况
  44.     plt.show()
复制代码


4.前向逐步回归
  1. import numpy as np

  2. def loadDataSet(fileName):
  3.     numFeat = len(open(fileName).readline().split('\t')) - 1
  4.     dataMat = []
  5.     labelMat = []
  6.     fr = open(fileName)
  7.     for line in fr.readlines():
  8.         lineArr = []
  9.         curLine = line.strip().split('\t')
  10.         for i in range(numFeat):
  11.             lineArr.append(float(curLine[i]))
  12.         dataMat.append(lineArr)
  13.         labelMat.append(float(curLine[-1]))
  14.     return dataMat, labelMat

  15. def regularize(xMat):
  16.     inMat = xMat.copy()
  17.     inMeans = np.mean(inMat,0)   
  18.     inVar = np.var(inMat,0)     
  19.     inMat = (inMat - inMeans)/inVar
  20.     return inMat

  21. def rssError(yArr, yHatArr):
  22.     return ((yArr-yHatArr)**2).sum()

  23. def stageWise(xArr, yArr, eps = 0.01, numIt = 100):
  24.     xMat = np.mat(xArr)
  25.     yMat = np.mat(yArr).T
  26.     yMean = np.mean(yMat, 0)
  27.     yMat = yMat - yMean     
  28.     xMat = regularize(xMat)
  29.     m, n = np.shape(xMat)
  30.     ws = np.zeros((n, 1))
  31.     returnMat = np.zeros((numIt, n))
  32.     wsMax = ws.copy()
  33.     for i in range(numIt):
  34.         lowestError = np.inf;
  35.         for j in range(n):
  36.             for sign in [-1, 1]:#增大或减少特征值
  37.                 wsTest = ws.copy()
  38.                 wsTest[j] += eps * sign
  39.                 yTest = xMat * wsTest
  40.                 rssE = rssError(yMat.A,yTest.A)
  41.                 if rssE < lowestError:
  42.                     lowestError = rssE
  43.                     wsMax = wsTest
  44.         ws = wsMax.copy()
  45.         returnMat[i,:] = ws.T
  46.     return returnMat

  47. if __name__ == "__main__":
  48.     xArr, yArr = loadDataSet(r'C:\...\abalone.txt')
  49.     res = stageWise(xArr, yArr, 0.01, 5000)
  50.     import matplotlib.pyplot as plt
  51.     fig = plt.figure()
  52.     ax = fig.add_subplot(111)
  53.     ax.plot(res)#一共有八条线,代表不同lambda下8个特征的取值情况
  54.     plt.show()
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-11-14 12:32:37 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-11-14 13:08:09 | 显示全部楼层
补充一个知识点:python中x.I就是对矩阵x求逆矩阵
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-7 16:06:04 | 显示全部楼层
本帖最后由 糖逗 于 2020-12-7 16:20 编辑

基于批梯度参数更新的线性回归
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. #计算损失函数
  4. def compute_error_for_line_given_points(b, w, points):
  5.     totalError = 0
  6.     for i in range(0, len(points)):
  7.         x = points[i, 0]
  8.         y = points[i, 1]
  9.         totalError += (y - (w * x + b)) ** 2
  10.     return totalError / len(points)

  11. #计算梯度(批梯度下降,计算一次梯度使用所有样本),更新参数
  12. #一次参数更新计算
  13. def step_gradient(b_current, w_current, points, learningRate):
  14.     b_gradient = 0
  15.     w_gradient = 0
  16.     N = len(points)
  17.     for i in range(N):
  18.         x = points[i, 0]
  19.         y = points[i, 1]
  20.         #grad_b = 2(wx + b - y)
  21.         b_gradient += (2 / N) * ((w_current * x + b_current) - y)
  22.         #grad_w = 2(wx+b-y)*x
  23.         w_gradient += (2/ N) * x * ((w_current * x + b_current) - y)
  24.     new_b = b_current - (learningRate * b_gradient)
  25.     new_w = w_current - (learningRate * w_gradient)
  26.     return [new_b, new_w]

  27. #多次梯度下降计算迭代
  28. def gradient_descent_runner(points, starting_b, starting_w, learning_rate, num_iterations):
  29.     b = starting_b
  30.     w = starting_w
  31.     for i in range(num_iterations):
  32.         b, w = step_gradient(b, w, np.array(points), learning_rate)
  33.     return [b, w]


  34. if __name__ == "__main__":
  35.     points = [[6, 24], [2, 80], [9, 2], [1, 100], [2, 98], [10, 12], [4, 77], [4.5, 60],[6.5, 15]]
  36.     plt.scatter(x = np.array(points)[:,0] , y = np.array(points)[:,1])
  37.     b, w = gradient_descent_runner(points, 100, -10, 0.02, 500)#初始化参数选取很重要,尤其是学习率
  38.     x = np.random.rand(100) * 10
  39.     y = np.array([])
  40.     for i in range(len(x)):
  41.         y = np.append(y, w * x[i] + b)
  42.     plt.plot(x, y)
复制代码


代码源自:《Tensorflow深度学习》(龙良曲)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-20 06:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表