乐趣区

关于机器学习:三机器学习算法篇线性回归2

1. 梯度降落法

上文写的求解损失函数的最小二乘法

除了最小二乘法还能够应用梯度降落求解。
咱们先随机给 θ 一个值,而后朝着负梯度的方向挪动,也就是迭代,每次失去的 θ 值应用 J(θ)比之前更小。


这个 α 是指学习率,或者说是步长,这个影响的迭代的快慢。

咱们函数 y = (x – 0.1)²/ 2 为例,应用梯度降落的办法,求其 y 达到最小时,x 的值
代码示例

# coding:utf-8
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager


font = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=25)

class OneGard(object):
    def __init__(self,fx,hx):
        """
        :param fx: 原函数
        :param hx: 导函数
        """
        self.fx = fx
        self.hx = hx
        self.x = None
        self.GD_X = []
        self.GD_Y = []
        self.iter_num = 0
        self.f_change = None
        self.f_current = None

    def gard_fun(self,x, alpha=0.5):
        """
        梯度降落
        :param x: 初始随机 x 值
        :param alpha: 学习率
        :return:
        """
        self.x = x
        self.f_change = self.fx(self.x)
        self.f_current = self.f_change
        self.GD_X.append(x)
        self.GD_Y.append(self.f_current)
        while self.f_change > 1e-10 and self.iter_num < 100:
            self.iter_num += 1
            self.x = self.x - alpha * self.hx(self.x)
            tmp = self.fx(self.x)
            self.f_change = np.abs(self.f_current - tmp)
            self.f_current = tmp
            self.GD_X.append(self.x)
            self.GD_Y.append(self.f_current)


def f(x):
    """
    y = (x - 0.1)²/2
    :param x:
    :return:
    """
    return (x - 0.1) ** 2 /2

def h(x):
    """
    y = (x - 0.1)²/ 2 的导数
    :param x:
    :return:
    """
    return (x - 0.1)



gard = OneGard(f, h)
gard.gard_fun(x=4,alpha=0.5)

print("最终 x:{:.2f},y:{:.2f}" .format(gard.x, gard.f_current))
print("迭代次数{}" .format(gard.iter_num))
print("迭代过程 x 的取值:\n{}".format(gard.GD_X))

# 画图
X = np.arange(-4, 4.5, 0.05)
Y = np.array(list(map(lambda t: f(t), X)))

plt.figure(figsize=(20,10), facecolor='w')
plt.plot(X, Y, 'r-', linewidth=2)
plt.plot(gard.GD_X, gard.GD_Y, 'bo--', linewidth=2)

plt.show()

后果为

最终 x:0.10,y:0.00
迭代次数 19
迭代过程 x 的取值:
[4, 2.05, 1.075, 0.5874999999999999, 0.34374999999999994, 0.221875, 0.1609375, 0.13046875000000002, 0.11523437500000001, 0.10761718750000002, 0.10380859375000001, 0.10190429687500001, 0.1009521484375, 0.10047607421875, 0.10023803710937501, 0.10011901855468751, 0.10005950927734375, 0.10002975463867188, 0.10001487731933595, 0.10000743865966798]

图像如下:

机器学习中梯度降落罕用的有三种:
批量梯度降落 (BGD)、随机梯度降落(SGD)、小批量梯度降落(MBGD)。
参考 梯度降落法的三种模式 BGD、SGD 以及 MBGD
(这个写的分明明了,以前学的时候,脑子听成了浆糊,看了这篇文,我是恍然大悟)

2. 多项式回归

线性回归针对的是 θ 而言是一种, 对于样本自身而言, 样本能够是非线性的。
例如

这时咱们能够领 x1 = x, x2 = x²,
失去如下

这样就转变成咱们的相熟的线性回归。

多项式扩大,就是将低纬度空间的点映射到高纬度空间中。

3. 其余线性回归

3.1Ridge 回归

线性回归的 L2 正则化通常称为 Ridge 回归,也叫作岭回归,与规范线性回归的差别,在于它在损失函数上减少了一个 L2 正则化的项。

λ 是常数系数,是正则化系数,属于一个超参数,须要调参。
λ 太小就会失去解决过拟合的能力,太大就会因力度过大而呈现欠拟合的景象。

3.2 LASSO 回归

应用 L1 正则的线性回归模型就称为 LASSO 回归,和 Ridge 回归区别在于,它加的是 L1 正则化的项。

3.3 弹性网络

弹性网络,Elasitc Net,同时应用 L1 正则和 L2 正则

3.4 Ridge 回归和 LASSO 回归比拟

1)两者都能够都能够来解决规范线性回归的过拟合问题。
2)LASSO 能够用来做特征选择,但 Ridge 回归则不行,因为 LASSO 可能使得不重要的变量的系数变为 0,而 Ridge 回归则不行。
参考 线性回归、lasso 回归、岭回归以及弹性网络的零碎解释

4. 代码示例

岭回归预测波士顿房价

from sklearn.datasets import load_boston
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

from matplotlib import pyplot as plt
from matplotlib import font_manager

font = font_manager.FontProperties(fname="/usr/share/fonts/wps-office/msyhbd.ttf", size=25)

def radge_fun():
   """
   岭回归预测波士顿房价
   :return:
   """
   lb = load_boston()

   x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.2)

   x_std = StandardScaler()
   y_std = StandardScaler()

   x_train = x_std.fit_transform(x_train)
   x_test = x_std.transform(x_test)
   y_train = y_std.fit_transform(y_train.reshape(-1,1))
   y_test = y_std.transform(y_test.reshape(-1,1))

   model = Ridge(alpha=1.0)

   model.fit(x_train, y_train)

   y_predict = y_std.inverse_transform(model.predict(x_test))
   return y_predict, y_std.inverse_transform(y_test)


def draw_fun(y_predict, y_test):
   """
   绘制房价预测与实在值的散点和折线图
   :param y_predict:
   :param y_test:
   :return:
   """
   x = range(1,len(y_predict)+1)
   plt.figure(figsize=(25, 10), dpi=80)
   plt.scatter(x, y_test, label="实在值",color='blue')
   plt.scatter(x, y_predict,label='预测值', color='red')
   plt.plot(x,y_test)
   plt.plot(x,y_predict)

   x_tick = list(x)
   y_tick = list(range(0,60,5))

   plt.legend(prop=font, loc='best')
   plt.xticks(list(x), x_tick)
   plt.yticks(y_tick)
   plt.grid(alpha=0.8)
   plt.show()


if __name__ == '__main__':
   y_predict, y_test = radge_fun()
   draw_fun(y_predict, y_test)
   

后果

退出移动版