基本概念
- 训练集、验证集、测试集(交叉验证、自助法等)
- 目标函数
- 损失函数
- 优化方法(梯度下降法等)
- 拟合、过拟合
- 准确率、泛化性能
模型训练
不可能有一个理想的线性函数经过所有训练集的数据点,把“偏移”看做误差,假设误差符合高斯分布。
求解方法有:
- 直接采用极值方法求解
- 梯度下降法求解
polynomial 方法可以对样本是非线性的,对系数是线性的。
image.png
正则化技术

- LASSO具有稀疏作用
- Ridge收敛更快
目标函数仍然是不带正则化的原函数,经过改造的上式称为损失函数,优化目标就是使损失函数最小
模型评价
- 连续数据(回归问题),一般使用方差评估
- 离散数据(分类问题),一般使用 ** accuracy、precision/recall**
线性回归模型有很多,区别在于如何从训练数据中学习参数 w 和 b,以及如何控制模型复杂程度。
1、普通最小二乘法
线性回归寻找参数 w 和 b,使得对训练集的预测值与真实的回归目标值 y 之间的均方误差最小。(模型可能存在欠拟合和过拟合)

2、岭回归
岭回归中,对系数(w)的选则不仅要在训练数据上得到好的预测结果,而且还要拟合附加约束。希望系数尽量的小。即 L2 正则化。
alpha 的设置
复杂度更小的模型意味着在训练集上的性能更差,但泛化性能更好。Ridge 模型在模型的简单性(系数都接近 0)与训练集性能之间做出权衡。简单性和训练集性能二者对于模型的重要程度可以由用户通过设置 alpha 参数来指定。增大 alpha 会使得系数更加趋近于 0 ,从而降低训练集性能,但可能会提高泛化性能。

大 alpha 对应的 coef_ 元素比小 alpha 对应的 coef_ 元素要小。
训练数据量的影响
如果足够多的训练数据,正则化变得不那么重要。如果添加更多的数据,模型将更加难以过拟合或记住所有的数据

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

实践中,两个模型一般首选岭回归。但如果特征很多,你认为只有其中几个是重要的,那么选择 Lasso 可能更好。
scikit-learn 提供了 ElasticNet 类,结合了 Lasso 和 Ridge 的惩罚项。在实践过程中,这种结合的效果最好,不过代价是要调节两个参数:一个用于 L1 正则化,一个用于 L2 正则化。
4、用于分类的线性模型
- Logistic 回归
- 线性支持向量机(线性 SVM)
两个模型都默认使用 L2 正则化,决定正则化强度的权衡参数是 C,C 值越大,对应的正则化越弱。

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

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

图像中间的三角形区域属于哪一个类别呢?答案是分类方程结果最大的那个类别,即最接近的那条线对应的类别。

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
