【火爐煉AI】機(jī)器學(xué)習(xí)009-用邏輯回歸分類器解決多分類問(wèn)題
(本文所使用的Python庫(kù)和版本號(hào): Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
前面的【火爐煉AI】機(jī)器學(xué)習(xí)008已經(jīng)講解了用簡(jiǎn)單線性分類器解決二分類問(wèn)題,但是對(duì)于多分類問(wèn)題,我們?cè)撛趺崔k了?
此處介紹一種用于解決多分類問(wèn)題的分類器:邏輯回歸。雖然名稱中含有回歸二字,但邏輯回歸不僅可以用來(lái)做回歸分析,也可以用來(lái)做分類問(wèn)題。邏輯回歸是機(jī)器學(xué)習(xí)領(lǐng)域比較常用的算法,用于估計(jì)樣本所屬類別的可能性,關(guān)于邏輯回歸的更深層次的公式推導(dǎo),可以參看https://blog.csdn.net/devotion987/article/details/78343834。
1. 準(zhǔn)備數(shù)據(jù)集
此處我們自己構(gòu)建了一些簡(jiǎn)單的數(shù)據(jù)樣本作為數(shù)據(jù)集,首先我們要分析該數(shù)據(jù)集,做到對(duì)數(shù)據(jù)集的特性了然如胸。
# 首先準(zhǔn)備數(shù)據(jù)集
# 特征向量
X =np.array([[4, 7], [3.5, 8], [3.1, 6.2], [0.5, 1], [1, 2],
[1.2, 1.9], [6, 2], [5.7, 1.5], [5.4, 2.2]]) # 自定義的數(shù)據(jù)集
# 標(biāo)記
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2]) # 三個(gè)類別
# 按照類別將數(shù)據(jù)點(diǎn)畫(huà)到散點(diǎn)圖中
class_0=np.array([feature for (feature,label) in zip(X,y) if label==0])
# print(class_0) # 確保沒(méi)有問(wèn)題
class_1=np.array([feature for (feature,label) in zip(X,y) if label==1])
# print(class_1)
class_2=np.array([feature for (feature,label) in zip(X,y) if label==2])
# print(class_2)
# 繪圖
plt.figure()
plt.scatter(class_0[:,0],class_0[:,1],marker='s',label='class_0')
plt.scatter(class_1[:,0],class_1[:,1],marker='x',label='class_1')
plt.scatter(class_2[:,0],class_2[:,1],marker='o',label='class_2')
plt.legend()

########################小**********結(jié)###############################
1,通過(guò)將數(shù)據(jù)集的y label可以看出,整個(gè)數(shù)據(jù)集有三個(gè)類別,每個(gè)類別的數(shù)據(jù)點(diǎn)都聚集到一塊,這個(gè)可以從散點(diǎn)圖中看出,故而此處是典型的多分類問(wèn)題。
2,此處數(shù)據(jù)集的樣本數(shù)比較少(每個(gè)類別三個(gè)樣本),且特征向量只有兩個(gè),并且從散點(diǎn)圖中可以看出,數(shù)據(jù)集各個(gè)類別都區(qū)分的比較開(kāi),故而相對(duì)比較容易分類。
#################################################################
2. 構(gòu)建邏輯回歸分類器
邏輯回歸分類器的構(gòu)建非常簡(jiǎn)單,如下代碼所示,首先我們用該分類器的默認(rèn)參數(shù)做一下分類試試。
# 構(gòu)建邏輯回歸分類器
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state=37) # 先用默認(rèn)的參數(shù)
classifier.fit(X, y) # 對(duì)國(guó)際回歸分類器進(jìn)行訓(xùn)練
雖然此處我們構(gòu)建了邏輯回歸分類器, 并且用我們的數(shù)據(jù)集進(jìn)行了訓(xùn)練,但訓(xùn)練的效果該怎么查看了?此時(shí)我們也沒(méi)有測(cè)試集,所以暫時(shí)的,我們將該分類器在訓(xùn)練集上的分類效果畫(huà)到圖中,給出一個(gè)直觀的分類效果。為了在圖中看到分類效果,需要定義一個(gè)專門繪制分類器效果展示的函數(shù),如下。
# 將分類器繪制到圖中
def plot_classifier(classifier, X, y):
x_min, x_max = min(X[:, 0]) - 1.0, max(X[:, 0]) + 1.0 # 計(jì)算圖中坐標(biāo)的范圍
y_min, y_max = min(X[:, 1]) - 1.0, max(X[:, 1]) + 1.0
step_size = 0.01 # 設(shè)置step size
x_values, y_values = np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step_size))
# 構(gòu)建網(wǎng)格數(shù)據(jù)
mesh_output = classifier.predict(np.c_[x_values.ravel(), y_values.ravel()])
mesh_output = mesh_output.reshape(x_values.shape)
plt.figure()
plt.pcolormesh(x_values, y_values, mesh_output, cmap=plt.cm.gray)
plt.scatter(X[:, 0], X[:, 1], c=y, s=80, edgecolors='black', linewidth=1, cmap=plt.cm.Paired)
# specify the boundaries of the figure
plt.xlim(x_values.min(), x_values.max())
plt.ylim(y_values.min(), y_values.max())
# specify the ticks on the X and Y axes
plt.xticks((np.arange(int(min(X[:, 0])-1), int(max(X[:, 0])+1), 1.0)))
plt.yticks((np.arange(int(min(X[:, 1])-1), int(max(X[:, 1])+1), 1.0)))
plt.show()
然后直接調(diào)用該繪圖函數(shù),查看該邏輯回歸分類器在訓(xùn)練集上的分類效果。
plot_classifier(classifier, X, y)

########################小**********結(jié)###############################
1,使用sklearn模塊中的LogisticRegression函數(shù)可以輕松的定義和訓(xùn)練一個(gè)邏輯回歸分類器模型。
2,由于此處采用分類器的默認(rèn)參數(shù),而不是最適合參數(shù),故而得到的分類效果并不是最佳,比如從圖中可以看出,雖然該分類模型能夠?qū)⑷齻€(gè)類別區(qū)分開(kāi)來(lái),但是其模型明顯還可以繼續(xù)優(yōu)化。
#################################################################
3. 對(duì)分類模型的優(yōu)化
邏輯回歸分類器有兩個(gè)最重要的參數(shù):solver和C,其中參數(shù)solver用于設(shè)置求解系統(tǒng)方程的算法類型,參數(shù)C表示對(duì)分類錯(cuò)誤的懲罰值,故而C越大,表明該模型對(duì)分類錯(cuò)誤的懲罰越大,即越不能接受分類發(fā)生錯(cuò)誤。
此處,作為拋磚引玉,可以優(yōu)化C值對(duì)分類效果的影響,如下,我們隨機(jī)選擇幾種C值,然后將分類結(jié)果圖畫(huà)出來(lái),憑借直觀感受來(lái)判斷哪一個(gè)比較好。當(dāng)然,更科學(xué)的做法是,使用測(cè)試集結(jié)合各種評(píng)估指標(biāo)來(lái)綜合評(píng)價(jià)那個(gè)參數(shù)組合下的模型最好。
# 優(yōu)化模型中的參數(shù)C
for c in [1,5,20,50,100,200,500]:
classifier = LogisticRegression(C=c,random_state=37)
classifier.fit(X, y)
plot_classifier(classifier, X, y)
# 貌似C越多,分類的效果越好。



########################小**********結(jié)###############################
1,對(duì)模型進(jìn)行優(yōu)化是一項(xiàng)體力活,也是最能考驗(yàn)機(jī)器學(xué)習(xí)技術(shù)功底的工作,此處作為拋磚引玉,我們僅僅優(yōu)化了邏輯回歸分類器的一個(gè)參數(shù)。
2,邏輯回歸分類器的C值越大,得到的分類器模型就越在兩個(gè)數(shù)據(jù)集中間區(qū)分開(kāi)來(lái),這也符合我們的預(yù)期,那么,是否有必要在一開(kāi)始時(shí)就設(shè)置非常大的C值?
#################################################################
注:本部分代碼已經(jīng)全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機(jī)器學(xué)習(xí)經(jīng)典實(shí)例,Prateek Joshi著,陶俊杰,陳小莉譯