简单的线性回归算法

一.认识回归

1.简单的介绍

  回归是统计学中最有力的工具之一。机器学习监督学习算法分为分类算法和回归算法两种,其实就是根据类别标签分布类型为离散型、连续性而定义的。顾名思义,分类算法用于离散型分布预测,如决策树、朴素贝叶斯、adaboost、SVM、Logistic回归都是分类算法;回归算法用于连续型分布预测,针对的是数值型的样本,使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签。

  回归的目的就是建立一个回归方程用来预测目标值,回归的求解就是求这个回归方程的回归系数。预测的方法当然十分简单,回归系数乘以输入值再全部相加就得到了预测值。

2.回归的定义

  回归最简单的定义是,给出一个点集D,用一个函数去拟合这个点集,并且使得点集与拟合函数间的误差最小,如果这个函数曲线是一条直线,那就被称为线性回归,如果曲线是一条二次曲线,就被称为二次回归。

3.多元线性回归

  在回归分析中,如果有两个或两个以上的自变量,就称为多元回归。事实上,一种现象常常是与多个因素相联系的,由多个自变量的最优组合共同来预测或估计因变量,比只用一个自变量进行预测或估计更有效,更符合实际。因此多元线性回归比一元线性回归的实用意义更大。

特别注意:注意多元和多次是两个不同的概念,“多元”指方程有多个参数,“多次”指的是方程中参数的最高次幂。多元线性方程是假设预测值y与样本所有特征值符合一个多元一次线性方程。

二.线性回归算法

1.简单介绍

 

 

 

 由上图可知,我们必须要求出y=ax + b的最佳拟合直线,因此我们需要先求出参数a参数b的值,这里我们采用最小二乘法的方法进行求解

 2.线性回归的求解方法--最小二乘法

线性回归过程主要解决的就是如何通过样本来获取最佳的拟合线。最常用的方法便是最小二乘法,它是一种数学优化技术,它通过最小化误差的平方和寻找数据的最佳函数匹配。

1.数学公式推导

 

 

 

 示例代码:

import numpy as np
import matplotlib.pyplot as plt

#自己创建几个虚拟的数据
x = np.array([1.,2.,3.,4.,5.])
y = np.array([1.,3.,2.,3.,5.])

#绘制出大致的散点图片
plt.scatter(x,y)
plt.axis([0,6,0,6])
plt.show()     #图1


#求出相应的平均值
x_mean=np.mean(x)
y_mean=np.mean(y)


#根据推导公式求出参数a 和 参数b的值
num = 0.0
d = 0.0
for x_i,y_i in zip(x,y):
    num += (x_i - x_mean) * (y_i - y_mean)
    d += (x_i - x_mean) ** 2

a = num / d
b = y_mean - a * x_mean

y_hat = a * x + b

#可视化数据的处理
plt.scatter(x,y)
plt.plot(x,y_hat,color = 'red')
plt.axis([0,6,0,6])
plt.show()  #图2

 

图1

图2

根据求出的a和b进行预测

x_predict=6
y_predict= a * x_predict + b

y_predict   #5.2

2.封装代码并实现

import numpy as np

class SimpleLinearRegression():

    def __init__(self):
        """初始化Simple Linear Regression模型"""
        self.a_=None
        self.b_=None

    def fit(self,x_train,y_train):

        """根据训练数据集x_train, y_train训练Simple Linear Regression模型"""
        assert x_train.ndim == 1, \
            "Simple Linear Regressor can only solve single feature training data."
        assert len(x_train) == len(y_train), \
            "the size of x_train must be equal to the size of y_train"
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)

        num = 0.0
        d = 0.0
        for x_i, y_i in zip(x_train, y_train):
            num += (x_i - x_mean) * (y_i - y_mean)
            d += (x_i - x_mean) ** 2

        self.a_= num / d
        self.b_=y_mean - self.a_ * x_mean

        return self

    def predict(self,x_predict):
        """给定待预测数据集x_predict,返回表示x_predict的结果向量"""
        assert x_predict.ndim == 1, \
            "Simple Linear Regressor can only solve single feature training data."
        assert self.a_ is not None and self.b_ is not None, \
            "must fit before predict!"

        return np.array([self._predict(x) for x in x_predict])

    def _predict(self,x_train):
        """给定单个待预测数据x,返回x的预测结果值"""
        return self.a_ * x_train + self.b_

    def __repr__(self):
        return "SimpleLinearRegression()"

在jupyter notebook上进行相关的测试

%run D:\project\sk-learn\Linear_regression\simple_linear_regression.py

#先实例化一个对象
simplelinearregression=SimpleLinearRegression()

#让对象调用fit方法
simplelinearregression.fit(x,y)  #


simplelinearregression.a_  #参数a的值:0.8

simplelinearregression.b_ #参数b的值:0.39999999999999947

y_hat= simplelinearregression.a_ * x + simplelinearregression.b_


#数据可是化处理
plt.scatter(x,y)
plt.plot(x,y_hat,color = 'red')
plt.axis([0,6,0,6])
plt.show()

图3

可以上图和前面的可视化结果是基本上是一样的,因此该实现方式的方法是可行的

3.采用向量的计算方法来进行计算

  上面的代码是实现了计算线性回归的方法,但是该代码的执行时间花费较长,因此我们采用向量的计算方法来进行相应的优化

示例代码如下:

import numpy as np

class SimpleLinearRegression2():

    def __init__(self):
        """初始化Simple Linear Regression模型"""
        self.a_=None
        self.b_=None

    def fit(self,x_train,y_train):

        """根据训练数据集x_train, y_train训练Simple Linear Regression模型"""
        assert x_train.ndim == 1, \
            "Simple Linear Regressor can only solve single feature training data."
        assert len(x_train) == len(y_train), \
            "the size of x_train must be equal to the size of y_train"
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)

        self.a_= (x_train - x_mean).dot(y_train - y_mean) / (x_train - x_mean).dot(x_train - x_mean)
        self.b_=y_mean - self.a_ * x_mean

        return self

    def predict(self,x_predict):
        """给定待预测数据集x_predict,返回表示x_predict的结果向量"""
        assert x_predict.ndim == 1, \
            "Simple Linear Regressor can only solve single feature training data."
        assert self.a_ is not None and self.b_ is not None, \
            "must fit before predict!"

        return np.array([self._predict(x) for x in x_predict])

    def _predict(self,x_train):
        """给定单个待预测数据x,返回x的预测结果值"""
        return self.a_ * x_train + self.b_

    def __repr__(self):
        return "SimpleLinearRegression2()"

在jupyter notebook上进行相关的测试

%run D:\project\sk-learn\Linear_regression\simple_linear_regression.py

#先实例化一个对象
simplelinearregression=SimpleLinearRegression2()

#让对象调用fit方法
simplelinearregression2.fit(x,y)  #


simplelinearregression2.a_  #参数a的值:0.8

simplelinearregression2.b_ #参数b的值:0.39999999999999947

y_hat2= simplelinearregression2.a_ * x + simplelinearregression2.b_


#数据可是化处理
plt.scatter(x,y)
plt.plot(x,y_hat2,color = 'red')
plt.axis([0,6,0,6])
plt.show()

图4

由图可知图4和图3的结果是一样的

4.测试两种计算方法运行速度

1.在jupyter notebook上进行测试

m = 1000000
big_x = np.random.random(size=m)  #创建一个随机的数组
big_y = big_x * 2.0 + 3.0 + np.random.normal(size=m) #最后这个是加上一点误差


#测试两种算法的运行时间
%timeit simplelinearregression.fit(big_x,big_y)
%timeit simplelinearregression2.fit(big_x,big_y)

#2.42 s ± 151 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#21.9 ms ± 271 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

#由上述结果可以知道,向量的方法比普通的方法快了100倍左右

 

posted @ 2018-05-21 11:17  明-少  阅读(1408)  评论(0)    收藏  举报