美文网首页程序员
线性回归模型

线性回归模型

作者: 脚印无痕 | 来源:发表于2019-05-08 22:29 被阅读9次

    1. 线性回归

    线性回归又名普通二成最小法(ordinary least squares, OLS),是回归问题最简单也是最经典的线性方法。线性回归寻找参数wb,使得对训练集的预测值与真实的回归目标值y之间的均方误差最小。线性回归没有参数,这是一个优点,但也因此无法控制模型的复杂度。
    线性回归的用法与近邻算法相似,如下:

    import numpy as np
    import pandas as pd
    import mglearn
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    # 线性回归在sklearn的linear_model模块的LinearRegression类中实现
    from sklearn.linear_model import LinearRegression
    # 生成数据
    X, y = mglearn.datasets.make_wave(n_samples=60)
    # 拆分数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
    # 实例化LinearRegression对象并用fit函数训练集数据进行模型拟合
    lr = LinearRegression().fit(X_train, y_train)
    # 调用LinearRegression对象的predict函数对测试集进行预测
    print("Test set predictions:\n{}".format(lr.predict(X_test)))
    # 调用LinearRegression对象的score函数对模型性能进行评估
    print("Test set acurracy:{:.2f}".format(lr.score(X_test, y_test)))
    print("Train set acurracy:{:.2f}".format(lr.score(X_train, y_train)))
    

    Test set predictions:
    [-0.3283204 -0.84483835 -0.49358667 0.35230624 -0.71167167 0.19957573
    1.02910669 0.07859229 0.75390167 -0.75032857 -0.47681266 1.07802761
    -0.8104986 0.2013684 1.00692209]
    Test set acurracy:0.66
    Train set acurracy:0.67
    训练集和测试集上的分数非常相近,且不是太好,说明可能存在欠拟合。

    斜率参数w也叫权重系数被保存在LinearRegression对象的coef_属性中,偏移截距(b)被保存在intercept_属性中:

    print("lr.coef_:{}".format(lr.coef_))
    print("lr.intercept_:{}".format(lr.intercept_))
    

    lr.coef_:[0.39390555]
    lr.intercept_:-0.031804343026759746

    注意使用的wave数据是一维数据集,模型的性能不是很好,对于更高维的数据集,线性模型将变动更加强大。
    下面使用更复杂的数据集boston房价,数据集有506个样本和105特征,验证线性回归在高维数据集上的表现:

    # 加载数据集
    X, y = mglearn.datasets.load_extended_boston()
    # 拆分数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    # 实例化LinearRegression对象并用fit函数训练集数据进行模型拟合
    lr = LinearRegression().fit(X_train, y_train)
    # 调用LinearRegression对象的score函数对模型性能进行评估
    print("Train set acurracy:{:.2f}".format(lr.score(X_train, y_train)))
    print("Test set acurracy:{:.2f}".format(lr.score(X_test, y_test)))
    

    Train set acurracy:0.95
    Test set acurracy:0.61
    线性回归在高维数据集上的表象明显好于一维数据集,但在训练集和测试集上的得分差异较大,是过拟合的明显标志。

    2. 岭回归

    岭回归也是一种用于回归的线性模型。在岭回归模型中,对系数(w)的选择不仅要在训练集上得到较好的效果,而且还要拟合附加约束,使得w尽量小,及w的所有元素都要接近于0。这种约束即是正则化。正则化是指对模型进行显示约束,以避免过拟合。岭回归用到的这种被称为L2正则化。

    岭回归在sklearnlinear_modelRidge类中实现。下面是岭回归在boston房价数据集上的效果。

    import numpy as np
    import pandas as pd
    import mglearn
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    # 线性回归在sklearn的linear_model模块的Ridge类中实现
    from sklearn.linear_model import Ridge
    # 加载数据
    X, y = mglearn.datasets.load_extended_boston()
    # 拆分数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    # 实例化Ridge对象并用fit函数训练集数据进行模型拟合
    rg = Ridge().fit(X_train, y_train)
    # 调用Ridge对象的score函数对模型性能进行评估
    print("Train set acurracy:{:.2f}".format(rg.score(X_train, y_train)))
    print("Test set acurracy:{:.2f}".format(rg .score(X_test, y_test)))
    

    Training set scroe:0.89
    Test set score:0.75
    Ridge在训练集上的得分低于LinearRegression,但在测试集上的得分要高。

    Ridge模型在模型的简单性(w接近0)与训练集性能之间做权衡。模型的简单性和训练集性能的权衡可通过设置参数alpha来指定。alpha的最佳值取决于具体的数据集。增大alpha的值会使得w更加趋向0,即模型更简单,从而降低训练集性能,但可能提高泛化性能。**

    rg10 = Ridge(alpha=10).fit(X_train, y_train)
    print("Training set scroe:{:.2f}".format(rg10.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(rg10.score(X_test, y_test)))
    

    Training set scroe:0.79
    Test set score:0.64

    减小alpha可以让w收到的限制更小,对于非常小的alphaw几乎没有收到限制,会得到一个与LinearRegression类似的模型。

    rg01 = Ridge(alpha=0.1).fit(X_train, y_train)
    print("Training set scroe:{:.2f}".format(rg01.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(rg01.score(X_test, y_test)))
    

    Training set scroe:0.93
    Test set score:0.77

    下面查看不同alpha取值对模型coef_属性的影响,观察alpha参数是如何影响模型。

    plt.plot(rg.coef_, 's', label="Ridge alpha=1")
    plt.plot(rg10.coef_, '^', label="Ridge alpha=10")
    plt.plot(rg01.coef_, 'v', label="Ridge alpha=0.1")
    
    plt.plot(lr.coef_, 'o', label="LinearRegression")
    plt.xlabel("Cofficient index")
    plt.ylabel("Cofficient magnitude")
    plt.hlines(0, 0, len(lr.coef_))
    plt.ylim(-25, 25)
    plt.legend()
    
    alpha对w的影响
    从上图中可以看出alpha越大,w的范围越集中且趋于0。

    另外一种理解正则化的影响,就是固定alpha的值,但是改变训练数据量。

    mglearn.plots.plot_ridge_n_samples()
    
    学习曲线

    无论是岭回归还是线性回归,训练分数都要高于测试分数。由于岭回归是正则化的,因此它的训练分数低于线性回归,但是测试分数要高于线性回归。尤其是较小的数据集时,从上图可看出数据点少于400时,线性回归学习不到任何内容。随着模型可用数据的增多,两个模型的性能都在提升,最终线性回归的性能会追上岭回归。即在有足够的的训练数据的情况下,正则化变得不那么重要。

    3. lasso

    lasso也是一种正则化的线性回归模型,与Ridge的不同之处在于它使用的是L1正则化,结果是使某些系数刚好为0。这说明某些特征被模型完全忽略,可看作是一种自动化的特征选择。

    import numpy as np
    import pandas as pd
    import mglearn
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    # lasso 在sklearn的linear_model模块的Lasso类中实现
    from sklearn.linear_model import Lasso
    # 加载boston房价数据
    X, y = mglearn.datasets.load_extended_boston()
    # 拆分数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    # 实例化Lasso对象并用测试集数据拟合模型
    la = Lasso().fit(X_train, y_train)
    # 调用Lasso对象的score函数进行模型评估
    print("Training set score:{:.2f}".format(la.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(la.score(X_test, y_test)))
    # 统计模型使用的特征数,及Lasso对象coef_属性不为0的
    print("Number of features used:{}".format(np.sum(la.coef_!=0)))
    

    Training set score:0.29
    Test set score:0.21
    Number of features used:4

    如上lasso在训练集和测试集上的得分都很低,标识存在欠拟合,模型只用到了105个特征中的4个。与Ridge相似,lasso也有alpha参数可以控制系数趋向0的强度。上面的代码中alpha参数使用默认值1.0。下面尝试减小alpha,降低欠拟合,从而得到一个更复杂的模型。减小alpha的同时需要增大max_iter(运行迭代的最大次数)的值:

    # 实例化Lasso对象并用测试集数据拟合模型
    la001 = Lasso(alpha=0.01, max_iter=10000).fit(X_train, y_train)
    # 调用Lasso对象的score函数进行模型评估
    print("Training set score:{:.2f}".format(la001.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(la001.score(X_test, y_test)))
    # 统计模型使用的特征数,及Lasso对象coef_属性不为0的
    print("Number of features used:{}".format(np.sum(la001.coef_!=0)))
    

    Training set score:0.90
    Test set score:0.77
    Number of features used:33
    alpha值变小后,lasso在训练集和测试集上的得分都明显提高。但是如果把alpha设置太小,就会消化正则化的效果,并出现过拟合,得到于LinearRegression类似的结果:

    # 实例化Lasso对象并用测试集数据拟合模型
    la00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)
    # 调用Lasso对象的score函数进行模型评估
    print("Training set score:{:.2f}".format(la00001.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(la00001.score(X_test, y_test)))
    # 统计模型使用的特征数,及Lasso对象coef_属性不为0的
    print("Number of features used:{}".format(np.sum(la00001.coef_!=0)))
    

    Training set score:0.95
    Test set score:0.64
    Number of features used:94

    from sklearn.linear_model import Ridge
    rg01 = Ridge(alpha = 0.1).fit(X_train, y_train)
    print("Training set score:{:.2f}".format(rg01.score(X_train, y_train)))
    print("Test set score:{:.2f}".format(rg01.score(X_test, y_test)))
    

    Training set score:0.93
    Test set score:0.77

    下面作图观察不同alpha值对模型系数的影响情况:

    plt.plot(la.coef_, 's', label="lasso alpha=1")
    plt.plot(la001.coef_, '^', label="lasso alpha=0.01")
    plt.plot(la00001.coef_, 'v', label="lasso alpha=0.0001")
    plt.plot(rg01.coef_, 'o', label="ridge alpha=0.1")
    plt.legend(ncol=2, loc=(0, 1.05))
    plt.ylim(-25, 25)
    plt.xlabel("Coefficient index")
    plt.ylabel("Coefficient magnitude")
    
    image.png

    lasso alpha=1 系数基本都为0,只有几个不为0且范围较小
    lasso alpha=0.01系数大部分都为0,范围增大
    lasso alpha=0.0001系数很小一部分为0,范围更大
    ridge alpha=0.1所有系数均不为0

    相关文章

      网友评论

        本文标题:线性回归模型

        本文链接:https://www.haomeiwen.com/subject/wkqboqtx.html