精华内容
下载资源
问答
  • linearregression
    千次阅读
    2022-01-26 21:28:09

    0. 引入

    下面是一个简单的数据集:

    x_data = np.array(  [[1,1,1 ],[2,4,8],[3,9,27],[4,16,64]]  )
    y_data = np.array( [3,2,0,5] )
    

    用sklearn自带的的LinearRegression,得到的结果(这是正确结果)。

    model.coef_ = array([15.16666667, -8.5       ,  1.33333333])
    model.intercept_ = −5.00000000000028
    

    也就是说,最终拟合的直线为:y=-5+15.17x_1-8.5x_2+1.33*x_3

    但是,用numpy从头实现的LinearRegression(参考2中有详细代码),得到的结果,就与这个大有不同了。

    为什么会有不同呢?

    1. numpy从头实现的LinearRegression

    参考2中有详细代码,下面给出原理注释:

    import numpy as np
    import pandas as pd
        
    class XLinearRegression() :
        def __init__( self, learning_rate, iterations ):
            self.learning_rate = learning_rate# 学习速率
            self.iterations = iterations# 迭代次数
            
        # 训练模型f(x)=wx+b
        def fit( self, X, Y ):
            # self.m是样本数量,self.n是特征数量
            self.m, self.n = X.shape
            # 初始化权重
            self.W = np.zeros( self.n )
            self.b = 0
            self.X = X
            self.Y = Y
              
            # 梯度下降更新权重的过程
            for i in range( self.iterations ):
                self.update_weights()
                
            return self
          
        # 梯度下降法更新权重
        def update_weights( self ):
            Y_pred = self.predict( self.X )#根据上一次求解得到的权重,获取预测值
            # 计算梯度
            #   MSE=Sigma(true-pred)^2, MSE对W和b分别求偏导数即可得到如下梯度
            dW = - ( 2 * ( self.X.T ).dot( self.Y - Y_pred )  ) / self.m
            db = - 2 * np.sum( self.Y - Y_pred ) / self.m 
            # 更新权重(负梯度方向)
            self.W = self.W - self.learning_rate * dW
            self.b = self.b - self.learning_rate * db
            return self
          
        # 根据求得的权重,求待拟合函数f(x)的值
        def predict( self, X ):
            return X.dot( self.W ) + self.b
    

    下面代码使用该线性回归

    x_data = np.array(  [[1,1,1 ],[2,4,8],[3,9,27],[4,16,64]]  )
    y_data = np.array( [3,2,0,5] )
    model = XLinearRegression(learning_rate=0.001, iterations=30)
    model.fit(x_data,y_data)
    print(model.W,model.b)
    

    得到的权重W为:[ -11305.592508 -41387.85209775 -155378.28247138]
    偏移(截距)b为:-3211.3991546315137

    结果错的很离谱。

    2. sklearn的LinearRegression源码原理

    那sklearn的LinearRegression是如何求解权重的呢?我们参考1对sklearn的LinearRegression做个动态调试:
    详细步骤见参考1。

    1. 找到第三方库所在的位置
      先利用如下Python代码找到sklearn源码位置。我的位置在 /xx/anaconda3/envs/env_test_py38/lib/python3.8/site-packages/sklearn
    import sklearn, os
    path = os.path.dirname(sklearn.__file__)
    
    1. 在第三方库源码中加断点

    首先找到sklearn的LinearRegression的源码,见参考3。
    然后在这个位置打开文件,用pdb加上断点

    • /xx/anaconda3/envs/env_test_py38/lib/python3.8/site-packages/sklearn/linear_model/_base.py
    1. 运行测试程序

    测试程序如下,直接调用 sklearn的LinearRegression 来训练模型。

    from sklearn.linear_model import LinearRegression
    import numpy as np
    
    x_data = np.array(  [[1,1,1],[2,4,8],[3,9,27],[4,16,64]]  )
    y_data = np.array( [3,2,0,5] )
    
    model = LinearRegression()
    model.fit(x_data,y_data)
    
    1. 源码调试过程

    加上断点后,可以单步调试。

    从调试中,可以看到,对于如本文这样一般性的数据,使用默认的fit()参数,源码主要做了两件事情

    (1)数据预处理,通过如下函数,对数据做了normalization

    X, y, X_offset, y_offset, X_scale = self._preprocess_data(
        X,
        y,
        fit_intercept=self.fit_intercept,
        normalize=_normalize,
        copy=self.copy_X,
        sample_weight=sample_weight,
        return_mean=True,
    )
    

    在预处理之前,数据值为

    (Pdb) X,y
    (array([[ 1,  1,  1],
           [ 2,  4,  8],
           [ 3,  9, 27],
           [ 4, 16, 64]]), array([3, 2, 0, 5]))
    
    

    在预处理之后,数据值变为

    (Pdb) X,y
    (array([[ -1.5,  -6.5, -24. ],
           [ -0.5,  -3.5, -17. ],
           [  0.5,   1.5,   2. ],
           [  1.5,   8.5,  39. ]]), array([ 0.5, -0.5, -2.5,  2.5]))
    

    注意这里连y值也变了

    (2)调用numpy中的linalg.lstsq最小二乘法来求解线性方程

    elf.coef_, self._residues, self.rank_, self.singular_ = linalg.lstsq(X, y)
    

    这里是对预处理之后的数据进行求解。

    3. sklearn的LinearRegression的数据预处理原理

    从源码中,可以找到预处理部分的源码(详见参考4),加上断点调试后,可以发现,最关键的预处理过程源码为:

    X_offset = np.average(X, axis=0)
    X -= X_offset
    y_offset = np.average(y, axis=0)
    y = y - y_offset
    

    即对矩阵X按列求平均值,并用每一列的数值减去平均值;对y也是一样,求平均值后相减。

    把这个过程用如下代码测试:

    import numpy as np
    x_data = np.array(  [[1,1,1],[2,4,8],[3,9,27],[4,16,64]]  )
    y_data = np.array( [3,2,0,5] )
    x_data = x_data-np.average(x_data,axis=0)
    y_data = y_data-np.average(y_data)
    print(x_data)
    print(y_data)
    

    得到的结果为

    [[ -1.5  -6.5 -24. ]
     [ -0.5  -3.5 -17. ]
     [  0.5   1.5   2. ]
     [  1.5   8.5  39. ]]
    [ 0.5 -0.5 -2.5  2.5]
    
    

    这个结果与2.4中“在预处理之后,数据值变为”的结果完全一致。

    4. 用 numpy.linalg.lstsq 复现sklearn的LinearRegression结果

    numpy.linalg.lstsq只能计算y=Wx+b中的W,无法得到b的值。

    对sklearn的LinearRegression中计算b(intercept_)的过程进一步动态调试(源码详见参考5),可以发现,b的计算过程为:

    -> self.coef_ = self.coef_ / X_scale
    (Pdb) X_scale
    array([1., 1., 1.])
    (Pdb) self.coef_
    array([15.16666667, -8.5       ,  1.33333333])
    (Pdb) n
    -> self.intercept_ = y_offset - np.dot(X_offset, self.coef_.T)
    (Pdb) X_offset
    array([ 2.5,  7.5, 25. ])
    (Pdb) y_offset
    2.5
    (Pdb) n
    --Return--
    -> self.intercept_ = y_offset - np.dot(X_offset, self.coef_.T)
    (Pdb) self.intercept_
    -5.000000000000277
    

    这样得到的截距值-5.00就是正确的了。

    下面给出完整版本的使用numpy.linalg.lstsq 复现sklearn的LinearRegression结果的代码

    import numpy as np
    
    # setp-01: original dataset
    x_data = np.array(  [[1,1,1],[2,4,8],[3,9,27],[4,16,64]]  )
    y_data = np.array( [3,2,0,5] )
    # step-02: preprocess
    x_offset = np.average(x_data,axis=0)
    x_data = x_data-x_offset
    y_offset = np.average(y_data)
    y_data = y_data-y_offset
    # step-03: lstsq
    coef,_,_,_ = np.linalg.lstsq(x_data,y_data,rcond=None)
    x_scale = np.ones(len(coef))
    intercept = y_offset - np.dot(x_offset, coef.T)
    # result
    print(coef)# W = [15.16666667 -8.5         1.33333333]
    print(intercept)# b = -5.000000000000277
    

    5. 总结

    1. sklearn的LinearRegression源码,会首先对数据做预处理(X,Y都减去列均值),然后再用numpy中lstsq求解线性回归
    2. 如果不做这个预处理,得到的值是与直接调用sklearn的LinearRegression得到的不相同的
    3. 动态调试结束,一定要删除断点
    4. 目前还没有找到靠谱的如原文1中的XLinearRegression一样从头写的多元线性回归源代码

    6. 参考

    1. 动态调试python第三方库。https://blog.csdn.net/ybdesire/article/details/54649211
    2. https://www.geeksforgeeks.org/linear-regression-implementation-from-scratch-using-python/
    3. sklearn的LinearRegression源码. https://github.com/scikit-learn/scikit-learn/blob/0d378913b/sklearn/linear_model/_base.py#L507
    4. https://github.com/scikit-learn/scikit-learn/blob/0d378913be6d7e485b792ea36e9268be31ed52d0/sklearn/linear_model/_base.py#L213
    5. https://github.com/scikit-learn/scikit-learn/blob/0d378913be6d7e485b792ea36e9268be31ed52d0/sklearn/linear_model/_base.py#L366
    更多相关内容
  • LinearRegression

    2021-03-27 15:10:27
    PyTorch线性回归PyTorch实现线性回归 包括模型训练,保存,推理使用等 ...│ └── net_regression.py ├── tool │ ├── generate_data.py │ └── merge_csv.py ├── trainner.py └── util
  • 四、多变量线性回归(Linear Regression with Multiple Variables) 4.1 多维特征 4.2 多变量梯度下降 4.3 梯度下降法实践1-特征缩放 4.4 梯度下降法实践2-学习率 4.5 特征和多项式回归 4.6 正规方程 4.1 多维特征 当...
  • LinearRegression.rar

    2019-06-03 15:06:54
    LinearRegression.rar,LinearRegression,ex1data1.txt,LinearRegression.py,QuadraticFunction.py6.1101,17.592 5.5277,9.1302 8.5186,13.662 7.0032,11.854 5.8598,6.8233 8.3829,11.886 7.4764,4.3483 8.5781,12 6...
  • sklearn.linear_model.LinearRegression 调用 sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=None) Parameters fit_intercept 释义:是否计算该模型的截距。 ...
  • LinearRegression-master.zip,LinearRegression-master,read me.txt,README.text,LinearRegression,LinearRegression.py,100(1000)_100_train.csv,test-100-100.csv,LearningCurve.py,CrossValidation,Output-...
  • 55947-variational-bayesian-linear-regression.zip,linRegVb.zip
  • 关于吴恩达coursera课程机器学习 线性回归编程实验答案
  • 练习线性回归的数据集 Linear Regression - Sheet1.csv
  • 线性回归(LinearRegression)实现房价预测-附件资源
  • 回归-PM2.5预测(李宏毅)
  • LinearRegression-master.zip,LinearRegression-master,ML_LinReg.m,ML_mvLinReg.m,ex1data1.txt,README.md,ML_mvLinReg_normal.m,ex1data2.txt
  • Linear regression with Yelp votes.zip,yelp.csv,Homework-1-4.ipynb,yelp.json
  • Applied Linear Regression, Third Edition is thoroughly updated to help students master the theory and applications of linear regression modeling. Focusing on model building, assessing fit and ...
  • Multiple Linear Regression.zip,Multiple Linear Regression.py
  • linear regression with matlab code
  • sklearn LinearRegression

    千次阅读 2021-11-11 10:48:23
    from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt loaded_data = datasets.load_boston() data_X = loaded_data.data data_y = loaded_data.target model = LinearRegression...
    from sklearn import datasets
    from sklearn.linear_model import LinearRegression
    import matplotlib.pyplot as plt
    
    loaded_data = datasets.load_boston()
    data_X = loaded_data.data
    data_y = loaded_data.target
    
    model = LinearRegression()
    model.fit(data_X, data_y)   # 训练模型, 找到规律 截距与斜率
    
    
    
    print(model.predict(data_X[:4, :]))  # 测试将数据喂到模型中
    print(data_y[:4])  # 测试数据的标签
    
    # y=0.1x_1 + 0.2x_2 0.3
    print(model.coef_) # y=0.1x_1 + 0.2x_2 0.3  打印x的系数0.1,0.2 相当于每个特征对应的x的系数,对应房价来说,比如楼层、地段等等关于x的参数
    print(model.intercept_)  # 打印0.3, 跟y轴的交点
    
    print(model.get_params()) # 模型的参数 例如{'copy_X': True, 'fit_intercept': True, 'n_jobs': None, 'normalize': False, 'positive': False},这都是在模型定义的时候默认的
    

    model.score(data_X, data_y) : 返回模型的该次预测的系数 R 2 R^2 R2,其中
    R 2 = 1 − u / v u = ( ( y t r u e − y p r e d ) 2 ) . s u m ( ) v = ( ( y t r u e − y t r u e . m e a n ( ) ) 2 ) . s u m ( ) R^2=1-u/v \\ u=((y_{true} - y_{pred}) ^ 2).sum() \\ v=((y_{true} - y_{true}.mean()) ^ 2).sum() R2=1u/vu=((ytrueypred)2).sum()v=((ytrueytrue.mean())2).sum()
    在这里插入图片描述

    model.fit(data_X, data_y)解析

    sklearn.linear_model.LinearRegression求解线性回归方程参数时,首先判断训练集X是否是稀疏矩阵,如果是,就用Golub&Kanlan双对角线化过程方法来求解;否则调用C库中LAPACK中的用基于分治法的奇异值分解来求解。

    在sklearn中并不是使用梯度下降法求解线性回归,而是使用最小二乘法求解。

    sklearn.LinearRegression的fit()方法:

            if self.positive:
                if y.ndim < 2:
                    self.coef_, self._residues = optimize.nnls(X, y)
                else:
                    # scipy.optimize.nnls cannot handle y with shape (M, K)
                    outs = Parallel(n_jobs=n_jobs_)(
                            delayed(optimize.nnls)(X, y[:, j])
                            for j in range(y.shape[1]))
                    self.coef_, self._residues = map(np.vstack, zip(*outs))
            elif sp.issparse(X):
                X_offset_scale = X_offset / X_scale
    
                def matvec(b):
                    return X.dot(b) - b.dot(X_offset_scale)
    
                def rmatvec(b):
                    return X.T.dot(b) - X_offset_scale * np.sum(b)
    
                X_centered = sparse.linalg.LinearOperator(shape=X.shape,
                                                          matvec=matvec,
                                                          rmatvec=rmatvec)
    
                if y.ndim < 2:
                    out = sparse_lsqr(X_centered, y)
                    self.coef_ = out[0]
                    self._residues = out[3]
                else:
                    # sparse_lstsq cannot handle y with shape (M, K)
                    outs = Parallel(n_jobs=n_jobs_)(
                        delayed(sparse_lsqr)(X_centered, y[:, j].ravel())
                        for j in range(y.shape[1]))
                    self.coef_ = np.vstack([out[0] for out in outs])
                    self._residues = np.vstack([out[3] for out in outs])
            else: # 如果X不是稀疏矩阵
                self.coef_, self._residues, self.rank_, self.singular_ = \
                    linalg.lstsq(X, y)
                self.coef_ = self.coef_.T
    

    如果训练集X是稀疏矩阵,就用sparse_lsqr()求解,否则使用linalg.lstsq()

    scipy.linalg.lstsq()方法就是用来计算X为非稀疏矩阵时的模型系数。这是使用普通的最小二乘OLS法来求解线性回归参数的。
    在这里插入图片描述

    模型的参数可以通过lin_reg.intercept_(截距)、lin_reg.coef_(系数)查看参数。

    线性回归拟合原理

    拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。因为这条曲线有无数种可能,从而有各种拟合方法。拟合的曲线一般可以用函数表示。

    对于一元线性回归(单变量线性回归)来说,学习算法为 y = ax + b 换一种写法: h θ ( x ) = θ 0 + θ 1 x 1 h_θ(x) = θ_0 + θ_1x_1 hθ(x)=θ0+θ1x1

    线性回归实际上要做的事情就是: 选择合适的参数 ( θ 0 , θ 1 ) (θ_0, θ_1) (θ0,θ1),使得 h θ ( x ) h_θ(x) hθ(x)方程,很好的拟合训练集。实现如何把最有可能的直线与我们的数据相拟合。

    我们选择的参数决定了我们得到的直线相对于我们的训练集的准确程度,模型所预测的值与训练集中实际值之间的差距就是建模误差(modeling error)。

    我们的目标便是选择出可以使得建模误差的平方和能够最小的模型参数。 即使得损失函数最小

    展开全文
  • LinearRegression_Explained 这是一个包含使用Sklearn,pandas,Numpy和Seaborn进行线性回归的解释的存储库。 还执行探索性数据分析和可视化。 该说明分为以下几部分,我们将详细介绍每一部分: 了解问题陈述,数据...
  • 吴恩达机器学习作业1-linear regression。matlab代码。
  • Linear Regression.zip,Influential Observations, High Leverage Points, and Outliers in Linear Regression..pdf
  • sklearn学习01——LinearRegression / LogisticRegression 前言 一、一/多元线性回归 1.1、数据生成 1.2、得到模型 1.3、模型测试和比较 1.4、多元线性回归 1.5、训练一元线性模型常用方法——梯度下降法 二、多项式...


    前言

    在学习了机器学习(周志华)的一系列的模型和学习算法之后,我们也需要使用python实际操作,实现它的效果,进而深入理解这些模型的原理。本篇讲解 几种线性回归 的sklearn实现。

    一、一/多元线性回归

    1.1、数据生成

    仅为了更加方便直观的理解机器学习算法,这里使用人工生成的简单数据。生成数据的思路是:设定一个二维的函数(维度高了没办法在平面上画出来),根据这个函数生成一些离散的数据点,对每个数据点我们可以适当的加一点波动,也就是噪声。代码如下:

    import numpy as np
    import matplotlib.pyplot as plt 
    
    def true_fun(X): # 这是我们设定的真实函数,我们的模型越接近它越好
        return 1.5*X + 0.2
    
    np.random.seed(0) # 设置随机种子
    n_samples = 30 # 设置采样数据点的个数
    
    '''生成随机数据作为训练集,并且加一些噪声'''
    X_train = np.sort(np.random.rand(n_samples)) 
    y_train = (true_fun(X_train) + np.random.randn(n_samples) * 0.05).reshape(n_samples,1)
    

    30个样本,每个样本都只有一个特征(因为是一维的)。

    注意:噪声是按照正态分布随机生成的30个数,附加到每个样本的 y 上,因此 y 也是符合正态分布的了。

    1.2、得到模型

    第一步生成好了数据,即有了训练集。接下来可以定义我们的算法模型,因为sklearn库中有类LinearRegression,所以直接调用它作为我们的线性模型即可。我们要做的就是:将训练集放入该LinearRegression模型中,然后等待它调用自己内部的方法求得最优解。代码如下:

    from sklearn.linear_model import LinearRegression # 导入线性回归模型
    model = LinearRegression() # 定义模型
    model.fit(X_train[:,np.newaxis], y_train) # 训练模型
    print("输出参数w:",model.coef_) # 输出模型参数w
    print("输出参数b:",model.intercept_) # 输出参数b
    

    输出参数w: [[1.4474774]]
    输出参数b: [0.22557542]

    1.3、模型测试和比较

    第二步我们根据训练集和 sklearn 库中的模型算法得到一组解,写成方程形式为:y = 1.4474774 * x + 0.22557542,而真实的函数为:y = 1.5*x + 0.2,相比来说还是非常接近的。下面使用python代码将训练集(30个样本点)、我们学得的模型、真实模型都可视化出来:

    X_test = np.linspace(0, 1, 100)
    plt.plot(X_test, model.predict(X_test[:, np.newaxis]), label="Model")
    plt.plot(X_test, true_fun(X_test), label="True function")
    plt.scatter(X_train,y_train) # 画出训练集的点
    plt.legend(loc="best")
    plt.show()
    

    对比

    1.4、多元线性回归

    多元的线性回归,思路与一元是一样的。使用sklearn库来实现的话,我们只需要准备一组 多元的训练集 即可,依旧调用 内部的LinearRegression类 实现模型的训练,代码如下:

    from sklearn.linear_model import LinearRegression
    
    X_train = [[1,1,1],[1,1,2],[1,2,1]] # 以三元为例
    y_train = [[6],[9],[8]]
     
    model = LinearRegression()
    model.fit(X_train, y_train)
    print("输出参数w:",model.coef_) # 输出参数w1,w2,w3
    print("输出参数b:",model.intercept_) # 输出参数b
    test_X = [[1,3,5]]
    pred_y = model.predict(test_X)
    print("预测结果:",pred_y)
    

    1.5、训练一元线性模型常用方法——梯度下降法

    梯度下降法大致流程如下图:
    梯度下降
    首先先假定我们的线性模型为:线性模型
    那么损失函数为:
    损失函数
    要求损失函数最小值,我们对其求梯度:

    梯度
    上述梯度使用矩阵形式表示:
    梯度
    在使用梯度下降算法更新我们线性模型的参数时,先初始化这些参数为全 1,然后按照梯度下降的方向更新所有的参数(批量梯度下降),达到迭代次数或者达到精度即可停止更新。代码如下:

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 梯度下降方法 实现一元线性回归模型
    def true_fun(X):
        return 1.5 * X + 0.2
    
    
    np.random.seed(0)  # 随机种子
    n_samples = 30
    '''生成随机数据作为训练集'''
    X_train = np.sort(np.random.rand(n_samples))
    y_train = (true_fun(X_train) + np.random.randn(n_samples) * 0.05).reshape(n_samples, 1)
    
    # 添加一维数据
    data_X = []
    for x in X_train:
        data_X.append([1, x])
    
    print(data_X)
    data_X = np.array((data_X))
    print(data_X)
    
    m,p = np.shape(data_X) # m, 数据量 p: 特征数
    max_iter = 1000 # 迭代数
    weights = np.ones((p,1))   # 初始权重:设置为 1
    print(weights)
    alpha = 0.1 # 学习率
    for i in range(0,max_iter):
        error = np.dot(data_X,weights)- y_train
        gradient = data_X.transpose().dot(error)/m
        weights = weights - alpha * gradient
    print("输出参数w:",weights[1:][0]) # 输出模型参数w
    print("输出参数b:",weights[0]) # 输出参数b
    
    X_test = np.linspace(0, 1, 100)
    plt.plot(X_test, X_test*weights[1][0]+weights[0][0], label="Model")
    plt.plot(X_test, true_fun(X_test), label="True function")
    plt.scatter(X_train,y_train) # 画出训练集的点
    plt.legend(loc="best")
    plt.show()
    

    输出参数w: 1.4454389990357697
    输出参数b: 0.2268326207539249

    二、多项式线性回归

    • 训练集
      用来训练模型内参数的数据集
    • 验证集
      用于在训练过程中检验模型的状态,收敛情况,通常用于调整超参数,根据几组模型验证集上的表现决定哪组超参数拥有最好的性能。
      同时验证集在训练过程中还可以用来监控模型是否发生过拟合,一般来说验证集表现稳定后,若继续训练,训练集表现还会继续上升,但是验证集会出现不升反降的情况,这样一般就发生了过拟合。所以验证集也用来判断何时停止训练
    • 测试集
      测试集用来评价模型泛化能力,即使用训练集调整了参数,之前模型使用验证集确定了超参数,最后使用一个不同的数据集来检查模型。

    这里我们使用 交叉验证方法来获得多组的 训练集/测试集,求得每组的模型评估(回归的评估度量手段一般为均方误差)然后求平均,作为评估此模型的标准。
    交叉验证
    多项式回归代码如下(这里尝试了三个最高次 1、4、15):

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import PolynomialFeatures
    from sklearn.linear_model import LinearRegression
    from sklearn.model_selection import cross_val_score
    
    def true_fun(X):
        return np.cos(1.5 * np.pi * X)
    np.random.seed(0)
    
    n_samples = 30
    degrees = [1, 4, 15] # 多项式最高次
    
    X = np.sort(np.random.rand(n_samples)) 
    y = true_fun(X) + np.random.randn(n_samples) * 0.1
    
    plt.figure(figsize=(14, 5))
    for i in range(len(degrees)):
        ax = plt.subplot(1, len(degrees), i + 1)
        plt.setp(ax, xticks=(), yticks=())
    
        polynomial_features = PolynomialFeatures(degree=degrees[i],
                                                 include_bias=False)
        linear_regression = LinearRegression()
        pipeline = Pipeline([("polynomial_features", polynomial_features),
                             ("linear_regression", linear_regression)]) # 使用pipline串联模型
        pipeline.fit(X[:, np.newaxis], y)
    
        # 使用交叉验证
        scores = cross_val_score(pipeline, X[:, np.newaxis], y,
                                 scoring="neg_mean_squared_error", cv=10)
        X_test = np.linspace(0, 1, 100)
        plt.plot(X_test, pipeline.predict(X_test[:, np.newaxis]), label="Model")
        plt.plot(X_test, true_fun(X_test), label="True function")
        plt.scatter(X, y, edgecolor='b', s=20, label="Samples")
        plt.xlabel("x")
        plt.ylabel("y")
        plt.xlim((0, 1))
        plt.ylim((-2, 2))
        plt.legend(loc="best")
        plt.title("Degree {}\nMSE = {:.2e}(+/- {:.2e})".format(
            degrees[i], -scores.mean(), scores.std()))
    plt.show()
    

    三、逻辑(Logistic)回归

    3.1、损失函数

    我们知道,在线性模型上套一个Sigmoid函数就成了对数几率回归(具体参考西瓜书),假设此模型为:
    模型
    其中
    再参考西瓜书得到其损失函数,这里直接写出来:
    损失

    3.2、梯度下降法

    梯度

    3.3、代码实现

    import sys
    from pathlib import Path
    curr_path = str(Path().absolute())
    parent_path = str(Path().absolute().parent)
    sys.path.append(parent_path) # add current terminal path to sys.path
    
    import numpy as np
    from Mnist.load_data import load_local_mnist
    
    (x_train, y_train), (x_test, y_test) = load_local_mnist(one_hot=False)
    
    # print(np.shape(x_train),np.shape(y_train))
    
    ones_col=[[1] for i in range(len(x_train))] # 生成全为1的二维嵌套列表,即[[1],[1],...,[1]]
    x_train_modified=np.append(x_train,ones_col,axis=1)
    ones_col=[[1] for i in range(len(x_test))]
    x_test_modified=np.append(x_test,ones_col,axis=1)
    
    # print(np.shape(x_train_modified))
    
    # Mnsit有0-9十个标记,由于是二分类任务,所以可以将标记0的作为1,其余为0用于识别是否为0的任务
    y_train_modified=np.array([1 if y_train[i]==1 else 0 for i in range(len(y_train))])
    y_test_modified=np.array([1 if y_test[i]==1 else 0 for i in range(len(y_test))])
    n_iters=10 
    
    x_train_modified_mat = np.mat(x_train_modified)
    theta = np.mat(np.zeros(len(x_train_modified[0])))
    lr = 0.01 # 学习率
    
    def sigmoid(x):
        '''sigmoid函数
        '''
        return 1.0/(1+np.exp(-x))
    
    

    小批量梯度下降法

    for i_iter in range(n_iters):
        for n in range(len(x_train_modified)):
            hypothesis = sigmoid(np.dot(x_train_modified[n], theta.T))
            error = y_train_modified[n]- hypothesis
            grad = error*x_train_modified_mat[n]
            theta += lr*grad
        print('LogisticRegression Model(learning_rate={},i_iter={})'.format(
        lr, i_iter+1))
    

    总结

    本文对一元线性回归、多元线性回归、多项式线性回归以及逻辑回归进行了算法分析和代码实现,梯度下降法也是求凸函数最优解常用的方法;同时,sklearn相关库、函数的调用掌握不足,需要多加学习。另外,本文参考了下述链接:
    机器学习算法实现

    展开全文
  • 线性回归linear_model.LinearRegression

    千次阅读 2021-03-31 10:25:03
    linear_model.LinearRegression 超参数 fit_intercept–是否计算截距,默认计算 normalize–是否标准化,默认不做 copy_x–是否对x肤质,如果为false,则经过中心化,标准化后,吧新数据覆盖到原数据上 n_job–计算...

    线性回归–监督学习

    linear_model.LinearRegression

    超参数

    fit_intercept–是否计算截距,默认计算
    normalize–是否标准化,默认不做
    copy_x–是否对x肤质,如果为false,则经过中心化,标准化后,吧新数据覆盖到原数据上
    n_job–计算时设置的任务个数

    属性:

    coef_:得到的feature的系数
    intercept——截距,线性模型中的独立项
    rank_:矩阵的秩
    singular_ :矩阵的奇异值,尽在x为密集矩阵时有效

    方法

    fit
    predict
    score(模型评估,返回r^2系数,最优值为1,说明所有的数据都预测正确)
    get_params()返回一个字典,键为参数名,值为估计器参数值
    set_params 设置估计器的参数,可以修改参数重新训练

    from sklearn.linear_model import LinearRegression
    x=np.array([2,6])
    y=np.array([3,5])
    rfs=LinearRegression()
    rfs.fit(x,y)
    #报错:ValueError: Expected 2D array, got 1D array instead:array=[2 6].
    #Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample
    

    在这里插入图片描述

    所以,线性回归的x一定是二维的矩阵

    x=x.reshape(-1,1)
    x
    #x=np.array([[2],[6]])
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    #假设有第三个点,坐标为(3,6)
    x2=np.array([[2],[3],[6]])
    y2=np.array([3,6,5])
    # 绘制三个点的散点图
    plt.scatter(x2,y2,s=180,c='r')
    # 利用线性回归模型拟合一条有均方误差最小的直线
    lr_2=LinearRegression()
    lr_2.fit(x2,y2)
    
    y2_predict=lr_2.predict(x_test)
    print(y2_predict)
    
    print(lr_2.coef_,lr_2.intercept_)
    

    在这里插入图片描述

    #利用datasets升恒用于回归分析的数据集
    from sklearn.datasets import make_regression
    X_3,y_3=make_regression(n_samples=100,n_features=1)
    plt.scatter(X_3,y_3)
    

    在这里插入图片描述

    #绘制出拟合的直线
    z=np.linspace(0,6,100)
    z_predict=lr_2.predict(z.reshape(-1,1))
    plt.plot(z,z_predict,lw=5,c='g')
    plt.scatter(x2,y2,s=180,c='r')
    #计算R方系数
    lr_2.score(x2,y2)
    #计算均方误差
    from sklearn.metrics import mean_squared_error
    mean_squared_error(y2,y2_predict)
    

    在这里插入图片描述

    利用make_regression 制作

    n_samples:样本数
    n_features:特征数
    n_information:参与建模特征数
    n_target:因变量个数
    noise:噪音
    bias:偏差
    coef:是否输出coef标识
    random_state

    from sklearn.datasets import make_regression
    X_3,y_3=make_regression(n_samples=100,n_features=1,noise=50,random_state=8)
    
    plt.scatter(X_3,y_3)
    

    在这里插入图片描述

    rfs=LinearRegression()
    rfs.fit(X_3,y_3)
    k=rfs.coef_#斜率
    b=rfs.intercept_
    plt.plot(X_3,k*X_3+b)
    

    在这里插入图片描述

    #利用线性回归进行拟合
    X_3,y_3=make_regression(n_samples=100,n_features=1,noise=50,random_state=8)
    plt.scatter(X_3,y_3)
    rfs=LinearRegression()
    rfs.fit(X_3,y_3)
    y_3=rfs.predict(X_3)
    plt.plot(X_3,y_3,'r-')
    

    在这里插入图片描述

    糖尿病数据集的线性回归

    from sklearn.datasets import load_diabetes
    diabetes=load_diabetes()
    print(diabetes['DESCR'])
    
    

    在这里插入图片描述

    X=diabetes.data#特征变量
    y=diabetes.target#因变量
    print(X.shape,y.shape)
    #划分训练集测试集
    from sklearn.model_selection import train_test_split
    X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=8)
    lr=LinearRegression().fit(X_train,y_train)
    y_test=lr.predict(X_test)
    print(lr.score(X_train,y_train))
    print(lr.score(X_test,y_test))
    

    在这里插入图片描述

    from sklearn import datasets
    X,y = datasets.load_diabetes(return_X_y=True)
    

    岭回归实践

    超参数

    alpha
    fit_intercept:截距
    copy_X:若为true,将复制x,否则,可能被覆盖
    max_iter:共振梯度求解器的最大迭代次数,若为none,则为默认值,不同silver的默认值不同,对于’sparse_cg’/'lsgr’求解器,默认值由scipy.sparse.linalg确定。对于’sag’求解器,默认值为1000
    normalize:如果为真,则回归x在回归之前被归一化。

    from sklearn.linear_model import Ridge
    ridge=Ridge()
    from sklearn.datasets import load_diabetes
    diabetes=load_diabetes()
    X=diabetes.data
    y=diabetes.target
    from sklearn.model_selection import train_test_split
    X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=8)
    ridge.fit(X_train,y_train)
    print(ridge.score(X_train,y_train))
    print(ridge.score(X_test,y_test))
    

    在这里插入图片描述

    岭回归的参数调节

    # 正则化系数alpha=10
    ridge10=Ridge(alpha=10).fit(X_train,y_train)
    print(ridge10.score(X_train,y_train))
    print(ridge10.score(X_test,y_test))
    

    在这里插入图片描述

    # 正则化系数alpha=0.1
    ridge01=Ridge(alpha=0.1).fit(X_train,y_train)
    print(ridge01.score(X_train,y_train))
    print(ridge01.score(X_test,y_test))
    

    在这里插入图片描述

    # 模型系数的可视化比较
    plt.plot(ridge.coef_,'s',label='ridge alpha=1')
    plt.plot(ridge10.coef_,label='ridge alpha=10')
    plt.plot(ridge01.coef_,label='ridge alpha=0.1')
    plt.xlabel('系数序号')
    plt.ylabel('系数量级')
    plt.hlines(0,0,len(lr.coef_))
    plt.legend(loc='best')
    plt.grid(linestyle=':')
    plt.rcParams['font.sans-serif']=['SimHei','Times New Roman']
    plt.rcParams['axes.unicode_minus']=False
    

    在这里插入图片描述

    绘制学习曲线,取固定的alpha值,改变训练集的数据量

    from sklearn.model_selection import learning_curve,KFold
    
    def plot_learning_curve(est,X,y):
        training_set_size,train_scores,test_scores=learning_curve(est,X,y,train_sizes=np.linspace(.1,1,20),cv=KFold(20,shuffle=True,random_state=1))
        eatimator_name=est._class_._name_
        line=plt.plot(training_set_size,train_scores.mean(axis=1),'--',label='training'+estimator_name)
        plt.plot(training_set_size,test_scores.mean(axis=1),'-',label='test'+estimator_name,c=line[0].get_color())
        plt.xlabel('training set size')
        plt.ylabel('score')
        plt.ylim(0,1.1)
    plot_learning_curve(Ridge(alpha=1),X,y)
    plot_learning_curve(Ridge(LinearRegressiong(),X,y))
    plt.legend(loc=(0,1.05),ncol=2,fontsize=11)
    
    plt.grid(linestyle=':')
    

    Lasso回归实践

    from sklearn.linear_model import Lasso
    lasso=Lasso()
    lasso.fit(X_train,y_train)
    print(lasso.score(X_train,y_train))
    print(lasso.score(X_test,y_test))
    print(np.sum(lasso.coef_!=0))#套索回归使用的特征数
    

    在这里插入图片描述

    lasso=Lasso(max_iter=100000)#增加最大迭代次数的默认设置,默认max_iter=1000
    lasso.fit(X_train,y_train)
    print(lasso.score(X_train,y_train))
    print(lasso.score(X_test,y_test))
    #特征选择
    print(np.sum(lasso.coef_!=0))
    

    在这里插入图片描述

    lasso=Lasso(alpha=0.1,max_iter=100000)
    #增加最大迭代次数的默认设置,默认max_iter=1000
    #回归调整alpha
    lasso.fit(X_train,y_train)
    print(lasso.score(X_train,y_train))
    print(lasso.score(X_test,y_test))
    #特征选择
    print(np.sum(lasso.coef_!=0))
    

    在这里插入图片描述

    lasso=Lasso(alpha=0.0001,max_iter=100000)
    #增加最大迭代次数的默认设置,默认max_iter=1000
    #回归调整alpha
    lasso.fit(X_train,y_train)
    print(lasso.score(X_train,y_train))
    print(lasso.score(X_test,y_test))
    #特征选择
    print(np.sum(lasso.coef_!=0))
    

    在这里插入图片描述

    plt.plot(ridge.coef_,'s',label='ridge alpha=1')
    plt.plot(ridge10.coef_,'^',label='ridge alpha=10')
    plt.plot(ridge.coef_,'v',label='ridge alpha=0.1')
    plt.plot(lr.coef_,'o',label='linear regression')
    
    plt.plot(lasso.coef_,'D',label='lasso alpha=1')
    plt.plot(lasso01,coef_,'H',label='lasso alpha=0.1')
    plt.plot(lasso00001,coef_,'p',label='lasso alpha=0.0001')
    plt.plot(ridge01,coef_,'<',label='ridge alpha=0.1')
    plt.xlabel('系数序号')
    plt.ylabel('系数量级')
    plt(hlines(0,0,len(lr.coef_)))
    plt.legend(loc='best')
    plt.grid(linestyle=':')
    

    在这里插入图片描述

    展开全文
  • Python:实现linear regression线性回归算法(附完整源码)
  • Previous graph-based semisupervised learning (G-SSL) methods have the following drawbacks: 1) they usually predefine the graph structure and then use it to perform label prediction, which cannot ...
  • 线性回归(Linear Regression)是一种非常简单、用处非常广泛、含义也非常容易理解的一类经典的算法,非常合适作为机器学习的入门算法。 线性回归就是拟合出一个线性组合关系的函数。要找一条直线,并且让这条直线...
  • sklearn-LinearRegression(线性回归)

    千次阅读 2022-04-07 20:57:12
    LinearRegression(线性回归) import numpy as np from sklearn.linear_model import LinearRegression #是二维数组所以用两个[],传入两个特征。 x=np.array([[150,70],[160,80],[170,90],[180,98]]) # y = 1 * x...
  • 64960-least-square-linear-regression.zip,linearregression.zip

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,938
精华内容 29,175
关键字:

linearregression