參考資料:#>《Python 機器學習》
github地址:歡迎訪問
這里寫目錄標題
- 投票法的原理
- 集成模型好于單個分類器的原因
- 加權多數投票
- 硬投票
- 軟投票
- 投票法的使用條件
- 投票法案例
- 資料讀取
- 基分類器與集成投票器
- 分類結果(訓練集)
- 不同模型的auc_roc曲線(測驗集)
- 不同模型的分類邊界
投票法的原理
如上圖所示,在同一訓練集上,訓練得到多個分類或回歸模型,然后通過一個投票器,通過某種加權方式,輸出得票率最高的結果,
集成模型好于單個分類器的原因
假設:n個基分類器的出錯率都是 ? \epsilon ?,且相互獨立,則n個基分類器的結果中,出現k個錯誤的數量服從二項分布,對集成模型(簡單多數投票)來說,n個結果中,有K個錯誤的概率是:
當K>n/2時,集成模型輸出錯誤結果
假設 ? = 0.25 , n = 11 \epsilon=0.25,n=11 ?=0.25,n=11,輸出錯誤結果的概率為:
from scipy.special import comb #計算組合
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 替換sans-serif字體)
plt.rcParams['axes.unicode_minus'] = False # (解決坐標軸負數的負號顯示問題)
import math
def ensemble_error(n_classifier,epsilon):
k = math.ceil(n_classifier/2)#向上取整
probs = [comb(n_classifier,k) * epsilon ** k * (1-epsilon)**(n_classifier-k)
for k in range(k,n_classifier+1)]
return sum(probs)
base_error = np.arange(0.0,1.01,0.01)
en_error = [ensemble_error(11,base_e) for base_e in base_error]
plt.figure(figsize=(8,6))
plt.plot(base_error,en_error,label = '集成誤差')
plt.plot(base_error,base_error,linestyle = '--',label = '基礎分類器誤差')
plt.xlabel('基錯誤率',fontsize = 15)
plt.ylabel('集成錯誤率',fontsize = 15)
plt.grid()
plt.legend()
plt.show()

如圖片所示,只有當基分類器的錯誤率 ? < 0.5 \epsilon<0.5 ?<0.5時,多數投票的繼承分類器出錯率才會低于單個分類器
加權多數投票
硬投票
不同的基模型可能有不同的正確率,因此需要賦予不同的結果權重值
w j 表 示 分 類 器 C j 對 應 的 權 重 , y ^ 是 輸 出 類 標 , χ A 是 類 標 為 i 的 一 個 分 類 器 集 合 w_j表示分類器C_j對應的權重,\hat y是輸出類標,\chi_A是類標為i的一個分類器集合 wj?表示分類器Cj?對應的權重,y^?是輸出類標,χA?是類標為i的一個分類器集合
軟投票
p i j 是 第 j 個 分 類 器 預 測 為 i 的 概 率 p_{ij}是第j個分類器預測為i的概率 pij?是第j個分類器預測為i的概率
投票法的使用條件
- 基模型之間的效果不能差別過大,當某個基模型相對于其他基模型效果過差時,該模型很可能成為噪聲,
- **基模型之間應該有較小的同質性,**例如在基模型預測效果近似的情況下,基于樹模型與線性模型的投票,往往優于兩個樹模型或兩個線性模型,
投票法案例
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import VotingClassifier
from sklearn.pipeline import make_pipeline
資料讀取
iris = datasets.load_iris()
# 選擇兩種花型,兩個屬性
X,y = iris.data[50:,[1,2]],iris.target[50:]
np.unique(y)
array([1, 2])
le = LabelEncoder()
y = le.fit_transform(y)
np.unique(y)
array([0, 1], dtype=int64)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.5,random_state = 1)
基分類器與集成投票器
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
clf_lr = LogisticRegression(penalty='l2',C=1000,random_state=0)
clf_dt = DecisionTreeClassifier(random_state=0)
clf_knn = KNeighborsClassifier(n_neighbors=1,p=2)
pipe1 = make_pipeline(StandardScaler(),clf_lr)
pipe2 = make_pipeline(StandardScaler(),clf_dt)
pipe3 = make_pipeline(StandardScaler(),clf_knn)
models = [('lr',pipe1),
('dt',pipe2),
('KNN',pipe3)]
ensembel = VotingClassifier(estimators=models,voting='soft')
分類結果(訓練集)
from sklearn.model_selection import cross_val_score
all_model = [pipe1,pipe2,pipe3,ensembel]
clf_labels = ['LogisticRegression','DecisionTreeClassifier','KNeighborsClassifier','Ensemble']
for clf,label in zip(all_model,clf_labels):
score = cross_val_score(estimator=clf,
X = X_train,
y=y_train,
cv = 10,
scoring = 'roc_auc')
print( 'roc_auc: %0.2f (+/- %0.2f) [%s]' % (score.mean(),score.std(),label))
roc_auc: 0.98 (+/- 0.05) [LogisticRegression]
roc_auc: 0.93 (+/- 0.11) [DecisionTreeClassifier]
roc_auc: 0.93 (+/- 0.15) [KNeighborsClassifier]
roc_auc: 0.98 (+/- 0.05) [Ensemble]
不同模型的auc_roc曲線(測驗集)
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
colors = ['black','orange','blue', 'green']
linestyles = [':','--','-.','-']
plt.figure(figsize=(10,8))
for clf, label, clr, ls in zip (all_model, clf_labels, colors, linestyles):
# assuming the label of the positive class is 1
y_pred = clf.fit(X_train, y_train).predict_proba(X_test)[:,1]
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=y_pred)
roc_auc = auc(x=fpr, y=tpr)
plt.plot (fpr, tpr, color=clr, linestyle=ls, label='%s (auc = %0.3f)'%(label, roc_auc) )
plt.legend (loc='lower right')
plt.plot ([0,1], [0, 1],linestyle='--',color='gray',linewidth=2)
plt.xlim ([-0.1, 1.1])
plt.ylim([-0.1, 1.1])
plt.grid()
plt.xlabel ('False Positive Rate')
plt.ylabel ('True Positive Rate')
plt.show()

不同模型的分類邊界
sc = StandardScaler()
X_train_std =sc.fit_transform(X_train)
from itertools import product
x_min =X_train_std[:,0].min()-1
x_max =X_train_std[:,0].max() + 1
y_min =X_train_std[:,1].min()-1
y_max =X_train_std[:,1].max() + 1
xx, yy =np.meshgrid(np.arange(x_min, x_max, 0.1),np.arange(y_min, y_max, 0.1))
f, axarr = plt.subplots (nrows=2, ncols=2,
sharex='col',
sharey='row',
figsize=(7, 5) )
for idx, clf, tt in zip(product([0, 1], [0, 1]), all_model, clf_labels):
clf.fit(X_train_std, y_train)
z= clf.predict(np.c_[xx.ravel(),yy.ravel()])
z= z.reshape(xx.shape)
axarr[idx[0],idx[1]].contourf(xx, yy, z, alpha=0.3)
axarr[idx[0],idx[1]].scatter(X_train_std[y_train==0,0],
X_train_std[y_train==0,1]
, c='blue',
marker='^'
,s=50)
axarr[idx[0],idx[1]].scatter(X_train_std[y_train==1,0],
X_train_std[y_train==1,1]
, c='red',
marker='o'
,s=50)
axarr[idx[0],idx[1]].set_title(tt)
plt.show()

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/275797.html
標籤:python
下一篇:Python簡潔優雅的推導式
