机器学习入门(三)之 梯度下降法

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

简介:

梯度下降法(Gradient Descent)严格地说其实不能算是一种机器学习的算法,而是属于一种优化算法,其目的在于基于搜索最小化一个损失函数,找到最优解。由于其简单又具有很好地效果,因此被广泛地运用在机器学习的算法中。

原理讲解:

假设在二维空间平面上,有函数如下:

在这里插入图片描述

因此我们要寻找到最低点,我们可以定义一个公式:y=y-ηy’(y’为y的导数)。当我们重复代入上述公式时,我们可以发现随着点逐渐下降,y’的值越来越小,直到寻找到最低点时y’的值为0,y值不再改变,这时我们就找到了最低点。

其中η我们称之为”学习效率”。不难发现η越小,我们代入公式的次数就越多,得到结果的速度也就越慢。但是η的值也不能取得太大,否则可能会出现第一次就越过了最低点,然后逐渐愈加偏离的情况:
在这里插入图片描述

梯度下降法不仅仅可以应用在二维的数据,多维的数据也同样适用,推广到多维时可如下图:

在这里插入图片描述

应用在多维事,我们可以运用之前学过的多元线性回归算法来帮助我们计算结果,并将线性回归得到的式子转换成矩阵的形式,我们就可以通过代码实现上述的算法了。

这里再拓展一种随机梯度下降法(上述方法我们通常成为批量梯度下降法),目的是让提高计算速度。因为上面的方法我们每次下降都需要计算所有的数据,这样子就需要大量的计算时间,而通过实验发现,即使是随机取其中一组数据进行计算,最终我们还是可以到达最低点的附近(这里类似于用精度换取时间)。

好了,大概思路就是这样子,接下来我们通过python代码实现上面的算法:

代码展示:

1、封装算法

  1. # 封装的多元线性回归的梯度下降算法
  2. import numpy as np
  3. from sklearn.metrics import r2_score
  4. class LinearRegression:
  5. def __init__(self):
  6. self.coef_ = None
  7. self.interception_ = None
  8. self._theta = None
  9. def fit_normal(self, x_train, y_train):
  10. assert x_train.shape[0] == y_train.shape[0], \
  11. "the size of x_train must be equal to the size of y_train"
  12. x_b = np.hstack([np.ones((len(x_train), 1)), x_train])
  13. self._theta = np.linalg.inv(x_b.T.dot(x_b)).dot(x_b.T).dot(y_train);
  14. self.interception_ = self._theta[0]
  15. self.coef_ = self._theta[1:]
  16. def fit_gd(self, x_train, y_train, eta=0.01, n_iters=1e4):
  17. assert x_train.shape[0] == y_train.shape[0], \
  18. "the size of x_train must be equal to the size of y_train"
  19. def lose(theta, x_b, y):
  20. try:
  21. return np.sum((y - x_b.dot(theta) ** 2)) / len(x_b)
  22. except:
  23. return float("inf")
  24. def Derivative(theta, x_b, y):
  25. return x_b.T.dot(x_b.dot(theta)-y)*2/len(x_b)
  26. def gradient_descent(x_b, y, init_theta, eta, epsilon=1e-8):
  27. theta = init_theta
  28. i_iters = 0
  29. while i_iters < n_iters:
  30. gradient = Derivative(theta, x_b, y)
  31. last_theta = theta
  32. theta = theta - eta * gradient
  33. if (abs(lose(theta, x_b, y) - lose(last_theta, x_b, y)) < epsilon):
  34. break
  35. i_iters += 1
  36. return theta
  37. x_b = np.hstack([np.ones((len(x_train), 1)), x_train])
  38. initial_theta = np.zeros(x_b.shape[1])
  39. self._theta = gradient_descent(x_b, y_train, initial_theta, eta, epsilon=1e-8)
  40. self.interception_ = self._theta[0]
  41. self.coef_ = self._theta[1:]
  42. return self
  43. def fit_random_gd(self, x_train, y_train, n_iters=5, t0=5, t1=50):
  44. assert x_train.shape[0] == y_train.shape[0], \
  45. "the size of x_train must be equal to the size of y_train"
  46. assert n_iters >= 1
  47. def Derivative(theta, x_b_i, y_i):
  48. return x_b_i*(x_b_i.dot(theta)-y_i)*2
  49. def random_gradient_descent(x_b, y, initial_theta):
  50. def learning_rate(t):
  51. return t0/(t+t1)
  52. theta = initial_theta
  53. m = len(x_b)
  54. for cur_iter in range(n_iters):
  55. indexes = np.random.permutation(m)
  56. x_b_new = x_b[indexes]
  57. y_new = y[indexes]
  58. for i in range(m):
  59. gradient = Derivative(theta, x_b_new[i], y_new[i])
  60. theta = theta - learning_rate(cur_iter*m+i)*gradient
  61. return theta
  62. x_b = np.hstack([np.ones((len(x_train), 1)), x_train])
  63. initial_theta = np.zeros(x_b.shape[1])
  64. self._theta = random_gradient_descent(x_b, y_train, initial_theta)
  65. self.interception_ = self._theta[0]
  66. self.coef_ = self._theta[1:]
  67. return self
  68. def predict(self, x_predict):
  69. assert x_predict.shape[1] == len(self.coef_), \
  70. "Simple Linear regressor can only solve single feature training data"
  71. assert self.interception_ is not None and self.coef_ is not None, \
  72. "must fit before predict!"
  73. x_b = np.hstack([np.ones((len(x_predict), 1)), x_predict])
  74. return x_b.dot(self._theta)
  75. def score(self, x_test, y_test):
  76. y_predict = self.predict(x_test)
  77. return r2_score(y_test, y_predict)
  78. def __repr__(self):
  79. return "LinearRegression()"

2、主函数:

  1. from sklearn import datasets
  2. from sklearn.model_selection import train_test_split
  3. from LR_GD_class import LinearRegression
  4. from sklearn.preprocessing import StandardScaler
  5. boston = datasets.load_boston()
  6. x = boston.data
  7. y = boston.target
  8. x = x[y < 50.0]
  9. y = y[y < 50.0]
  10. x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=666)
  11. standardScaler = StandardScaler()
  12. standardScaler.fit(x_train)
  13. x_train_stand = standardScaler.transform(x_train)
  14. x_test_stand = standardScaler.transform(x_test)
  15. # 批量梯度下降法
  16. lin_reg = LinearRegression()
  17. lin_reg.fit_gd(x_train_stand, y_train)
  18. print(lin_reg.score(x_test_stand, y_test))
  19. ## 随机梯度下降法
  20. lin_reg1 = LinearRegression()
  21. lin_reg1.fit_random_gd(x_train_stand, y_train, n_iters=50)
  22. print(lin_reg1.score(x_test_stand, y_test))

文章标签:

原文连接:https://juejin.cn/post/7096315783583809550

相关推荐

【机器学习基础】无监督学习(5)——生成模型

【机器学习的数学01】可数集与不可数集

机器学习:贝叶斯分类器详解(一)-贝叶斯决策理论与朴素贝叶斯

OneFlow v0.8.0正式发布

从“AI玩具”到“创作工具”的云原生改造之路

【深度学习】(一)机器学习基础

基于CLIP的色情图片识别;油管最新ML课程大合集;交互式编写shell管道;机器人仓库环境增量感知数据集;最新AI论文 | ShowMeAI资讯日报

数据脱敏系统【回顾】

机器学习强基计划0-2:什么是机器学习?和AI有什么关系?

拯救不开心!我的机器人心理医生;机器学习的KPI千里追踪术;YOLO v7的PyTorch实现;李航新书『机器学习方法』开放试读 | ShowMeAI资讯日报

深度学习 机器学习 数据集资源汇总

德国信贷数据建模baseline!

嘘!摸鱼神器,别让老板知道!| 语音实时转文本,时序快速出预测,YOLOv6在线就能用,一行命令整理CSV | ShowMeAI资讯日报

深度学习最全资料合集

裁员吵架散摊子

AI遮天传 ML-无监督学习

机器学习之线性回归详解

[科普文] 搞 Web3 要学习哪些基础知识?

股市预测,销量预测,病毒传播...一个时间序列建模套路搞定全部!⛵

花了6个月时间完成本科优秀毕业设计,我做了什么?