线性回归 订阅
线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w'x+e,e为误差服从均值为0的正态分布。 [1]  回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。 展开全文
线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w'x+e,e为误差服从均值为0的正态分布。 [1]  回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。
信息
相关术语
回归系数
类    别
分析方法
应用学科
数学
中文名
线性回归
外文名
linear regression
适用范围
数理统计
线性回归基本含义
在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归。(这反过来又应当由多个相关的因变量预测的多元线性回归区别,而不是一个单一的标量变量。)在线性回归中,数据使用线性预测函数来建模,并且未知的模型参数也是通过数据来估计。这些模型被叫做线性模型。最常用的线性回归建模是给定X值的y的条件均值是X的仿射函数。不太一般的情况,线性回归模型可以是一个中位数或一些其他的给定X的条件下y的条件分布的分位数作为X的线性函数表示。像所有形式的回归分析一样,线性回归也把焦点放在给定X值的y的条件概率分布,而不是X和y的联合概率分布(多元分析领域)。线性回归是回归分析中第一种经过严格研究并在实际应用中广泛使用的类型。这是因为线性依赖于其未知参数的模型比非线性依赖于其位置参数的模型更容易拟合,而且产生的估计的统计特性也更容易确定。线性回归模型经常用最小二乘逼近来拟合,但他们也可能用别的方法来拟合,比如用最小化“拟合缺陷”在一些其他规范里(比如最小绝对误差回归),或者在桥回归中最小化最小二乘损失函数的惩罚.相反,最小二乘逼近可以用来拟合那些非线性的模型.因此,尽管“最小二乘法”和“线性模型”是紧密相连的,但他们是不能划等号的。
收起全文
精华内容
下载资源
问答
  • 线性回归

    千次阅读 2018-07-11 01:08:40
    这篇博客为大家介绍线性回归模型,也是本人写的第一篇回归模型的博客。之前介绍的模型预测结果都是离散值,也就是机器学习当中的分类问题,那么机器学习中还有一大类预测问题,其预测结果为连续值,我们称之为回归...

    这篇博客为大家简单介绍线性回归模型,也是写的第一篇回归模型的博客。

    之前介绍的模型预测结果都是离散值,也就是机器学习当中的分类问题,那么机器学习中还有一大类预测问题,其预测结果为连续值,我们称之为回归问题。

    线性回归属于机器学习中最基础的回归模型,因此,首先介绍线性回归模型。

    虽然线性回归模型是最基础的模型,但是其重要性也是不容小觑的。在很多实际项目应用当中,其效果还是不错的。

    首先我们用一个案例来引出线性回归:

    假设我们要预测某个房子的价格,那么我们如何去预测得知房屋的价格呢?通常情况下我们会综合考虑各个因素之后再给出这个房子的估价。这些因素有可能是房屋面积,卧室数目,房屋所处楼层,是否为学区房等等。当我们掌握了这些信息之后我们便能够基本预测得知这个房子的大概的价格。然而这只是凭借我们的经验来进行预测得知的价格,实际上我们并不知道这些因素同房价之间的真正的关系。线性回归要解决的问题就是找到这些因素同房价之间的真实关系,在已知其关系的情况下,我们就能根据已知的这些因素去预测得到房屋的价格。上文中所说的因素也就是机器学习中的样本的特征。如下表所示:

    房屋面积卧室数目所处楼层是否学区房房屋价格
    1233211000000
    90260600000

    表中每一行为一个房屋的特征信息以及价格信息,我们称之为一个样本,其中代表房屋的各个特征。假设房屋价格与各个特征之间的关系为,设,那么,这便是线性回归的基本模型,注意,线性回归并不是指关于特征是线性的,而是说关于权重向量是线性的,我们的任务就是要寻找最优的权重向量,从而确定特征和标记之间的关系。

    确定后,则线性回归模型也就确定,,其中为样本的预测值。

    接下来我们就来探索如何求得最好的

    假设存在样本集,其中为第i个样本的特征向量,为样本的真实标记。

    现在我们已知存在一组初始的权重向量,构造出了一个初始线性模型,但是这个模型的预测效果并不是很好,因此我们需要对其进行优化。

    在当前模型下,给定样本特征向量,我们可以得到其预测值。因此,我们也可以得到其预测误差

    在这里我们假设,则的概率密度函数,将带入得

    由于上式与的概率密度一致,因此我们可以重新解释上式为。由此便可以的出似然函数,可以看出似然函数中的变量只有,我们只需要找出使得似然函数最大的权重向量即可,即

    由于似然函数中为常数,所以我们将其省略,之后再对其取对数求取对数似然函数得到,省略可以得到。我们只需使得对数似然函数最大即可,因此

    由此我们便退出了线性回归的损失函数,因此,最后只需要对损失函数进行优化即可。

    在这里我们依旧采用梯度下降法:

    因为,所以,接下来只需按照式子更新即可。

    接下来附上本人使用python编写的linear regression的程序:

    import numpy as np
    from numpy import random as rd
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import mean_squared_error
    rd.seed(2)
    np.set_printoptions(linewidth=1000, suppress=True)
    
    
    def generate_samples(count):
        """
    
        :param count: 样本的个数
        :return:
        """
        x = rd.uniform(-10, 10, count)
        y = 3.5 * x + 4 + rd.uniform(-5, 5, count)
        x_return = np.ones((count, 1))
        x_return = np.concatenate([x_return, x.reshape(-1, 1)], axis=1)
        return x_return, y
    
    
    class LinearRegression(object):
    
        def __init__(self, count, alpha, lamda, beta, iter_times):
            """
    
            :param lamda: 正则项系数
            :param count: 生成样本个数,样本容量
            :param alpha: 学习率
            :param beta: 学习率衰减系数
            :param iter_times: 多少个epoch
            """
            self.iter_times = iter_times
            self.beta = beta
            self.lamda = lamda
            self.alpha = alpha
            self.x, self.y = generate_samples(count)
            self.x_train, self.x_test, self.y_train, self.y_test = train_test_split(self.x, self.y, test_size=0.3, random_state=1)
            self.weight = rd.uniform(-10, 10, 2)
            self.batch_size = int(0.2 * self.x_train.shape[0])
            self.epoch = int(np.ceil(self.x_train.shape[0] / self.batch_size))
            # self.test_mses以及self.train_mses用于存放每一个epoch训练集和测试集的均方误差
            self.test_mses = []
            self.train_mses = []
    
        def train(self):
            for j in range(self.iter_times):
                # 第一层循环控制多少个epoch
                for i in range(self.epoch):
                    # 第二层循环完成一次就是一个epoch,每次遍历出一个batch
                    if i != (self.epoch - 1):
                        self.x_epoch = self.x_train[i * self.batch_size:(i + 1) * self.batch_size, :]
                        self.y_epoch = self.y_train[i * self.batch_size:(i + 1) * self.batch_size]
                    else:
                        self.x_epoch = self.x_train[i * self.batch_size:, :]
                        self.y_epoch = self.y_train[i * self.batch_size:]
                    self.weight -= self.alpha * (-np.sum((self.y_epoch.reshape(-1, 1) - np.dot(self.x_epoch, self.weight.reshape(-1, 1))) * self.x_epoch, axis=0) + 2 * self.lamda * self.weight)
                    # print(self.weight)
                self.alpha *= self.beta
                try:
                    mse_train = mean_squared_error(self.y_train, np.dot(self.x_train, self.weight.reshape(-1, 1)).ravel())
                    mse_test = mean_squared_error(self.y_test, np.dot(self.x_test, self.weight.reshape(-1, 1)).ravel())
                    self.train_mses.append(mse_train)
                    self.test_mses.append(mse_test)
                except ValueError as e:
                    raise Exception("学习率设置过大")
                if (j + 1) % int(0.1 * self.iter_times) == 0:
                    print("================epoch: %d================" % (j + 1))
                    print("第%d个epoch训练集均方误差:" % (j + 1), mse_train)
                    print("第%d个epoch测试集均方误差:" % (j + 1), mse_test)
    
        def draw_mses(self):
            fig = plt.figure()
            ax = plt.subplot(2, 1, 1)
            ax2 = plt.subplot(2, 1, 2)
            plt.sca(ax)
            ax.plot(np.arange(1, 1 + self.iter_times), self.train_mses, label="train dataset mse", color="g")
            ax.plot(np.arange(1, 1 + self.iter_times), self.test_mses, label="test dataset mse", color="y")
            ax.set_xlabel("epoch")
            ax.set_ylabel("mse")
            ax.set_title("mse")
            ax.legend(loc="upper right")
            plt.sca(ax2)
            ax2.scatter(self.x[:, 1], self.y, label="samples", marker="*", color="r")
            x = np.linspace(-10, 10, 1000).reshape(-1, 1)
            x = np.concatenate([np.ones((1000, 1)), x], axis=1)
            ax2.plot(x[:, 1].ravel(), np.dot(x, self.weight.reshape(-1, 1)).ravel(), color="b", label="fitness curve")
            ax2.set_xlabel("x")
            ax2.set_ylabel("y")
            ax2.set_title("fitness curve")
            ax2.legend(loc="upper left")
            plt.subplots_adjust(wspace=10, hspace=0.5)
            plt.show()
    
    
    def main():
        linear = LinearRegression(100, 0.001, 0.8, 0.99, 200)
        linear.train()
        linear.draw_mses()
    
    
    if __name__ == "__main__":
        main()

    展开全文
  • Python实现多元线性回归

    万次阅读 多人点赞 2018-04-12 21:39:25
    Python实现多元线性回归 线性回归介绍 线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w'x+e,e为误差服从均值为0的...

    Python实现多元线性回归

     

     

    线性回归介绍

     

    线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w'x+e,e为误差服从均值为0的正态分布。回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。
    线性回归属于回归问题。对于回归问题,解决流程为: 
    给定数据集中每个样本及其正确答案,选择一个模型函数h(hypothesis,假设),并为h找到适应数据的(未必是全局)最优解,即找出最优解下的h的参数。这里给定的数据集取名叫训练集(Training Set)。不能所有数据都拿来训练,要留一部分验证模型好不好使,这点以后说。先列举几个几个典型的模型:
    ● 最基本的单变量线性回归: 
    形如h(x)=theta0+theta1*x1
    ● 多变量线性回归: 
    形如h(x)=theta0+theta1*x1+theta2*x2+theta3*x3
    ● 多项式回归(Polynomial Regression): 
    形如h(x)=theta0+theta1*x1+theta2*(x2^2)+theta3*(x3^3) 
    或者h(x)=ttheta0+theta1*x1+theta2*sqr(x2) 
    但是可以令x2=x2^2,x3=x3^3,于是又将其转化为了线性回归模型。虽然不能说多项式回归问题属于线性回归问题,但是一般我们就是这么做的。
    ● 所以最终通用表达式就是: 
    这里写图片描述

     

     

    数据导入与清洗

     

    对于数据导入来说,可以利用pandas内的read_csv的函数来对数据进行导入操作,在进行多元线性回归之间通过简单线性回归来展现线性回归的特性和结果之后再延伸至多元线性回归。

     

    在进行数据导入之间需要导入进行线性回归的包:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from pandas import DataFrame,Series
    from sklearn.cross_validation import train_test_split
    from sklearn.linear_model import LinearRegression

    我们利用pandas和numpy对数据进行操作,使用matplotlib进行图像化,使用sklearn进行数据集训练与模型导入。

     

    简单线性回归

     

    对于学生来说,所学习的时间和考试的成绩挂钩,所学习的时间与考试的成绩也是呈线性相关。创建一个数据集来描述学生学习时间与成绩的关系并且做简单的线性回归。

     

    in:

    #创建数据集
    examDict  = {'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,
                         2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
                 '分数':[10,22,13,43,20,22,33,50,62,
                       48,55,75,62,73,81,76,64,82,90,93]}
    
    #转换为DataFrame的数据格式
    examDf = DataFrame(examDict)

     

    通过DataFrame的函数将字典转化为所需要的数据集,也就是学生成绩与考试成绩的数据集。且关于pandas的数据内容Series与DataFrame可以查看关于pandas的博客了解点击打开链接

     

    out:

      分数  学习时间
    0   10  0.50
    1   22  0.75
    2   13  1.00
    3   43  1.25
    4   20  1.50
    5   22  1.75
    6   33  1.75
    7   50  2.00
    8   62  2.25
    9   48  2.50
    10  55  2.75
    11  75  3.00
    12  62  3.25
    13  73  3.50
    14  81  4.00
    15  76  4.25
    16  64  4.50
    17  82  4.75
    18  90  5.00
    19  93  5.50

     

    从上面的数据可以看到数据的特征值与其标签,学生所学习的时间就是所需要的特征值,而成绩就是通过特征值所反应的标签。在这个案例中要对数据进行观测来反应学习时间与成绩的情况,将利用散点图来实现简单的观测。

     

    in:

    #绘制散点图
    plt.scatter(examDf.分数,examDf.学习时间,color = 'b',label = "Exam Data")
    
    #添加图的标签(x轴,y轴)
    plt.xlabel("Hours")
    plt.ylabel("Score")
    #显示图像
    plt.show()

    out:

     

    从上图可以看到对于分数和时间来说存在相应的线性关系,且俩数据间相关性较强。

    在此可以通过相关性来衡量两个变量因素的相关密切程度。

    相关系数是用以反映变量之间相关关系密切程度的统计指标。

    r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy(即person系数)

    对于相关性强度来说的化有以下的关系:

    0~0.3 弱相关

    0.3~0.6  中等程度相关

    0.6~1  强相关

     

    in:

    rDf = examDf.corr()
    print(rDf)

    out:

    分数      学习时间
    分数    1.000000  0.923985
    学习时间  0.923985  1.000000

     

    pandas中的数学统计函数D.corr()可以反应数据间的相关性关系,可从表值中反应出学习时间与分数之间的相关性为强相关(0.6~1)。对于简单线性回归来来说,简单回归方程为: y = a + b*x (模型建立最佳拟合线)最佳拟合线也是需要通过最小二乘法来实现其作用。对于OLS即最小二乘法我们需要知道的一个关系为点误差,点误差 = 实际值 - 预测值,而误差平方和(Sum of square error) SSE = Σ(实际值-预测值)^2,最小二乘法就是基于SSE实现,最小二乘法 : 使得误差平方和最小(最佳拟合)。解释完简单线性回归后进行对训练集和测试集的创建,将会使用train_test_split函数来创建(train_test_split是存在与sklearn中的函数)

     

    in:

    #将原数据集拆分训练集和测试集
    X_train,X_test,Y_train,Y_test = train_test_split(exam_X,exam_Y,train_size=.8)
    #X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比
    
    print("原始数据特征:",exam_X.shape,
          ",训练数据特征:",X_train.shape,
          ",测试数据特征:",X_test.shape)
    
    print("原始数据标签:",exam_Y.shape,
          ",训练数据标签:",Y_train.shape,
          ",测试数据标签:",Y_test.shape)
    
    #散点图
    plt.scatter(X_train, Y_train, color="blue", label="train data")
    plt.scatter(X_test, Y_test, color="red", label="test data")
    
    #添加图标标签
    plt.legend(loc=2)
    plt.xlabel("Hours")
    plt.ylabel("Pass")
    #显示图像
    plt.savefig("tests.jpg")
    plt.show()

    out:

    原始数据特征: (20,) ,训练数据特征: (16,) ,测试数据特征: (4,)
    原始数据标签: (20,) ,训练数据标签: (16,) ,测试数据标签: (4,)

     

    tips:由于训练集随机分配的原因每一次运行的结果(点的分布情况,训练集内的情况,测试集内的情况)不都相同在创建数据集之后我们需要将训练集放入skleran中的线性回归模型(LinearRegression())进行训练,使用函数种的.fit函数进行模型的训练操作。

     

    in:

    model = LinearRegression()
    
    #对于模型错误我们需要把我们的训练集进行reshape操作来达到函数所需要的要求
    # model.fit(X_train,Y_train)
    
    #reshape如果行数=-1的话可以使我们的数组所改的列数自动按照数组的大小形成新的数组
    #因为model需要二维的数组来进行拟合但是这里只有一个特征所以需要reshape来转换为二维数组
    X_train = X_train.values.reshape(-1,1)
    X_test = X_test.values.reshape(-1,1)
    
    model.fit(X_train,Y_train)

     

    在模型训练完成之后会得到所对应的方程式(线性回归方程式)需要利用函数中的intercept_与coef_来得到

     

    a  = model.intercept_#截距
    
    b = model.coef_#回归系数
    
    print("最佳拟合线:截距",a,",回归系数:",b)

     

    out:

     

    最佳拟合线:截距 7.5580754557 ,回归系数: [ 16.28401865]

     

    由上述的最佳拟合线的截距和回归系数可以算出其线性回归线方程:y = 7.56 + 16.28*x

    接下来需要对模型进行预测和对模型进行评价,在进行评价之间将会引入一个决定系数r平方的概念。

    对于决定系数R平方常用于评估模型的精确度。

    下列为R平方的计算公式:

    ● y误差平方和 = Σ(y实际值 - y预测值)^2

    ● y的总波动 = Σ(y实际值 - y平均值)^2

    ● 有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动

    ● 有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方

    对于决定系数R平方来说

    (1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)

    (2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合对于预测来说我们需要运用函数中的model.predict()来得到预测值

     

    in:

    #训练数据的预测值
    y_train_pred = model.predict(X_train)
    #绘制最佳拟合线:标签用的是训练数据的预测值y_train_pred
    plt.plot(X_train, y_train_pred, color='black', linewidth=3, label="best line")
    
    #测试数据散点图
    plt.scatter(X_test, Y_test, color='red', label="test data")
    
    #添加图标标签
    plt.legend(loc=2)
    plt.xlabel("Hours")
    plt.ylabel("Score")
    #显示图像
    plt.savefig("lines.jpg")
    plt.show()
    
    
    score = model.score(X_test,Y_test)
    
    print(score)

     

    out:

    score : 0.834706696876

     

    多元线性回归

     

    在间单线性回归的例子中可以得到与线性回归相关的分析流程,接下来对多元线性回归进行分析对于多元线性回归前面已经提到,形如h(x)=theta0+theta1*x1+theta2*x2+theta3*x3http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv(已经失效)来下载数据集 Advertising.csv,其数据描述了一个产品的销量与广告媒体的投入之间影响。将会利用pandas的pd.read()来读取数据。

     

     

    in:

    #通过read_csv来读取我们的目的数据集
    adv_data = pd.read_csv("C:/Users/Administrator/Desktop/Advertising.csv")
    #清洗不需要的数据
    new_adv_data = adv_data.ix[:,1:]
    #得到我们所需要的数据集且查看其前几列以及数据形状
    print('head:',new_adv_data.head(),'\nShape:',new_adv_data.shape)

    out:

    head:       TV  radio  newspaper  sales
           0  230.1   37.8       69.2   22.1
           1   44.5   39.3       45.1   10.4
           2   17.2   45.9       69.3    9.3
           3  151.5   41.3       58.5   18.5
           4  180.8   10.8       58.4   12.9 
    Shape:  (200, 4)

     

    对于上述的数据可以得到数据中

    标签值(sales):

    • Sales:对应产品的销量

    特征值(TV,Radio,Newspaper):

    • TV:对于一个给定市场中单一产品,用于电视上的广告费用(以千为单位)
    • Radio:在广播媒体上投资的广告费用
    • Newspaper:用于报纸媒体的广告费用

    在这个案例中,通过不同的广告投入,预测产品销量。因为响应变量是一个连续的值,所以这个问题是一个回归问题。数据集一共有200个观测值,每一组观测对应一个市场的情况。接下里对数据进行描述性统计,以及寻找缺失值(缺失值对模型的影响较大,如发现缺失值应替换或删除),且利用箱图来从可视化方面来查看数据集,在描述统计之后对数据进行相关性分析,以此来查找数据中特征值与标签值之间的关系。

     

    in:

    #数据描述
    print(new_adv_data.describe())
    #缺失值检验
    print(new_adv_data[new_adv_data.isnull()==True].count())
    
    new_adv_data.boxplot()
    plt.savefig("boxplot.jpg")
    plt.show()
    ##相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
    #相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
    print(new_adv_data.corr())

     

    out:

                   TV       radio   newspaper       sales
    count  200.000000  200.000000  200.000000  200.000000
    mean   147.042500   23.264000   30.554000   14.022500
    std     85.854236   14.846809   21.778621    5.217457
    min      0.700000    0.000000    0.300000    1.600000
    25%     74.375000    9.975000   12.750000   10.375000
    50%    149.750000   22.900000   25.750000   12.900000
    75%    218.825000   36.525000   45.100000   17.400000
    max    296.400000   49.600000  114.000000   27.000000
    TV           0
    radio        0
    newspaper    0
    sales        0
    dtype: int64
                     TV     radio  newspaper     sales
    TV         1.000000  0.054809   0.056648  0.782224
    radio      0.054809  1.000000   0.354104  0.576223
    newspaper  0.056648  0.354104   1.000000  0.228299
    sales      0.782224  0.576223   0.228299  1.000000

     

     

     

     

    可以从corr表中看出,TV特征和销量是有比较强的线性关系的,而Radio和Sales线性关系弱一些但是也是属于强相关的,Newspaper和Sales线性关系更弱。接下来建立散点图来查看数据里的数据分析情况以及对相对应的线性情况,将使用seaborn的pairplot来绘画3种不同的因素对标签值的影响

     

    in:

    # 通过加入一个参数kind='reg',seaborn可以添加一条最佳拟合直线和95%的置信带。
    sns.pairplot(new_adv_data, x_vars=['TV','radio','newspaper'], y_vars='sales', size=7, aspect=0.8,kind = 'reg')
    plt.savefig("pairplot.jpg")
    plt.show()

    out:

     

    上如图种所示,可以了解到不同的因素对销量的预测线(置信度= 95 %),也可可以大致看出不同特征对于标签值的影响与相关关系在了解了数据的各种情况后需要对数据集建立模型,在建立模型的第一步我们将建立训练集与测试集同样的将会使用train_test_split函数来创建(train_test_split是存在与sklearn中的函数)

     

    in:

    X_train,X_test,Y_train,Y_test = train_test_split(new_adv_data.ix[:,:3],new_adv_data.sales,train_size=.80)
    
    print("原始数据特征:",new_adv_data.ix[:,:3].shape,
          ",训练数据特征:",X_train.shape,
          ",测试数据特征:",X_test.shape)
    
    print("原始数据标签:",new_adv_data.sales.shape,
          ",训练数据标签:",Y_train.shape,
          ",测试数据标签:",Y_test.shape)

    out:

    原始数据特征: (200, 3) ,训练数据特征: (160, 3) ,测试数据特征: (40, 3)
    原始数据标签: (200,) ,训练数据标签: (160,) ,测试数据标签: (40,)

     

    建立初步的数据集模型之后将训练集中的特征值与标签值放入LinearRegression()模型中且使用fit函数进行训练,在模型训练完成之后会得到所对应的方程式(线性回归方程式)需要利用函数中的intercept_与coef_。

     

    in:

    model = LinearRegression()
    
    model.fit(X_train,Y_train)
    
    a  = model.intercept_#截距
    
    b = model.coef_#回归系数
    
    print("最佳拟合线:截距",a,",回归系数:",b)

     

    out:

    最佳拟合线:截距 2.79361553401 ,回归系数: [ 0.04711495  0.18719875 -0.00185999]

     

    即所得的多元线性回归模型的函数为 : y = 2.79 + 0.04 * TV + 0.187 * Radio - 0.002 * Newspaper,对于给定了Radio和Newspaper的广告投入,如果在TV广告上每多投入1个单位,对应销量将增加0.04711个单位。就是加入其它两个媒体投入固定,在TV广告上每增加1000美元(因为单位是1000美元),销量将增加47.11(因为单位是1000)。但是大家注意这里的newspaper的系数居然是负数,所以我们可以考虑不使用newspaper这个特征。接下来对数据集进行预测与模型测评。同样使用predict与score函数来获取所需要的预测值与得分。

     

    in:

    #R方检测
    #决定系数r平方
    #对于评估模型的精确度
    #y误差平方和 = Σ(y实际值 - y预测值)^2
    #y的总波动 = Σ(y实际值 - y平均值)^2
    #有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动
    #有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方
    #对于决定系数R平方来说1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)
    #2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合
    score = model.score(X_test,Y_test)
    
    print(score)
    
    #对线性回归进行预测
    
    Y_pred = model.predict(X_test)
    
    print(Y_pred)
    
    plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
    #显示图像
    plt.savefig("predict.jpg")
    plt.show()

     

    out:

    score : 0.871755480886
    predict :[ 14.17217173  17.42866884  16.81933374  18.16079802   7.64784604
      17.8670496   16.66488531  14.98782916   9.41023763  16.21679696
      19.32696651   7.76788593  23.34231219   3.59006148  13.15777984
      24.26609169  15.47571902  15.39542342  13.98430709  12.65446708
       7.59818691  13.85179898  12.16325619  10.34902817  11.9813427
      11.05726513   8.13405159  21.94038306  16.4388483   14.06506403
       4.36052153   6.45326681   7.55083036  24.25987365  17.13603444
      14.04814117   7.28664465  17.24163581  20.42745536   6.55512244]

    预测集与源数据集的对比如下:

     

    模型的检测方法-ROC曲线:

     ROC曲线是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(灵敏度)为纵坐标,假阳性率(1-特异度)为横坐标绘制的曲线。传统的诊断试验评价方法有一个共同的特点,必须将试验结果分为两类,再进行统计分析。ROC曲线的评价方法与传统的评价方法不同,无须此限制,而是根据实际情况,允许有中间状态,可以把试验结果划分为多个有序分类,如正常、大致正常、可疑、大致异常和异常五个等级再进行统计分析。因此,ROC曲线评价方法适用的范围更为广泛。

    1.ROC曲线能很容易地查出任意界限值时的对疾病的识别能力。

    2.选择最佳的诊断界限值。ROC曲线越靠近左上角,试验的准确性就越高。最靠近左上角的ROC曲线的点是错误最少的最好阈值,其假阳性和假阴性的总数最少。

    3.两种或两种以上不同诊断试验对疾病识别能力的比较。在对同一种疾病的两种或两种以上诊断方法进行比较时,可将各试验的ROC曲线绘制到同一坐标中,以直观地鉴别优劣,靠近左上角的ROC曲线所代表的受试者工作最准确。亦可通过分别计算各个试验的ROC曲线下的面积(AUC)进行比较,哪一种试验的 AUC最大,则哪一种试验的诊断价值最佳(百度百科)

    模型提升:

    对于提升模型准确度的方法很多,在这个模型下,可以利用异常值替换,将Newspaper中的异常值进行拉格朗日法插补,朗格朗日插补法(from scipy.interpolate import lagrange即scipy中的函数)可以间接提高模型的准确度,如果不需要插补异常值或缺失值的话可以将Newspaper不列为特征值考虑,在不考虑Newspaper为特征值的情况下,新的模型的准确率将超过旧模型,也可以从模型的准确度来反证Newspaper不适合作为特征值。

     

    整体代码如下,数据集再上面链接中可直接下载。

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from pandas import DataFrame,Series
    from sklearn.cross_validation import train_test_split
    from sklearn.linear_model import LinearRegression
    #创建数据集
    examDict  = {'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,
                         2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
                 '分数':[10,22,13,43,20,22,33,50,62,
                       48,55,75,62,73,81,76,64,82,90,93]}
    
    #转换为DataFrame的数据格式
    examDf = DataFrame(examDict)
    
    #绘制散点图
    plt.scatter(examDf.分数,examDf.学习时间,color = 'b',label = "Exam Data")
    
    #添加图的标签(x轴,y轴)
    plt.xlabel("Hours")
    plt.ylabel("Score")
    #显示图像
    plt.savefig("examDf.jpg")
    plt.show()
    
    
    #相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
    #相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
    rDf = examDf.corr()
    print(rDf)
    
    #回归方程 y = a + b*x (模型建立最佳拟合线)
    #点误差 = 实际值 - 拟合值
    #误差平方和(Sum of square error) SSE = Σ(实际值-预测值)^2
    #最小二乘法 : 使得误差平方和最小(最佳拟合)
    exam_X  =  examDf.loc[:,'学习时间']
    exam_Y  =  examDf.loc[:,'分数']
    
    #将原数据集拆分训练集和测试集
    X_train,X_test,Y_train,Y_test = train_test_split(exam_X,exam_Y,train_size=.8)
    #X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比
    
    print("原始数据特征:",exam_X.shape,
          ",训练数据特征:",X_train.shape,
          ",测试数据特征:",X_test.shape)
    
    print("原始数据标签:",exam_Y.shape,
          ",训练数据标签:",Y_train.shape,
          ",测试数据标签:",Y_test.shape)
    
    #散点图
    plt.scatter(X_train, Y_train, color="blue", label="train data")
    plt.scatter(X_test, Y_test, color="red", label="test data")
    
    #添加图标标签
    plt.legend(loc=2)
    plt.xlabel("Hours")
    plt.ylabel("Pass")
    #显示图像
    plt.savefig("tests.jpg")
    plt.show()
    
    
    
    model = LinearRegression()
    
    #对于下面的模型错误我们需要把我们的训练集进行reshape操作来达到函数所需要的要求
    # model.fit(X_train,Y_train)
    
    #reshape如果行数=-1的话可以使我们的数组所改的列数自动按照数组的大小形成新的数组
    #因为model需要二维的数组来进行拟合但是这里只有一个特征所以需要reshape来转换为二维数组
    X_train = X_train.values.reshape(-1,1)
    X_test = X_test.values.reshape(-1,1)
    
    model.fit(X_train,Y_train)
    
    a  = model.intercept_#截距
    
    b = model.coef_#回归系数
    
    print("最佳拟合线:截距",a,",回归系数:",b)
    
    #决定系数r平方
    #对于评估模型的精确度
    #y误差平方和 = Σ(y实际值 - y预测值)^2
    #y的总波动 = Σ(y实际值 - y平均值)^2
    #有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动
    #有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方
    #对于决定系数R平方来说1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)
    #2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合
    
    plt.scatter(X_train, Y_train, color='blue', label="train data")
    
    #训练数据的预测值
    y_train_pred = model.predict(X_train)
    #绘制最佳拟合线:标签用的是训练数据的预测值y_train_pred
    plt.plot(X_train, y_train_pred, color='black', linewidth=3, label="best line")
    
    #测试数据散点图
    plt.scatter(X_test, Y_test, color='red', label="test data")
    
    #添加图标标签
    plt.legend(loc=2)
    plt.xlabel("Hours")
    plt.ylabel("Score")
    #显示图像
    plt.savefig("lines.jpg")
    plt.show()
    
    
    score = model.score(X_test,Y_test)
    
    print(score)
    import pandas as pd
    import seaborn as sns
    from sklearn.linear_model import LinearRegression
    import matplotlib.pyplot as plt
    from sklearn.cross_validation import train_test_split
    
    #通过read_csv来读取我们的目的数据集
    adv_data = pd.read_csv("C:/Users/Administrator/Desktop/Advertising.csv")
    #清洗不需要的数据
    new_adv_data = adv_data.ix[:,1:]
    #得到我们所需要的数据集且查看其前几列以及数据形状
    print('head:',new_adv_data.head(),'\nShape:',new_adv_data.shape)
    
    #数据描述
    print(new_adv_data.describe())
    #缺失值检验
    print(new_adv_data[new_adv_data.isnull()==True].count())
    
    new_adv_data.boxplot()
    plt.savefig("boxplot.jpg")
    plt.show()
    ##相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
    #相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
    print(new_adv_data.corr())
    
    #建立散点图来查看数据集里的数据分布
    #seaborn的pairplot函数绘制X的每一维度和对应Y的散点图。通过设置size和aspect参数来调节显示的大小和比例。
    # 可以从图中看出,TV特征和销量是有比较强的线性关系的,而Radio和Sales线性关系弱一些,Newspaper和Sales线性关系更弱。
    # 通过加入一个参数kind='reg',seaborn可以添加一条最佳拟合直线和95%的置信带。
    sns.pairplot(new_adv_data, x_vars=['TV','radio','newspaper'], y_vars='sales', size=7, aspect=0.8,kind = 'reg')
    plt.savefig("pairplot.jpg")
    plt.show()
    
    #利用sklearn里面的包来对数据集进行划分,以此来创建训练集和测试集
    #train_size表示训练集所占总数据集的比例
    X_train,X_test,Y_train,Y_test = train_test_split(new_adv_data.ix[:,:3],new_adv_data.sales,train_size=.80)
    
    print("原始数据特征:",new_adv_data.ix[:,:3].shape,
          ",训练数据特征:",X_train.shape,
          ",测试数据特征:",X_test.shape)
    
    print("原始数据标签:",new_adv_data.sales.shape,
          ",训练数据标签:",Y_train.shape,
          ",测试数据标签:",Y_test.shape)
    
    model = LinearRegression()
    
    model.fit(X_train,Y_train)
    
    a  = model.intercept_#截距
    
    b = model.coef_#回归系数
    
    print("最佳拟合线:截距",a,",回归系数:",b)
    #y=2.668+0.0448∗TV+0.187∗Radio-0.00242∗Newspaper
    
    #R方检测
    #决定系数r平方
    #对于评估模型的精确度
    #y误差平方和 = Σ(y实际值 - y预测值)^2
    #y的总波动 = Σ(y实际值 - y平均值)^2
    #有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动
    #有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方
    #对于决定系数R平方来说1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)
    #2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合
    score = model.score(X_test,Y_test)
    
    print(score)
    
    #对线性回归进行预测
    
    Y_pred = model.predict(X_test)
    
    print(Y_pred)
    
    
    plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
    #显示图像
    # plt.savefig("predict.jpg")
    plt.show()
    
    plt.figure()
    plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
    plt.plot(range(len(Y_pred)),Y_test,'r',label="test")
    plt.legend(loc="upper right") #显示图中的标签
    plt.xlabel("the number of sales")
    plt.ylabel('value of sales')
    plt.savefig("ROC.jpg")
    plt.show()
    
    
    
    
    

    Advertising.csv的连接已经失效,以下是补充的数据,可复制粘贴到CSV进行保存

    TV radio newspaper sales
    230.1 37.8 69.2 22.1
    44.5 39.3 45.1 10.4
    17.2 45.9 69.3 9.3
    151.5 41.3 58.5 18.5
    180.8 10.8 58.4 12.9
    8.7 48.9 75 7.2
    57.5 32.8 23.5 11.8
    120.2 19.6 11.6 13.2
    8.6 2.1 1 4.8
    199.8 2.6 21.2 10.6
    66.1 5.8 24.2 8.6
    214.7 24 4 17.4
    23.8 35.1 65.9 9.2
    97.5 7.6 7.2 9.7
    204.1 32.9 46 19
    195.4 47.7 52.9 22.4
    67.8 36.6 114 12.5
    281.4 39.6 55.8 24.4
    69.2 20.5 18.3 11.3
    147.3 23.9 19.1 14.6
    218.4 27.7 53.4 18
    237.4 5.1 23.5 12.5
    13.2 15.9 49.6 5.6
    228.3 16.9 26.2 15.5
    62.3 12.6 18.3 9.7
    262.9 3.5 19.5 12
    142.9 29.3 12.6 15
    240.1 16.7 22.9 15.9
    248.8 27.1 22.9 18.9
    70.6 16 40.8 10.5
    292.9 28.3 43.2 21.4
    112.9 17.4 38.6 11.9
    97.2 1.5 30 9.6
    265.6 20 0.3 17.4
    95.7 1.4 7.4 9.5
    290.7 4.1 8.5 12.8
    266.9 43.8 5 25.4
    74.7 49.4 45.7 14.7
    43.1 26.7 35.1 10.1
    228 37.7 32 21.5
    202.5 22.3 31.6 16.6
    177 33.4 38.7 17.1
    293.6 27.7 1.8 20.7
    206.9 8.4 26.4 12.9
    25.1 25.7 43.3 8.5
    175.1 22.5 31.5 14.9
    89.7 9.9 35.7 10.6
    239.9 41.5 18.5 23.2
    227.2 15.8 49.9 14.8
    66.9 11.7 36.8 9.7
    199.8 3.1 34.6 11.4
    100.4 9.6 3.6 10.7
    216.4 41.7 39.6 22.6
    182.6 46.2 58.7 21.2
    262.7 28.8 15.9 20.2
    198.9 49.4 60 23.7
    7.3 28.1 41.4 5.5
    136.2 19.2 16.6 13.2
    210.8 49.6 37.7 23.8
    210.7 29.5 9.3 18.4
    53.5 2 21.4 8.1
    261.3 42.7 54.7 24.2
    239.3 15.5 27.3 15.7
    102.7 29.6 8.4 14
    131.1 42.8 28.9 18
    69 9.3 0.9 9.3
    31.5 24.6 2.2 9.5
    139.3 14.5 10.2 13.4
    237.4 27.5 11 18.9
    216.8 43.9 27.2 22.3
    199.1 30.6 38.7 18.3
    109.8 14.3 31.7 12.4
    26.8 33 19.3 8.8
    129.4 5.7 31.3 11
    213.4 24.6 13.1 17
    16.9 43.7 89.4 8.7
    27.5 1.6 20.7 6.9
    120.5 28.5 14.2 14.2
    5.4 29.9 9.4 5.3
    116 7.7 23.1 11
    76.4 26.7 22.3 11.8
    239.8 4.1 36.9 12.3
    75.3 20.3 32.5 11.3
    68.4 44.5 35.6 13.6
    213.5 43 33.8 21.7
    193.2 18.4 65.7 15.2
    76.3 27.5 16 12
    110.7 40.6 63.2 16
    88.3 25.5 73.4 12.9
    109.8 47.8 51.4 16.7
    134.3 4.9 9.3 11.2
    28.6 1.5 33 7.3
    217.7 33.5 59 19.4
    250.9 36.5 72.3 22.2
    107.4 14 10.9 11.5
    163.3 31.6 52.9 16.9
    197.6 3.5 5.9 11.7
    184.9 21 22 15.5
    289.7 42.3 51.2 25.4
    135.2 41.7 45.9 17.2
    222.4 4.3 49.8 11.7
    296.4 36.3 100.9 23.8
    280.2 10.1 21.4 14.8
    187.9 17.2 17.9 14.7
    238.2 34.3 5.3 20.7
    137.9 46.4 59 19.2
    25 11 29.7 7.2
    90.4 0.3 23.2 8.7
    13.1 0.4 25.6 5.3
    255.4 26.9 5.5 19.8
    225.8 8.2 56.5 13.4
    241.7 38 23.2 21.8
    175.7 15.4 2.4 14.1
    209.6 20.6 10.7 15.9
    78.2 46.8 34.5 14.6
    75.1 35 52.7 12.6
    139.2 14.3 25.6 12.2
    76.4 0.8 14.8 9.4
    125.7 36.9 79.2 15.9
    19.4 16 22.3 6.6
    141.3 26.8 46.2 15.5
    18.8 21.7 50.4 7
    224 2.4 15.6 11.6
    123.1 34.6 12.4 15.2
    229.5 32.3 74.2 19.7
    87.2 11.8 25.9 10.6
    7.8 38.9 50.6 6.6
    80.2 0 9.2 8.8
    220.3 49 3.2 24.7
    59.6 12 43.1 9.7
    0.7 39.6 8.7 1.6
    265.2 2.9 43 12.7
    8.4 27.2 2.1 5.7
    219.8 33.5 45.1 19.6
    36.9 38.6 65.6 10.8
    48.3 47 8.5 11.6
    25.6 39 9.3 9.5
    273.7 28.9 59.7 20.8
    43 25.9 20.5 9.6
    184.9 43.9 1.7 20.7
    73.4 17 12.9 10.9
    193.7 35.4 75.6 19.2
    220.5 33.2 37.9 20.1
    104.6 5.7 34.4 10.4
    96.2 14.8 38.9 11.4
    140.3 1.9 9 10.3
    240.1 7.3 8.7 13.2
    243.2 49 44.3 25.4
    38 40.3 11.9 10.9
    44.7 25.8 20.6 10.1
    280.7 13.9 37 16.1
    121 8.4 48.7 11.6
    197.6 23.3 14.2 16.6
    171.3 39.7 37.7 19
    187.8 21.1 9.5 15.6
    4.1 11.6 5.7 3.2
    93.9 43.5 50.5 15.3
    149.8 1.3 24.3 10.1
    11.7 36.9 45.2 7.3
    131.7 18.4 34.6 12.9
    172.5 18.1 30.7 14.4
    85.7 35.8 49.3 13.3
    188.4 18.1 25.6 14.9
    163.5 36.8 7.4 18
    117.2 14.7 5.4 11.9
    234.5 3.4 84.8 11.9
    17.9 37.6 21.6 8
    206.8 5.2 19.4 12.2
    215.4 23.6 57.6 17.1
    284.3 10.6 6.4 15
    50 11.6 18.4 8.4
    164.5 20.9 47.4 14.5
    19.6 20.1 17 7.6
    168.4 7.1 12.8 11.7
    222.4 3.4 13.1 11.5
    276.9 48.9 41.8 27
    248.4 30.2 20.3 20.2
    170.2 7.8 35.2 11.7
    276.7 2.3 23.7 11.8
    165.6 10 17.6 12.6
    156.6 2.6 8.3 10.5
    218.5 5.4 27.4 12.2
    56.2 5.7 29.7 8.7
    287.6 43 71.8 26.2
    253.8 21.3 30 17.6
    205 45.1 19.6 22.6
    139.5 2.1 26.6 10.3
    191.1 28.7 18.2 17.3
    286 13.9 3.7 15.9
    18.7 12.1 23.4 6.7
    39.5 41.1 5.8 10.8
    75.5 10.8 6 9.9
    17.2 4.1 31.6 5.9
    166.8 42 3.6 19.6
    149.7 35.6 6 17.3
    38.2 3.7 13.8 7.6
    94.2 4.9 8.1 9.7
    177 9.3 6.4 12.8
    283.6 42 66.2 25.5
    232.1 8.6 8.7 13.4
    展开全文
  • 通俗理解线性回归(一)

    万次阅读 多人点赞 2018-08-29 22:04:03
    假设线性回归是个黑盒子,那按照程序员的思维来说,这个黑盒子就是个函数,然后呢,我们只要往这个函数传一些参数作为输入,就能得到一个结果作为输出。那回归是什么意思呢?其实说白了,就是这个黑盒子输出的结果是...

    本人已经打算将这一系列博文做成动画趣味科普的形式来呈现,感兴趣的话可以点这里

    #0 什么是回归?
    假设线性回归是个黑盒子,那按照程序员的思维来说,这个黑盒子就是个函数,然后呢,我们只要往这个函数传一些参数作为输入,就能得到一个结果作为输出。那回归是什么意思呢?其实说白了,就是这个黑盒子输出的结果是个连续的值。如果输出不是个连续值而是个离散值那就叫分类。那什么叫做连续值呢?非常简单,举个栗子:比如我告诉你我这里有间房子,这间房子有40平,在地铁口,然后你来猜一猜我的房子总共值多少钱?这就是连续值,因为房子可能值80万,也可能值80.2万,也可能值80.111万。再比如,我告诉你我有间房子,120平,在地铁口,总共值180万,然后你来猜猜我这间房子会有几个卧室?那这就是离散值了。因为卧室的个数只可能是1, 2, 3,4,充其量到5个封顶了,而且卧室个数也不可能是什么1.1, 2.9个。所以呢,对于ML萌新来说,你只要知道我要完成的任务是预测一个连续值的话,那这个任务就是回归。是离散值的话就是分类。(PS:目前只讨论监督学习)

    #1 线性回归
    OK,现在既然已经知道什么是回归,那现在就要来聊一聊啥叫线性。其实这玩意也很简单,我们在上初中的时候都学过直线方程对不对?来来来,我们来回忆一下直线方程是啥?
    y=kx+by=kx+b
    喏,这就是初中数学老师教我们的直线方程。那上过初中的同学都知道,这个式子表达的是,当我知道k(参数)和b(参数)的情况下,我随便给一个x我都能通过这个方程算出y来。而且呢,这个式子是线性的,为什么呢?因为从直觉上来说,你都知道,这个式子的函数图像是条直线。。。。从理论上来说,这式子满足线性系统的性质。(至于线性系统是啥,我就不扯了,不然没完没了)那有的同学可能会觉得疑惑,这一节要说的是线性回归,我扯这个low逼直线方程干啥?其实,说白了,线性回归无非就是在N维空间中找一个形式像直线方程一样的函数来拟合数据而已。比如说,我现在有这么一张图,横坐标代表房子的面积,纵坐标代表房价。
    这里写图片描述
    然后呢,线性回归就是要找一条直线,并且让这条直线尽可能地拟合图中的数据点。
    那如果让1000个老铁来找这条直线就可能找出1000种直线来,比如这样
    这里写图片描述
    这样
    这里写图片描述
    或者这样
    这里写图片描述
    喏,其实找直线的过程就是在做线性回归,只不过这个叫法更有逼格而已。。。

    #2 损失函数
    那既然是找直线,那肯定是要有一个评判的标准,来评判哪条直线才是最好的。OK,道理我们都懂,那咋评判呢?其实简单的雅痞。。。只要算一下实际房价和我找出的直线根据房子大小预测出来的房价之间的差距就行了。说白了就是算两点的距离。当我们把所有实际房价和预测出来的房价的差距(距离)算出来然后做个加和,我们就能量化出现在我们预测的房价和实际房价之间的误差。例如下图中我画了很多条小数线,每一条小数线就是实际房价和预测房价的差距(距离)
    这里写图片描述
    然后把每条小竖线的长度加起来就等于我们现在通过这条直线预测出的房价与实际房价之间的差距。那每条小竖线的长度的加和怎么算?其实就是欧式距离加和,公式如下。(其中y(i)表示的是实际房价,y^(i)表示的是预测房价)
    这里写图片描述
    这个欧氏距离加和其实就是用来量化预测结果和真实结果的误差的一个函数。在ML中称它为损失函数(说白了就是计算误差的函数)。那有了这个函数,我们就相当于有了一个评判标准,当这个函数的值越小,就越说明我们找到的这条直线越能拟合我们的房价数据。所以说啊,线性回归无非就是通过这个损失函数做为评判标准来找出一条直线。

    刚刚我举的例子是一维的例子(特征只有房子大小),那现在我们假设我的数据中还有一个特征是楼间距,那图像可能就是酱紫了。
    这里写图片描述
    从图我们可以看得出来,就算是在二维空间中,还是找一条直线来拟合我们的数据。所以啊,换汤不换药,损失函数还是这个欧式距离加和。
    这里写图片描述


    先写到这里,因为如果篇幅太长,对于萌新来说不太友好,而且后面想用人话来聊聊线性回归的正规方程解,所以先蓄个力。

    展开全文
  • 单变量线性回归 绘制散点图 相关系数R 拆分训练集和测试集 多变量线性回归 数据检验(判断是否可以做线性回归) 训练线性回归模型 先甩几个典型的线性回归的模型,帮助大家捡起那些年被忘记的数学。 ● 单...

    目录

    数据导入

    单变量线性回归

    绘制散点图

    相关系数R

    拆分训练集和测试集

    多变量线性回归

    数据检验(判断是否可以做线性回归)

    训练线性回归模型


    先甩几个典型的线性回归的模型,帮助大家捡起那些年被忘记的数学。

    单变量线性回归: h(x)=theta0 + theta1* x 1
    多变量线性回归: h(x)=theta0 + theta1* x 1 + theta2* x 2 + theta3* x 3
    多项式回归:        h(x)=theta0 + theta1* x 1 + theta2* (x2^2) + theta3* (x3^3) 

    多项式回归始终还是线性回归,你可以令x2=x2^2,x3=x3^3,简单的数据处理一下就好了,这样上述多项式回归的模型就变成多变量线性回归的模型了。

    数据导入

    下面我们要开始用数据说话了,先来看看数据源是什么样子吧。

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from pandas import DataFrame,Series
    from sklearn.cross_validation import train_test_split
    from sklearn.linear_model import LinearRegression
    
    #读取文件
    datafile = u'E:\\pythondata\\dhdhdh.xlsx'#文件所在位置,u为防止路径中有中文名称,此处没有,可以省略
    data = pd.read_excel(datafile)#datafile是excel文件,所以用read_excel,如果是csv文件则用read_csv
    examDf = DataFrame(data)
    examDf.head()

    运行结果:

         Call   Connect    Return
    0  2.1335  1.267760  1.176615
    1  2.5534  1.352941  1.978967
    2  3.3361  1.872093  2.249511
    3  3.3861  1.826667  2.986597
    4  3.9682  1.875000  2.798570

     


    单变量线性回归

     

    绘制散点图

    先将上述数据中的Connect(接通量)和Return(回款量)做一个单变量的线性回归,先绘制一个散点图,大致看一下分布情况。

    #绘制散点图,examDf.jt为X轴,examDf.hk为Y轴
    plt.scatter(examDf.Connect,examDf.Return,color = 'darkgreen',label = "Exam Data")
     
    #添加图的标签(x轴,y轴)
    plt.xlabel("The Connection amount of the average account")#设置X轴标签
    plt.ylabel("The ratio of average return amount")#设置Y轴标签
    plt.show()#显示图像

    运行结果:  

    看来商业中的实际数据总是和课本上的完美数据不一样,看这零零散散的分布,线性关系很是勉强,但是大致还是有一个线性相关的样子的,那么就看看相关系数有多少吧。

    相关系数R

    rDf = examDf.corr()#查看数据间的相关系数
    print(rDf)

    运行结果: 

                 Call   Connect    Return
    Call     1.000000  0.445870  0.441673
    Connect  0.445870  1.000000  0.745338
    Return   0.441673  0.745338  1.000000

    Connect(接通量)和Return(回款量)的相关系数为0.745338,还不错。

    相关系数是用以反映变量之间相关关系密切程度的统计指标,对于相关性强度来说,我们一般认为:

    0~0.3 弱相关

    0.3~0.6  中等程度相关

    0.6~1  强相关

    在数学中,相关系数的计算一般是这样的,给数学狂人看:

    R(相关系数) = X和Y的协方差 / (X的标准差 * Y的标准差) == cov(X,Y)/ σX * σY (即person系数)

    拆分训练集和测试集

    Connect(接通量)和Return(回款量)属于强相关,可以进行线性回归训练,那么我们先来拆分训练集和测试集吧。

    #拆分训练集和测试集(train_test_split是存在与sklearn中的函数)
    X_train,X_test,Y_train,Y_test = train_test_split(examDf.Connect,examDf.Return,train_size=0.8)
    #train为训练数据,test为测试数据,examDf为源数据,train_size 规定了训练数据的占比
     
    print("自变量---源数据:",examDf.Connect.shape, ";  训练集:",X_train.shape, ";  测试集:",X_test.shape)
    print("因变量---源数据:",examDf.Return.shape, ";  训练集:",Y_train.shape, ";  测试集:",Y_test.shape)
     
    #散点图
    plt.scatter(X_train, Y_train, color="darkgreen", label="train data")#训练集为深绿色点
    plt.scatter(X_test, Y_test, color="red", label="test data")#测试集为红色点
     
    #添加标签
    plt.legend(loc=2)#图标位于左上角,即第2象限,类似的,1为右上角,3为左下角,4为右下角
    plt.xlabel("The Connection amount of the average account")#添加 X 轴名称
    plt.ylabel("The ratio of average return amount")#添加 Y 轴名称
    plt.show()#显示散点图

    运行结果:  

    自变量---源数据: (14,) ;  训练集: (11,) ;  测试集: (3,)
    因变量---源数据: (14,) ;  训练集: (11,) ;  测试集: (3,)
    

    回归模型训练

    #调用线性规划包
    model = LinearRegression()
    
    #线性回归训练
    model.fit(X_train,Y_train)#调用线性回归包
    
    a  = model.intercept_#截距
    b = model.coef_#回归系数
    
    #训练数据的预测值
    y_train_pred = model.predict(X_train)
    #绘制最佳拟合线:标签用的是训练数据的预测值y_train_pred
    plt.plot(X_train, y_train_pred, color='blue', linewidth=2, label="best line")
    
    #测试数据散点图
    plt.scatter(X_train, Y_train, color='darkgreen', label="train data")
    plt.scatter(X_test, Y_test, color='red', label="test data")
     
    #添加图标标签
    plt.legend(loc=2)#图标位于左上角,即第2象限,类似的,1为右上角,3为左下角,4为右下角
    plt.xlabel("The Connection amount of the average account")#添加 X 轴名称
    plt.ylabel("The ratio of average return amount")#添加 Y 轴名称
    plt.show()#显示图像
    
    print("拟合参数:截距",a,",回归系数:",b)
    print("最佳拟合线: Y = ",round(a,2),"+",round(b[0],2),"* X")#显示线性方程,并限制参数的小数位为两位
    

    运行结果:  

    拟合参数:截距 -0.7291766860887745 ,回归系数: [1.71584366]
    最佳拟合线: Y =  -0.73 + 1.72 * X

    补充一句,有博友说单变量线性回归上面的这段代码中,加一个reshape就能运行出来了,可能是版本不同,我没加也能运行出来,所以分享在下面给大家参考一下,如果有和博友一样的情况,可以试试增加下面一段代码(谢谢博友 dsy23 的分享):

    
    #调用线性规划包
    model = LinearRegression()
    
    
    #在这里加一段
    X_train = X_train.values.reshape(-1,1)
    X_test = X_test.values.reshape(-1,1)
    
    
    
    #线性回归训练
    model.fit(X_train,Y_train)#调用线性回归包
    
    a  = model.intercept_#截距
    b = model.coef_#回归系数


    多变量线性回归

    在单变量线性回归中,我们将每一步都讲解的极其详细,所以在多变量线性回归中,我们不会重复讲那些简单的部分了,但是为了防止python小白迷失自己,所以在这部分该有的代码还是会甩出来,该有的备注也都有,只不过不会一点一点分步骤来了。

    上面我们提到多变量线性回归的模型为h(x)=theta0 + theta1* x 1 + theta2* x 2 + theta3* x 3,下面,我们还是使用单变量线性回归中的数据,单变量线性回归中,我们只用到了Connect(接通量)和Return(回款量),既然是多变量回归模型,那么我们就多加一个变量Call(拨打量)。

     

    数据检验(判断是否可以做线性回归)

    #-*- coding:utf-8 -*- 
    
    import pandas as pd
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    from pandas import DataFrame,Series
    from sklearn.cross_validation import train_test_split
    from sklearn.linear_model import LinearRegression
    
    #读取文件
    datafile = u'E:\\pythondata\\dhdhdh.xlsx'#文件所在位置,u为防止路径中有中文名称,此处没有,可以省略
    data = pd.read_excel(datafile)#datafile是excel文件,所以用read_excel,如果是csv文件则用read_csv
    examDf = DataFrame(data)
    
    #数据清洗,比如第一列有可能是日期,这样的话我们就只需要从第二列开始的数据,
    #这个情况下,把下面中括号中的0改为1就好,要哪些列取哪些列
    new_examDf = examDf.ix[:,0:]
    
    #检验数据
    print(new_examDf.describe())#数据描述,会显示最值,平均数等信息,可以简单判断数据中是否有异常值
    print(new_examDf[new_examDf.isnull()==True].count())#检验缺失值,若输出为0,说明该列没有缺失值
    
    #输出相关系数,判断是否值得做线性回归模型
    print(new_examDf.corr())#0-0.3弱相关;0.3-0.6中相关;0.6-1强相关;
    
    #通过seaborn添加一条最佳拟合直线和95%的置信带,直观判断相关关系
    sns.pairplot(data, x_vars=['Call','Connect'], y_vars='Return', size=7, aspect=0.8, kind='reg')  
    plt.show()
    

    运行结果:

                Call    Connect     Return
    count  99.000000  99.000000  99.000000
    mean    3.153649   1.967779   2.591121
    std     1.027607   0.470364   0.790172
    min     1.280100   1.014208   0.941292
    25%     2.373528   1.596610   2.044147
    50%     3.040000   1.913472   2.476091
    75%     3.835980   2.253994   3.035603
    max     5.851181   3.234977   5.160840
    Call       0
    Connect    0
    Return     0
    dtype: int64
                 Call   Connect    Return
    Call     1.000000  0.837052  0.744792
    Connect  0.837052  1.000000  0.844640
    Return   0.744792  0.844640  1.000000
    

    判断是否可以做线性回归

    • 异常值:通过最值或者平均数或者中位数等判断,或者直接通过查看是否有游离在大部队之外的点来判断是否有异常值;
    • 空值:这个没办法,你必须看运行结果的10-12行是否等于0,是0则无空值,如果不是0,就要看看是删掉空值呢?还是用其他值代替呢?不同情况不同对待;
    • 相关性:要么通过相关系数的大小判断,要么看散点图中的最佳拟合直线和95%的置信带,直观判断相关关系;

     

    训练线性回归模型

    #拆分训练集和测试集
    X_train,X_test,Y_train,Y_test = train_test_split(new_examDf.ix[:,:2],new_examDf.Return,train_size=0.8)
    #new_examDf.ix[:,:2]取了数据中的前两列为自变量,此处与单变量的不同
     
    print("自变量---源数据:",new_examDf.ix[:,:2].shape, ";  训练集:",X_train.shape, ";  测试集:",X_test.shape)
    print("因变量---源数据:",examDf.Return.shape, ";  训练集:",Y_train.shape, ";  测试集:",Y_test.shape)
    
    #调用线性规划包
    model = LinearRegression()
    
    model.fit(X_train,Y_train)#线性回归训练
    
    a  = model.intercept_#截距
    b = model.coef_#回归系数
    print("拟合参数:截距",a,",回归系数:",b)
    
    #显示线性方程,并限制参数的小数位为两位
    print("最佳拟合线: Y = ",round(a,2),"+",round(b[0],2),"* X1 + ",round(b[1],2),"* X2")
    
    Y_pred = model.predict(X_test)#对测试集数据,用predict函数预测
    
    plt.plot(range(len(Y_pred)),Y_pred,'red', linewidth=2.5,label="predict data")
    plt.plot(range(len(Y_test)),Y_test,'green',label="test data")
    plt.legend(loc=2)
    plt.show()#显示预测值与测试值曲线
    

    运行结果:

    自变量---源数据: (99, 2) ;  训练集: (79, 2) ;  测试集: (20, 2)
    因变量---源数据: (99,) ;  训练集: (79,) ;  测试集: (20,)
    拟合参数:截距 -0.006540954521370601 ,回归系数: [0.08624344 1.19029593]
    最佳拟合线: Y =  -0.01 + 0.09 * X1 +  1.19 * X2

    效果勉强满意,毕竟才用了80个数训练的模型,要求高的话多用一些数据就好。

    除了用 Python 做线性回归,我们还可以使用 SPSS 来做,不用编程,不用各种调参,就是点几下就可以输出结果,更简便!具体操作请参考下面链接里的文章:

    数据建模 - SPSS做多元线性回归 - 分析步骤、输出结果详解、与Python的结果对比 -(SPSS)

     

    【此处是重点】打赏一下发数据!

    https://download.csdn.net/download/weixin_40683253/11890448

     

     

    展开全文
  • SPSS多元线性回归输出结果的详细解释

    万次阅读 多人点赞 2017-06-27 17:41:05
    最近做了一些用SPSS进行线性回归的实验,还是感觉很多细节把握不好,这里结合我的实验结果,以及网上别人的介绍总结一下,先贴几张SPSS的输出: 下面简单解释一下这三张图中的结果: 第一个表模型汇总表中,...
  • 当只有一个自变量时,称为简单线性回归,当具有多个自变量时,称为多元线性回归。 线性关系的理解: 画出来的图像是直的。 每个自变量的最高次项为1。 拟合是指构建一种算法,使得该算法能够符合真实的数据。从...
  • python机器学习手写算法系列——线性回归

    万次阅读 多人点赞 2019-05-06 19:51:29
    本文致力于手把手教你实现一个最简单的机器学习模型--一元线性回归模型。短短的14行代码,就实现了。希望读完以后,你也能自己实现它。并对线性回归有更好的了解,或者从不了解到了解。
  • 本课程主要讲述如何使用python进行线性回归与非线性回归分析,包括: 基于statsmodel的线性回归方法 基于sklearn的线性回归方法 基于Numpy的一元多项式非线性回归方法 基于sklearn的多元多项式非线性回归方法 基于...
  • 线性回归从一元线性回归入门

    千次阅读 2018-08-07 01:03:59
    本文是从一元线性回归为为基础来理解线性回归,适合于线性回归的入门,让初学者对于线性回归有直观的理解。本文也是我对于线性回归算法入门学习,分享给大家。 线性回归的定义 回归是用于应用于输入变量与输出...
  • 机器学习(三)线性回归模型、广义线性回归模型、非线性回归模型   线性回归(数据集要满足正态分布) 一元线性回归模型: 在这里会想到,如何确定方程中的系数呢?我们先来了解最小二乘法,简单来说就是这个点...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,884
精华内容 22,753
关键字:

线性回归