Python機(jī)器學(xué)習(xí)基礎(chǔ)教程學(xué)習(xí)筆記(6)——線性模型(分類)
1. 二分類
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
# 不想看到warnings
import warnings
warnings.filterwarnings("ignore", category=Warning)
# 拆分訓(xùn)練集與測試集
from sklearn.model_selection import train_test_split
# 使用兩個分類算法:LogisticRegression和LinearSVC
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
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=.7)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
ax.set_title(clf.__class__.__name__)
ax.set_xlabel("Feature 0")
ax.set_ylabel("Feature 1")
ax.legend()
output_3_0.png
- LinearSVC和LogisticRegression兩個模型默認(rèn)都使用L2正則化
- 決定正則化強(qiáng)度的權(quán)衡參數(shù)叫做C。
- C值越大粘昨,對應(yīng)的正則化越弱。
- C值較大微峰,模型將盡可能將訓(xùn)練集擬合到最好
- C值較小,模型更強(qiáng)調(diào)使用系統(tǒng)向量接近于0
mglearn.plots.plot_linear_svc_regularization()
output_5_0.png
from sklearn.datasets import load_breast_cancer
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().fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg.score(X_test, y_test)))
Training set score: 0.953
Test set score: 0.958
- C=1的默認(rèn)值給出了相當(dāng)好的性能蕴忆,都是95%的精度屯远。
- 訓(xùn)練集和測試集的性能非常接近,所以很可能是欠擬合惕耕。
- 嘗試增大C來擬合一個更靈活的模型
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg100.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg100.score(X_test, y_test)))
Training set score: 0.972
Test set score: 0.965
- 當(dāng)減小C值時,正則化更強(qiáng)诫肠,訓(xùn)練集和測試集精度都變小
logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg001.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg001.score(X_test, y_test)))
Training set score: 0.934
Test set score: 0.930
plt.plot(logreg.coef_.T,'o',label="C=1")
plt.plot(logreg100.coef_.T,'^',label="C=100")
plt.plot(logreg001.coef_.T,'v',label="C=0.01")
# 給橫坐標(biāo)賦值
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("coeffient magnitude")
plt.legend()
plt.show()
output_11_0.png
- LogisticRegression使用的是L2正則化
- 更強(qiáng)的正則化使用得系統(tǒng)趨向于0司澎,但是系統(tǒng)永遠(yuǎn)不會正好等于0
- 對線性模型系統(tǒng)的解釋應(yīng)該始終持保留態(tài)度
- 如果想要解釋性更強(qiáng)的模型,使用L1正則化可能更好栋豫,因?yàn)樗s束模型只使用少數(shù)的幾個特征
for C,marker in zip([0.001,1,100],['o','^','v']):
# 這里把penalty參數(shù)設(shè)置為l1挤安,表示使用L1正則化
lr_l1= LogisticRegression(C=C,penalty="l1").fit(X_train,y_train)
print("C={:.3f}".format(C))
print("Training set score : {:.3f}".format(lr_l1.score(X_train, y_train)))
print("Test set score : {:.3f}".format(lr_l1.score(X_test, y_test)))
print("---------------------------------------")
plt.plot(lr_l1.coef_.T,marker,label="C={:.3f}".format(C))
# 給橫坐標(biāo)賦值
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("coeffient magnitude")
plt.legend()
plt.show()
C=0.001
Training set score : 0.913
Test set score : 0.923
---------------------------------------
C=1.000
Training set score : 0.960
Test set score : 0.958
---------------------------------------
C=100.000
Training set score : 0.986
Test set score : 0.979
---------------------------------------
output_13_1.png
- 模型的主要差別在于penalty參數(shù),這個參數(shù)會影響正則化丧鸯,也會影響模型是使用所有可用特征還是只選擇特征的一個子集
2. 多分類
將二分類算法推廣到多分類算法的一種常見方法是“一對其余”(one-vs.-rest)
from sklearn.datasets import make_blobs
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()
output_17_0.png
linear_svm = LinearSVC().fit(X,y)
# coef_的形狀是(3,2),說明coef_每行包含三個類別之一的系統(tǒng)微量每列包含某個特征(這個數(shù)據(jù)集有2個特征)對應(yīng)的系數(shù)值蛤铜。
print("Coefficient shape:{}".format(linear_svm.coef_.shape))
# intercept_的形狀是(3,),是一維數(shù)組丛肢,保存每個類別的截距
print("Intercept shape:{}".format(linear_svm.intercept_.shape))
Coefficient shape:(3, 2)
Intercept shape:(3,)
mglearn.discrete_scatter(X[:,0],X[:,1],y)
line = np.linspace(-15,15)
# -(line*coef[0]+ intercept)/coef[1] 這個值可以簡單理解一下
for coef,intercept,color in zip(linear_svm.coef_,linear_svm.intercept_,['b','r','g']):
plt.plot(line,-(line*coef[0]+ intercept)/coef[1],color)
plt.xlim(-10,8)
plt.ylim(-10,15)
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()
output_19_0.png
- 從圖中可以看出這種“一對其余”(one-vs.-rest)的樣子
- 但是圖中間的三角形區(qū)域?qū)儆谀囊粋€類別呢围肥,3個二類分類器都將這一區(qū)域內(nèi)的點(diǎn)劃分為“其余”
- 答案是,分類方程結(jié)果最大的那個類別蜂怎,即最接近的那條線對應(yīng)的類別穆刻。
mglearn.plots.plot_2d_classification(linear_svm,X,fill=True,alpha=.3)
mglearn.discrete_scatter(X[:,0],X[:,1],y)
line = np.linspace(-15,15)
# -(line*coef[0]+ intercept)/coef[1] 這個值可以簡單理解一下
for coef,intercept,color in zip(linear_svm.coef_,linear_svm.intercept_,['b','r','g']):
plt.plot(line,-(line*coef[0]+ intercept)/coef[1],color)
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()
output_21_0.png
3 優(yōu)點(diǎn)、缺點(diǎn)和參數(shù)
- 線性模型的主要參數(shù)是正則化參數(shù)
- 回歸模型中叫alpha
- 分類模型中叫C
- alpha值較大或C值較小杠步,說明模型比較簡單
- 還需要確定使用L1正則化還是L2正則化
- 如果假定只有幾個特征是真正重要的氢伟,那么使用L1正則化,否則默認(rèn)使用L2正則化
- 如果模型的可解釋性很重要幽歼,使用L1會有幫助
- 線性模型的訓(xùn)練速度非扯渎啵快,預(yù)測速度也很快试躏。
- 可推廣到非常大的數(shù)據(jù)集
- 稀疏數(shù)據(jù)也很有效
- 如果數(shù)據(jù)包含數(shù)十萬甚至上百萬個樣本猪勇,需要研究如何使用LogisticRegression和Ridge模型的solver='sag'選項(xiàng)设褐,在處理大數(shù)據(jù)時颠蕴,這一選項(xiàng)比默認(rèn)值更快
- 其他選項(xiàng)還有SGDClassifier類和SDGRegressor類泣刹,對本節(jié)介紹的線性模型實(shí)現(xiàn)了可擴(kuò)展性更強(qiáng)的版本。
- 如果特征數(shù)量大于樣本數(shù)量犀被,線性模型表現(xiàn)通常都很好椅您。
- 常用于非常大的數(shù)據(jù)集,只是因?yàn)橛?xùn)練其他模型并不可行寡键。
- 在更低維的空間中掀泳,其他模型的泛化性能可能更好