线性模型

基本概念

  • 训练集、验证集、测试集(交叉验证、自助法等)
  • 目标函数
  • 损失函数
  • 优化方法(梯度下降法等)
  • 拟合、过拟合
  • 准确率、泛化性能

模型训练

不可能有一个理想的线性函数经过所有训练集的数据点,把“偏移”看做误差,假设误差符合高斯分布。

求解方法有:

  • 直接采用极值方法求解
  • 梯度下降法求解
    polynomial 方法可以对样本是非线性的,对系数是线性的。
    image.png

正则化技术

image.png
  • LASSO具有稀疏作用
  • Ridge收敛更快

目标函数仍然是不带正则化的原函数,经过改造的上式称为损失函数,优化目标就是使损失函数最小

模型评价

  • 连续数据(回归问题),一般使用方差评估
  • 离散数据(分类问题),一般使用 ** accuracy、precision/recall**

线性回归模型有很多,区别在于如何从训练数据中学习参数 w 和 b,以及如何控制模型复杂程度。

1、普通最小二乘法

线性回归寻找参数 w 和 b,使得对训练集的预测值与真实的回归目标值 y 之间的均方误差最小。(模型可能存在欠拟合和过拟合)


线性模型预测结果.png

2、岭回归

岭回归中,对系数(w)的选则不仅要在训练数据上得到好的预测结果,而且还要拟合附加约束希望系数尽量的小。即 L2 正则化。

alpha 的设置

复杂度更小的模型意味着在训练集上的性能更差,但泛化性能更好。Ridge 模型在模型的简单性(系数都接近 0)与训练集性能之间做出权衡。简单性和训练集性能二者对于模型的重要程度可以由用户通过设置 alpha 参数来指定。增大 alpha 会使得系数更加趋近于 0 ,从而降低训练集性能,但可能会提高泛化性能。

不同 alpha 值的岭回归与线性回归的系数比较.png

大 alpha 对应的 coef_ 元素比小 alpha 对应的 coef_ 元素要小。

训练数据量的影响

如果足够多的训练数据,正则化变得不那么重要。如果添加更多的数据,模型将更加难以过拟合或记住所有的数据

训练数据量对正则化的影响.png

3、lasso

L1 正则化的结果是:使用 lasso 某些系数刚好为 0,可以看作是一种自动化的特征选择。
alpha 可以控制系数趋向于 0 的强度,默认为 1.0 。

不同 alpha 回归系数比较.png

实践中,两个模型一般首选岭回归。但如果特征很多,你认为只有其中几个是重要的,那么选择 Lasso 可能更好。
scikit-learn 提供了 ElasticNet 类,结合了 Lasso 和 Ridge 的惩罚项。在实践过程中,这种结合的效果最好,不过代价是要调节两个参数:一个用于 L1 正则化,一个用于 L2 正则化。

4、用于分类的线性模型

  • Logistic 回归
  • 线性支持向量机(线性 SVM)
    两个模型都默认使用 L2 正则化,决定正则化强度的权衡参数是 C,C 值越大,对应的正则化越弱。
线性 SVM 和 Logistic 回归.png

较小的 C 值可以让算法尽量适应“大多数”数据点,而较大的 C 值更强调每个数据点都分类正确的重要性。


不同 C 值的线性 SVM .png

5、用于多分类的线性模型

将二分类算法推广到多分类算法的一种常见方法“一对多余”方法。对每个类别都学习一个二分类模型,将这个类别与所有其他类别尽量分开。
每个类别都对应一个二类分类器。

包含 3 个类别的二维玩具数据集.png

图像中间的三角形区域属于哪一个类别呢?答案是分类方程结果最大的那个类别,即最接近的那条线对应的类别。
三个“一对多余”分类器学到的决策边界.png

6、代码

import mglearn
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
from sklearn.datasets import load_breast_cancer
from sklearn.datasets import make_blobs

# 最小二乘法
def ols_test(X_train, X_test, y_train, y_test):

    mglearn.plots.plot_linear_regression_wave()
    plt.show()

    lr=LinearRegression()
    lr.fit(X_train,y_train)
    print('lr.coef_:{}'.format(lr.coef_))
    print('lr.intercept_:{}'.format(lr.intercept_))
    # 模型欠拟合
    print('Training set score:{:.2f}'.format(lr.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(lr.score(X_test,y_test)))
    X,y=mglearn.datasets.load_extended_boston()
    X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)
    lr=LinearRegression()
    lr.fit(X_train,y_train)
    # 过拟合
    print('Training set score:{:.2f}'.format(lr.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(lr.score(X_test,y_test)))

def ridge_test():

    X, y = mglearn.datasets.load_extended_boston()
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    lr = LinearRegression()
    lr.fit(X_train, y_train)
    # 过拟合
    print('Training set score:{:.2f}'.format(lr.score(X_train, y_train)))
    print('Test set score:{:.2f}'.format(lr.score(X_test, y_test)))

    # 岭回归模型
    ridge=Ridge()
    ridge.fit(X_train,y_train)
    print('Training set score:{:.2f}'.format(ridge.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(ridge.score(X_test,y_test)))

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

    ridge01=Ridge(alpha=0.1)
    ridge01.fit(X_train,y_train)
    print('Training set score:{:.2f}'.format(ridge01.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(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_,'v',label='Ridege alpha=0.1')

    plt.plot(lr.coef_,'o',label='LinearRegression')
    plt.xlabel('Coefficient index')
    plt.hlines(0,0,len(lr.coef_))
    plt.ylim(-25,25)
    plt.legend()
    plt.show()
    # 训练数据量对正则化的影响
    mglearn.plots.plot_ridge_n_samples()
    plt.show()

# lasso
def lasso_test():

    X, y = mglearn.datasets.load_extended_boston()
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    # 欠拟合
    lasso=Lasso()
    lasso.fit(X_train,y_train)
    print('Training set score:{:.2f}'.format(lasso.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(lasso.score(X_test,y_test)))
    print('Number of features used :{}'.format(np.sum(lasso.coef_!=0)))

    lasso001=Lasso(alpha=0.01,max_iter=100000)
    lasso001.fit(X_train,y_train)
    print('Training set score:{:.2f}'.format(lasso001.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(lasso001.score(X_test,y_test)))
    print('Number of features used :{}'.format(np.sum(lasso001.coef_!=0)))

    # 过拟合
    lasso00001=Lasso(alpha=0.0001,max_iter=100000)
    lasso00001.fit(X_train,y_train)
    print('Training set score:{:.2f}'.format(lasso00001.score(X_train,y_train)))
    print('Test set score:{:.2f}'.format(lasso00001.score(X_test,y_test)))
    print('Number of features used :{}'.format(np.sum(lasso00001.coef_!=0)))

    plt.plot(lasso.coef_,'s',label='Lasso alpha=1')
    plt.plot(lasso001.coef_,'^',label='Lasso alpha=0.01')
    plt.plot(lasso00001.coef_,'v',label='Lasso alpha=0.0001')

    ridge01 = Ridge(alpha=0.1)
    ridge01.fit(X_train, y_train)
    plt.plot(ridge01.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')

    plt.show()

# 分类
def class_test():

    X,y=mglearn.datasets.make_forge()
    fig,axes=plt.subplots(1,2,figsize=(10,3))

    for model,ax in zip([LinearSVC(),LogisticRegression()],axes):
        clf=model.fit(X,y)
        mglearn.plots.plot_2d_separator(clf,X,fill=False,eps=0.5,ax=ax,alpha=0.7)
        mglearn.discrete_scatter(X[:,0],X[:,1],y,ax=ax)
        ax.set_title('{}'.format(clf.__class__.__name__))
        ax.set_xlabel('Feature 0')
        ax.set_ylabel('Feature 1')
    axes[0].legend()
    mglearn.plots.plot_linear_svc_regularization()
    plt.show()

def logistic_test():

    cancer=load_breast_cancer()
    X_train,X_test,y_train,y_test=train_test_split(cancer.data,cancer.target,stratify=cancer.target,random_state=42)
    logreg=LogisticRegression()
    logreg.fit(X_train,y_train)
    print('Traning set score:{:.3f}'.format(logreg.score(X_train,y_train)))
    print('Test set score:{:.3f}'.format(logreg.score(X_test,y_test)))

    logreg100=LogisticRegression(C=100)
    logreg100.fit(X_train,y_train)
    print('Traning set score:{:.3f}'.format(logreg100.score(X_train,y_train)))
    print('Test set score:{:.3f}'.format(logreg100.score(X_test,y_test)))


    logreg001=LogisticRegression(C=0.01)
    logreg001.fit(X_train,y_train)
    print('Traning set score:{:.3f}'.format(logreg001.score(X_train,y_train)))
    print('Test set score:{:.3f}'.format(logreg001.score(X_test,y_test)))

    plt.plot(logreg.coef_.T,'s',label='C=1')
    plt.plot(logreg100.coef_.T,'^',label='C=100')
    plt.plot(logreg001.coef_.T,'v',label='C=0.001')
    plt.xticks(range(cancer.data.shape[1]),cancer.feature_names,rotation=90)
    plt.hlines(0,0,cancer.data.shape[1])
    plt.ylim(-5,5)

    plt.xlabel('Coefficient index')
    plt.ylabel('Coefficient magnitude')
    plt.legend()
    plt.show()

    for C,marker in zip([0.001,1,100],['o','^','v']):
        lr_l1=LogisticRegression(penalty='l1',C=C).fit(X_train,y_train)
        print('Training accuracy of l1 logreg with C={:.3f}:{:.2f}'.format(C,lr_l1.score(X_train,y_train)))
        print('Test accuracy of l1 logreg with C={:.3f}:{:.2f}'.format(C, lr_l1.score(X_test, y_test)))

    plt.plot(lr_l1.coef_.T,marker,label='C={:.3f}'.format(C))
    plt.xticks(range(cancer.data.shape[1]),cancer.feature_names,rotation=90)
    plt.hlines(0,0,cancer.data.shape[1])
    plt.ylim(-5,5)

    plt.xlabel('Coefficient index')
    plt.ylabel('Coefficient magnitude')
    plt.legend(loc=3)
    plt.show()

def multi_classification():
    X,y=make_blobs(random_state=42)
    mglearn.discrete_scatter(X[:,0],X[:,1],y)
    plt.xlabel('Feature 0')
    plt.ylabel('Feature 1')
    plt.legend(['class 0','class 1','class 2',])
    plt.show()
    plt.clf()
    linear_svm=LinearSVC().fit(X,y)
    print('Coefficient shape:',linear_svm.coef_.shape)
    print('Intercept shape:',linear_svm.intercept_.shape)
    mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
    line=np.linspace(-15,15)
    for coef,intercept,color in zip(linear_svm.coef_,linear_svm.intercept_,['b','r','g']):
        plt.plot(line,-(line*coef[0]+intercept)/coef[1],c=color)
    plt.ylim(-10,15)
    plt.xlim(-10,8)
    plt.xlabel('Feature 0')
    plt.ylabel('Feature 1')
    plt.legend(['Class 0','Class 1','Class 2','Line class 0','Line class 1','Line class 2'],loc=(1.01,0.3))
    plt.show()
if __name__=='__main__':
    # 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)
    # ols_test(X_train, X_test, y_train, y_test)
    # ridge_test()
    # lasso_test()
    # class_test()
    # logistic_test()
    multi_classification()
```p
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容