博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bobo老师机器学习笔记第六课-梯度下降法在线性回归中的应用
阅读量:4170 次
发布时间:2019-05-26

本文共 6932 字,大约阅读时间需要 23 分钟。

在上一篇博客中大概介绍了一下,那么梯度下降法在线性回归中如何更好的应用了,本篇博客做一介绍。

在BoBo老师的课程中,梯度下降法主要讲了2中,批量梯度下降法(Batch Gradient Descent)和随机梯度下降法(Stochastic Gradient Descent)。 

一、理论介绍

1、批量梯度下降法(Batch Gradient Descent)

损失函数以及未使用向量化的方程:

进行向量化后的梯度方程:

从上图方程中可以看出,每一次求theta的值都要把所有的样本遍历一遍,所以这是为什么成为批量梯度下降法。

2、随机梯度下降法(Stonastic Gradient Descent)

损失函数不变,但计算计算梯度的方法如下:

从上图的公式可以看出,计算梯度是随机取出其中一个样本进行计算的。此外还要注意学习率的区别:

a一般取5,b为50,i_iters表示当前迭代的次数。 而这个值在批量梯度学习算法中是一个常量,一般是0.01 

二、在线性回归中的应用

# -*- coding: utf-8 -*-import numpy as npfrom metrics import r2_scoreclass LinearRegression(object):    def __init__(self):        self.coef_ = None  # 表示系数        self.intercept_ = None  # 表示截距        self._theta = None  # 过程计算值,不需要暴露给外面    def fit_normal(self, X_train, y_train):        """根据训练数据集X_train, y_train, 利用正规方程进行训练Linear Regression模型,利用正规方程训练的时候就不需要对数据进行向量化"""        assert X_train is not None and y_train is not None, "训练集X和Y不能为空"        assert X_train.shape[0] == y_train.shape[0], "训练集X和Y的样本数要相等"        # np.linalg.inv(X) 表示求X的逆矩阵        # 不能忘了X要增加一列,第一列数据为0        ones = np.ones(shape=(len(X_train), 1))        X_train = np.hstack((ones, X_train))        self._theta = np.linalg.inv(X_train.T.dot(X_train)).dot(X_train.T).dot(y_train)        self.intercept_ = self._theta[0]        self.coef_ = self._theta[1:]    def fit_gd(self, X_train, y_train, eta=0.01, n_iters=1e4):        """        用批量梯度下降法训练模型        :param X_train: 经过向量化的特征数据        :param y_train:        :param eta: 步长        :param n_iters: 迭代次数        :return:        """        def J(theta, X_b, y):            """            损失函数            此处要注意:X_b相对于原特征矩阵多了一列 n * 1的列向量, 所以X_b是(m, n+1)的矩阵            :return:            """            return np.sum((y - X_b.dot(theta)) ** 2) / len(y)        def DJ(theta, X_b, y):            """            获取梯度            :return:            """            # 注释掉的算法是不用向量计算的实现            # res = np.empty(len(theta))            # res[0] = np.sum(X_b.dot(theta) - y)            # for i in range(1, len(theta)):            #     res[i] = (X_b.dot(theta) - y).dot(X_b[:, i])            # return res * 2 / len(X_b)            return X_b.T.dot(X_b.dot(theta) - y) * 2 / len(X_b)        def gredient_descent(X_b, y, theta, n_inters=1e4, eta=0.01, epsilon=1e-8):            """            利用批量梯度下降法训练线性回归            :param X_b: 是(m, n+1)的矩阵            :param y:            :param init_ethta: etha初始化值            :param n_inters: 迭代次数            :param eta: 变化率步长, 默认是0.01            :param epsilon: 精度,用来比较当前etha和上一次etha差值            :return:            """            cur_inter = 0            while cur_inter < n_inters:                last_theta = theta                theta = theta - eta * DJ(theta, X_b, y)                if abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon:                    break                cur_inter += 1            return theta        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])        init_ethta = np.zeros(X_b.shape[1])        self._theta = gredient_descent(X_b, y_train, init_ethta, eta=eta, n_inters=n_iters)        self.coef_ = self._theta[1:]        self.intercept_ = self._theta[0]        return self    def fit_sgd(self, X_train, y_train, n_iters=5, t0=5.0, t1=50.0):        """        利用随机梯度下降法训练线性回归        :param X_train: 向量化的特征值        :param y_train:        :param n_iters: 迭代次数        :param t0: 用来计算学习率        :param t1: 用来计算学习率        :return:        """        def DJ(theta, X_b_i, y_i):            """            获取梯度            X_b_i: 是X_b向量中的一个样本            :return:            """            return X_b_i.T.dot(X_b_i.dot(theta) - y_i) * 2        def sgd(X_b, y, theta, n_inters, t0, t1):            def learning_rate(t):                return t0 / (t + t1)            m = len(X_b)            for cur_index in range(n_inters):                indexs = np.random.permutation(m)                X_b_new = X_b[indexs]                y_new = y[indexs]                for i in range(m):                    gradient = DJ(theta, X_b_new[i], y_new[i])                    theta = theta - learning_rate(cur_index * m + i) * gradient            return theta        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])        initial_theta = np.random.randn(X_b.shape[1])        self._theta = sgd(X_b, y_train, initial_theta, n_iters, t0, t1)        self.coef_ = self._theta[1:]        self.intercept_ = self._theta[0]    def predict(self, X_test):        """给定待预测数据集X_test,返回表示X_test的结果向量"""        assert X_test.shape[1] == self.coef_.shape[0], '测试集X的特征值个数不对'        ones = np.ones(shape=(len(X_test), 1))        X_test = np.hstack((ones, X_test))        return X_test.dot(self._theta)    def score(self, X_test, y_test):        """根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""        assert X_test.shape[0] == y_test.shape[0], '测试集X和Y的个数不相等'        return r2_score(y_test, self.predict(X_test))    def __repr__(self):        return '%s(coef_:%s, intercept_:%s)' % (self.__class__.__name__, self.coef_, self.intercept_)
def test_regession_using_gd():    from linearregression import LinearRegression    # step 1: 创建训练数据    m = 10000  # 假设10000个样本    x = np.random.normal(size=m)    X = x.reshape(-1, 1)    y = 4. * x + 3. + np.random.normal(0, 3, size=m)    # step 2: 数据标准化    X_train, X_test, y_train, y_test = train_test_split(X, y)    standardscaler = StandardScaler()    standardscaler.fit(X_train)    x_train_standard = standardscaler.transform(X_train)    # step 3: 训练模型    lrg = LinearRegression()    # 批量梯度下降法    # lrg.fit_gd(x_train_standard, y_train, eta=0.001, n_iters=1e6)    # 随机梯度下降法    lrg.fit_sgd(x_train_standard, y_train)    # step 4: 获取评分    x_test_standard = standardscaler.transform(X_test)    print 'score:', lrg.score(x_test_standard, y_test)

运行结果:

批量梯度下降法

LinearRegression(coef_:[4.01485425], intercept_:3.0079330321024687)

score: 0.6569687845397328

随机梯度下降法

LinearRegression(coef_:[3.96601229], intercept_:3.030732598906986) score: 0.644882902625483

三、在Sklearn中的实现

def test_sklearn():    # step 1: 创建训练数据    m = 10000  # 假设10000个样本    x = np.random.normal(size=m)    X = x.reshape(-1, 1)    y = 4. * x + 3. + np.random.normal(0, 3, size=m)    # step 2: 数据标准化    X_train, X_test, y_train, y_test = train_test_split(X, y)    standardscaler = StandardScaler()    standardscaler.fit(X_train)    x_train_standard = standardscaler.transform(X_train)    # step 3:调用sklearn模型    from sklearn.linear_model import SGDRegressor    # 随机梯度下降法    sgr = SGDRegressor()    sgr.fit(x_train_standard, y_train)    print sgr    # step 4: 获取评分    x_test_standard = standardscaler.transform(X_test)    print 'score:', sgr.score(x_test_standard, y_test)

运行结果:

SGDRegressor(alpha=0.0001, average=False, epsilon=0.1, eta0=0.01,       fit_intercept=True, l1_ratio=0.15, learning_rate='invscaling',       loss='squared_loss', max_iter=None, n_iter=None, penalty='l2',       power_t=0.25, random_state=None, shuffle=True, tol=None, verbose=0,       warm_start=False)score: 0.6465744359869433

要是你在西安,感兴趣一起学习AIOPS,欢迎加入QQ群 860794445

转载地址:http://vhkai.baihongyu.com/

你可能感兴趣的文章
2018.3.19
查看>>
A Game of Thrones(97)
查看>>
A Game of Thrones(98)
查看>>
2018.3.20
查看>>
2018.3.21
查看>>
2018.3.22
查看>>
2018.3.23
查看>>
A Game of Thrones(102)
查看>>
2018.4.29
查看>>
2018.4.30
查看>>
2018.4.31
查看>>
2018.4.32
查看>>
2018.4.33
查看>>
《python基础教程》答案(第一章)
查看>>
2018.4.34
查看>>
2018.4.35
查看>>
2018.4.36
查看>>
我为什么要写博客
查看>>
如何导入pycharm无法导入的包
查看>>
2018.4.37
查看>>