当前位置:   article > 正文

机器学习-线性回归_研究线性回归的机器学习

研究线性回归的机器学习

线性回归

一、算法思想

回归分析是一种预测性建模技术,它是研究因变量自变量之间的关系,这种技术通常用于预测分析,时间序列模型以及发现变量之间的因果关系,通常使用直线或曲线进行拟合,目标是使曲线到目标点的距离差最小。线性回归是回归问题中的一种,线性回归假设目标值与特征之间线性相关,即满足一个多元一次方程。通过构建损失函数,来求解损失函数最小时的参数 ω \omega ω b b b

二、算法推导

1、线性回归

通常线性回归可以表达成以下公式: y ^ = ω x + b \widehat y = \omega x + b y =ωx+b。其中 y ^ \widehat y y 为预测值,为了构建这个函数关系,通过已知的点 ( x , y ) (x,y) (x,y)来求解参数 ω \omega ω b b b

2、损失函数

为了评价所求参数的好与不好,需要一个标准来衡量,因此需要构建一个目标函数,使计算机通过已有数据对目标函数不断进行优化。因此,目标函数定义如下:

L = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 L = \frac{1}{n}\sum\limits_{i = 1}^n {{{({{\widehat y}_i} - {y_i})}^2}} L=n1i=1n(y iyi)2 (1)

其中, y ^ i \widehat y_i y i 为模型的预测值, y i y_i yi 为真实值, n n n 为数据点的个数。该损失函数表示的意义为样本预测值与真实值之间的平均平方和,即MSE.将公式(1)带入目标函数中,求解的参数 ω \omega ω b b b可以看做是函数 L L L的自变量,因此函数可以写成:

L ( ω , b ) = 1 n ∑ i = 1 n ( ω x i + b − y i ) 2 L(\omega ,b) = \frac{1}{n}\sum\limits_{i = 1}^n {{{(\omega {x_i} + b - {y_i})}^2}} L(ω,b)=n1i=1n(ωxi+byi)2

现在的主要任务为求使函数取得最小值的 ω \omega ω b b b。因此,目标函数的优化公式为:

L ( ω ∗ , b ∗ ) = arg ⁡ min ⁡ ( ω , b ) ∑ i = 1 n ( ω x i + b − y i ) 2 L({\omega ^*},{b^*}) = \mathop {\arg \min }\limits_{(\omega ,b)} \sum\limits_{i = 1}^n {{{(\omega {x_i} + b - {y_i})}^2}} L(ω,b)=(ω,b)argmini=1n(ωxi+byi)2

3、求解方法

(1) 最小二乘法
求解 ω \omega ω b b b是使损失函数最小化的过程,将 L ( ω , b ) L(\omega ,b) L(ω,b)分别对 ω \omega ω b b b进行求偏导:

∂ L ∂ ω = 2 ( ω ∑ i = 1 n x i 2 − ∑ i = 1 n ( y i − b ) ) \frac{{\partial L}}{{\partial \omega }} = 2(\omega \sum\limits_{i = 1}^n {x_i^2 - \sum\limits_{i = 1}^n {({y_i} - b)} } ) ωL=2(ωi=1nxi2i=1n(yib))

∂ L ∂ b = 2 ( n b − ∑ i = 1 n ( y i − ω x i ) ) \frac{{\partial L}}{{\partial b}} = 2(nb - \sum\limits_{i = 1}^n {({y_i} - \omega {x_i})} ) bL=2(nbi=1n(yiωxi))

令上述两式等于0,可以得到 ω \omega ω b b b 的封闭式最优解。

ω = ∑ i = 1 n y i ( x i − x ‾ ) ∑ i = 1 n x i 2 − 1 n ( ∑ i = 1 n x i ) 2 \omega = \frac{{\sum\nolimits_{i = 1}^n {{y_i}({x_i} - \overline x )} }}{{\sum\limits_{i = 1}^n {x_i^2 - \frac{1}{n}{{(\sum\limits_{i = 1}^n {{x_i}} )}^2}} }} ω=i=1nxi2n1(i=1nxi)2i=1nyi(xix)

(2) 梯度下降法

梯度下降法的核心内容是对自变量进行不断的更新,使目标函数不断逼近最小值的过程。

ω ← ω − α ∂ L ∂ ω b ← b − α ∂ L ∂ b \omega \leftarrow \omega - \alpha \frac{{\partial L}}{{\partial \omega }}\\ b \leftarrow b - \alpha \frac{{\partial L}}{{\partial b}} ωωαωLbbαbL

三、算法实现

算法实现见代码文件夹,算法测试结果如下:
在这里插入图片描述

LinearRegression.py

import numpy as np
class LinearRegression(object):
    def __init__(self,learning_rate=0.01,max_iter=100,seed=None):
        np.random.seed(seed)
        self.lr=learning_rate
        self.max_iter=max_iter
        self.w=np.random.normal(1,0.1)
        self.b=np.random.normal(1,0.1)
        self.loss_arr=[]
    def fit(self,x,y):
        self.x=x
        self.y=y
        for i in range(self.max_iter):
            self._train_step()
            self.loss_arr.append(self.loss())
    def _f(self,x,w,b):
        return w*x+b
    def predict(self,x=None):
        if x is None:
            x=self.x
        y_pred=self._f(x,self.w,self.b)
        return y_pred
    def loss(self,y_true=None,y_pred=None):
        if y_true is None or y_pred is None:
            y_true=self.y
            y_pred=self.predict(self.x)
        return np.mean((y_true-y_pred)**2)
    def _calculate_gradient(self):
        d_w=np.mean((self.w*self.x+self.b-self.y)*self.x)
        d_b=np.mean(self.w*self.x+self.b-self.y)
        return d_w,d_b
    def _train_step(self):
        d_w,d_b=self._calculate_gradient()
        self.w=self.w-self.lr*d_w
        self.b=self.b-self.lr*d_b
        return self.w,self.b
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

train_test.py

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from linear_regression import LinearRegression


def show_data(x, y, w=None, b=None):
    plt.scatter(x, y, marker='.')
    if w is not None and b is not None:
        plt.plot(x, w*x+b, c='red')
    plt.show()


# data generation
np.random.seed(272)
data_size = 100
x = np.random.uniform(low=1.0, high=10.0, size=data_size)
y = x * 20 + 10 + np.random.normal(loc=0.0, scale=10.0, size=data_size)

# plt.scatter(x, y, marker='.')
# plt.show()

# train / test split
shuffled_index = np.random.permutation(data_size)
x = x[shuffled_index]
y = y[shuffled_index]
split_index = int(data_size * 0.7)
x_train = x[:split_index]
y_train = y[:split_index]
x_test = x[split_index:]
y_test = y[split_index:]

# visualize data
# plt.scatter(x_train, y_train, marker='.')
# plt.show()
# plt.scatter(x_test, y_test, marker='.')
# plt.show()

# train the liner regression model
regr = LinearRegression(learning_rate=0.01, max_iter=10, seed=314)
regr.fit(x_train, y_train)
print('cost: \t{:.3}'.format(regr.loss()))
print('w: \t{:.3}'.format(regr.w))
print('b: \t{:.3}'.format(regr.b))
show_data(x, y, regr.w, regr.b)

# plot the evolution of cost
plt.scatter(np.arange(len(regr.loss_arr)), regr.loss_arr, marker='o', c='green')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/807442
推荐阅读
相关标签
  

闽ICP备14008679号