Python實現鳶尾花數據集分類問題——基於skearn的LogisticRegression
一. 邏輯回歸
邏輯回歸(Logistic Regression)是用於處理因變量為分類變量的回歸問題,常見的是二分類或二項分布問題,也可以處理多分類問題,它實際上是屬於一種分類方法。
概率p與因變量往往是非線性的,為了解決該類問題,我們引入了logit變換,使得logit(p)與自變量之 間存在線性相關的關系,邏輯回歸模型定義如下:
1 #Sigmoid曲線: 2 import matplotlib.pyplot as plt 3 import numpy as np 4 5 def Sigmoid(x): 6 return 1.0 / (1.0 + np.exp(-x)) 7 8 x= np.arange(-10, 10, 0.1) 9 h = Sigmoid(x) #Sigmoid函數 10 plt.plot(x, h) 11 plt.axvline(0.0, color='k') #坐標軸上加一條豎直的線(0位置) 12 plt.axhspan(0.0, 1.0, facecolor='1.0', alpha=1.0, ls='dotted') 13 plt.axhline(y=0.5, ls='dotted', color='k') #在y=0.5的地方加上黑色虛線 14 plt.yticks([0.0, 0.5, 1.0]) #y軸標度 15 plt.ylim(-0.1, 1.1) #y軸范圍 16 plt.show()
二. LogisticRegression回歸算法
LogisticRegression回歸模型在Sklearn.linear_model子類下,調用sklearn邏輯回歸算法步驟比較簡單,即:
(1) 導入模型。調用邏輯回歸LogisticRegression()函數。
(2) fit()訓練。調用fit(x,y)的方法來訓練模型,其中x為數據的屬性,y為所屬類型。
(3) predict()預測。利用訓練得到的模型對數據集進行預測,返回預測結果。
分類器完整實現代碼如下:
1 # !/usr/bin/env python 2 # encoding: utf-8 3 __author__ = 'Xiaolin Shen' 4 from sklearn.linear_model import LogisticRegression 5 import numpy as np 6 import pandas as pd 7 from sklearn import preprocessing 8 from sklearn import model_selection 9 import matplotlib.pyplot as plt 10 import matplotlib as mpl 11 from matplotlib import colors 12 from sklearn.preprocessing import StandardScaler 13 from sklearn.pipeline import Pipeline 14 15 16 # 當使用numpy中的loadtxt函數導入該數據集時,假設數據類型dtype為浮點型,但是很明顯數據集的第五列的數據類型是字符串並不是浮點型。 17 # 因此需要額外做一個工作,即通過loadtxt()函數中的converters參數將第五列通過轉換函數映射成浮點類型的數據。 18 # 首先,我們要寫出一個轉換函數: 19 # 定義一個函數,將不同類別標簽與數字相對應 20 def iris_type(s): 21 class_label={b'Iris-setosa':0,b'Iris-versicolor':1,b'Iris-virginica':2} 22 return class_label[s] 23 24 #(1)使用numpy中的loadtxt讀入數據文件 25 filepath='IRIS_dataset.txt' # 數據文件路徑 26 data=np.loadtxt(filepath,dtype=float,delimiter=',',converters={4:iris_type}) 27 #以上4個參數中分別表示: 28 #filepath :文件路徑。eg:C:/Dataset/iris.txt。 29 #dtype=float :數據類型。eg:float、str等。 30 #delimiter=',' :數據以什么分割符號分割。eg:‘,’。 31 #converters={4:iris_type} :對某一列數據(第四列)進行某種類型的轉換,將數據列與轉換函數進行映射的字典。eg:{1:fun},含義是將第2列對應轉換函數進行轉換。 32 # converters={4: iris_type}中“4”指的是第5列。 33 34 # print(data) 35 #讀入結果示例為: 36 # [[ 5.1 3.5 1.4 0.2 0. ] 37 # [ 4.9 3. 1.4 0.2 0. ] 38 # [ 4.7 3.2 1.3 0.2 0. ] 39 # [ 4.6 3.1 1.5 0.2 0. ] 40 # [ 5. 3.6 1.4 0.2 0. ]] 41 42 43 #(2)將原始數據集划分成訓練集和測試集 44 X ,y=np.split(data,(4,),axis=1) #np.split 按照列(axis=1)進行分割,從第四列開始往后的作為y 數據,之前的作為X 數據。函數 split(數據,分割位置,軸=1(水平分割) or 0(垂直分割))。 45 x=X[:,0:2] #在 X中取前兩列作為特征(為了后期的可視化畫圖更加直觀,故只取前兩列特征值向量進行訓練) 46 x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,random_state=1,test_size=0.3) 47 # 用train_test_split將數據隨機分為訓練集和測試集,測試集占總數據的30%(test_size=0.3),random_state是隨機數種子 48 # 參數解釋: 49 # x:train_data:所要划分的樣本特征集。 50 # y:train_target:所要划分的樣本結果。 51 # test_size:樣本占比,如果是整數的話就是樣本的數量。 52 # random_state:是隨機數的種子。 53 # (隨機數種子:其實就是該組隨機數的編號,在需要重復試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他參數一樣的情況下你得到的隨機數組是一樣的。但填0或不填,每次都會不一樣。 54 # 隨機數的產生取決於種子,隨機數和種子之間的關系遵從以下兩個規則:種子不同,產生不同的隨機數;種子相同,即使實例不同也產生相同的隨機數。) 55 56 57 #(3)搭建模型,訓練LogisticRegression分類器 58 classifier=Pipeline([('sc',StandardScaler()),('clf',LogisticRegression())]) 59 #開始訓練 60 classifier.fit(x_train,y_train.ravel()) 61 62 63 def show_accuracy(y_hat,y_test,parameter): 64 pass 65 66 #(4)計算LogisticRegression分類器的准確率 67 print("LogisticRegression-輸出訓練集的准確率為:",classifier.score(x_train,y_train)) 68 y_hat=classifier.predict(x_train) 69 show_accuracy(y_hat,y_train,'訓練集') 70 print("LogisticRegression-輸出測試集的准確率為:",classifier.score(x_test,y_test)) 71 y_hat=classifier.predict(x_test) 72 show_accuracy(y_hat,y_test,'測試集') 73 # LogisticRegression-輸出訓練集的准確率為: 0.809523809524 74 # LogisticRegression-輸出測試集的准確率為: 0.688888888889 75 76 77 # 查看決策函數,可以通過decision_function()實現。decision_function中每一列的值代表距離各類別的距離。 78 print('decision_function:\n', classifier.decision_function(x_train)) 79 print('\npredict:\n', classifier.predict(x_train)) 80 81 82 # (5)繪制圖像 83 # 1.確定坐標軸范圍,x,y軸分別表示兩個特征 84 x1_min, x1_max = x[:, 0].min(), x[:, 0].max() # 第0列的范圍 85 x2_min, x2_max = x[:, 1].min(), x[:, 1].max() # 第1列的范圍 86 x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j] # 生成網格采樣點 87 grid_test = np.stack((x1.flat, x2.flat), axis=1) # 測試點 88 # print 'grid_test = \n', grid_test 89 grid_hat = classifier.predict(grid_test) # 預測分類值 90 grid_hat = grid_hat.reshape(x1.shape) # 使之與輸入的形狀相同 91 92 93 # 2.指定默認字體 94 mpl.rcParams['font.sans-serif'] = [u'SimHei'] 95 mpl.rcParams['axes.unicode_minus'] = False 96 # 3.繪制 97 cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF']) 98 cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) 99 100 alpha=0.5 101 102 plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light) # 預測值的顯示 103 # plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', s=50, cmap=cm_dark) # 樣本 104 plt.plot(x[:, 0], x[:, 1], 'o', alpha=alpha, color='blue', markeredgecolor='k') 105 plt.scatter(x_test[:, 0], x_test[:, 1], s=120, facecolors='none', zorder=10) # 圈中測試集樣本 106 plt.xlabel(u'花萼長度', fontsize=13) 107 plt.ylabel(u'花萼寬度', fontsize=13) 108 plt.xlim(x1_min, x1_max) 109 plt.ylim(x2_min, x2_max) 110 plt.title(u'鳶尾花LogisticRegression分類結果', fontsize=15) 111 plt.grid() #顯示網格 112 plt.show()
程序運行結果:
數據可視化展示: