0.鳶尾花數據集
鳶尾花數據集作為入門經典數據集。Iris數據集是常用的分類實驗數據集,由Fisher, 1936收集整理。Iris也稱鳶尾花卉數據集,是一類多重變量分析的數據集。數據集包含150個數據集,分為3類,每類50個數據,每個數據包含4個屬性。可通過花萼長度,花萼寬度,花瓣長度,花瓣寬度4個屬性預測鳶尾花卉屬於(Setosa,Versicolour,Virginica)三個種類中的哪一類。
在三個類別中,其中有一個類別和其他兩個類別是線性可分的。另外。在sklearn中已內置了此數據集。
1 from sklearn.datasets import load_iris #導入IRIS數據集 2 iris = load_iris() #特征矩陣
數據集的格式如下圖所示:
1.數據集的載入
雖然在sklearn中,內置了鳶尾花數據集,但是我們用的是下載好的數據集,下面是數據集的讀入,我們先通過手動的方式將數據集進行讀入。
1 f = open(path) 2 x = [] 3 y = [] 4 for d in f: 5 d = d.strip() 6 if d: 7 d = d.split(',') 8 y.append(d[-1]) 9 x.append(list(map(float, d[:-1]))) 10 x = np.array(x) 11 y = np.array(y) 12 print(x) 13 y[y == 'Iris-setosa'] = 0 14 y[y == 'Iris-versicolor'] = 1 15 y[y == 'Iris-virginica'] = 2 16 print(y) 17 y = y.astype(dtype=np.int) 18 print(y)
代碼的13-15中,通過判斷y中的標簽值,返回的是一個y大小相同的一個boolearn類型的列表,在通過這個列表進行賦值操作,非常的迅速和靈活。
讀取的X數據如下:
處理后的標簽的數據如下:
除了上述方式的手動讀入數據,還可以通過pandas庫來進行數據的讀取。
1 import numpy as np 2 from sklearn.linear_model import LogisticRegression 3 import matplotlib.pyplot as plt 4 import matplotlib as mpl 5 from sklearn import preprocessing 6 import pandas as pd 7 from sklearn.preprocessing import StandardScaler 8 from sklearn.pipeline import Pipeline 9 10 df = pd.read_csv(path, header=0) 11 x = df.values[:, :-1] 12 y = df.values[:, -1] 13 print('x = \n', x) 14 print('y = \n', y) 15 le = preprocessing.LabelEncoder() 16 le.fit(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']) 17 print(le.classes_) 18 y = le.transform(y) 19 print('Last Version, y = \n', y)
上述代碼中,pd.read_csv(path, header=0),header :指定行數用來作為列名,數據開始行數。如果文件中沒有列名,則默認為0【第一行數據】,否則設置
為None。
sklearn.preprocessing.LabelEncoder():標准化標簽,將標簽值統一轉換成range(標簽值個數-1)范圍內,例如["paris", "paris", "tokyo", "amsterdam"];里面不
同的標簽數目是3個,則標准化標簽之后就是0,1,2,並且根據字典排序。
le.fit(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'])含義為將標簽集喂給le標簽處理器,y = le.transform(y)對y進行轉化。
也可以使用numpy來對數據進行加載。
def iris_type(s): it = {b'Iris-setosa': 0, b'Iris-versicolor': 1, b'Iris-virginica': 2} return it[s] data = np.loadtxt(path, dtype=float, delimiter=',', converters={4: iris_type})
使用np中的loadtxt來對數據加載,delimiter指定數據的分割符,converter為指定需要進行轉換的列及對應的轉換函數。
2.構建線性模型
為了后面的可視化的效果,我們在此僅選用了連兩個特征構建logistic回歸模型,代碼如下:
1 x = x[:, :2] 2 print(x) 3 print(y) 4 x = StandardScaler().fit_transform(x) 5 lr = LogisticRegression() # Logistic回歸模型 6 lr.fit(x, y.ravel()) # 根據數據[x,y],計算回歸參數
StandardScaler----計算訓練集的平均值和標准差,以便測試數據集使用相同的變換。即fit_transform()的作用就是先擬合數據,然后轉化它將其轉化為標准形
式。調用fit_transform(),其實找到了均值μ和方差σ^2,即已經找到了轉換規則,把這個規則利用在訓練集上,同樣,可以直接將其運用到測試集上(甚至交叉驗證
集)。
我們也可以使用管道的方式構建模型,並進行訓練:
1 lr = Pipeline([('sc', StandardScaler()), 2 ('clf', LogisticRegression()) ]) 3 lr.fit(x, y.ravel())
LogisticRegression()的主要參數如下:
- penalty:懲罰項,str類型,可選參數為l1和l2,默認為l2。用於指定懲罰項中使用的規范。newton-cg、sag和lbfgs求解算法只支持L2規范。L1規范假設的是模型的參數滿足拉普拉斯分布,L2假設的模型參數滿足高斯分布。
- dual:對偶或原始方法,bool類型,默認為False。對偶方法只用在求解線性多核(liblinear)的L2懲罰項上。當樣本數量>樣本特征的時候,dual通常設置為False。
- tol:停止求解的標准,float類型,默認為1e-4。就是求解到多少的時候,停止,認為已經求出最優解。
- c:正則化系數λ的倒數,float類型,默認為1.0。必須是正浮點型數。像SVM一樣,越小的數值表示越強的正則化。
- fit_intercept:是否存在截距或偏差,bool類型,默認為True。
- intercept_scaling:僅在正則化項為”liblinear”,且fit_intercept設置為True時有用。float類型,默認為1。
- class_weight:用於標示分類模型中各種類型的權重,可以是一個字典或者’balanced’字符串,默認為不輸入,也就是不考慮權重,即為None。
- random_state:隨機數種子,int類型,可選參數,默認為無,僅在正則化優化算法為sag,liblinear時有用。
- solver:優化算法選擇參數,只有五個可選參數,即newton-cg,lbfgs,liblinear,sag,saga。默認為liblinear。solver參數決定了我們對邏輯回歸損失函數的優化方法,有四種算法可以選擇,分別是:
- liblinear:使用了開源的liblinear庫實現,內部使用了坐標軸下降法來迭代優化損失函數。
- lbfgs:擬牛頓法的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
- newton-cg:也是牛頓法家族的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
- sag:即隨機平均梯度下降,是梯度下降法的變種,和普通梯度下降法的區別是每次迭代僅僅用一部分的樣本來計算梯度,適合於樣本數據多的時候。
- saga:線性收斂的隨機優化算法的的變重。
3.模型的可視化
我們可以在所選特征的范圍內,從最大值到最小值構建一系列的數據,使得它能覆蓋整個的特征數據范圍,然后預測這些值所屬的分類,並給它們所在的區域
上色,這樣我們就能夠清楚的看到模型每個分類的區域了,具體的代碼如下所示:
1 N, M = 500, 500 # 橫縱各采樣多少個值 2 x1_min, x1_max = x[:, 0].min(), x[:, 0].max() # 第0列的范圍 3 x2_min, x2_max = x[:, 1].min(), x[:, 1].max() # 第1列的范圍 4 t1 = np.linspace(x1_min, x1_max, N) 5 t2 = np.linspace(x2_min, x2_max, M) 6 x1, x2 = np.meshgrid(t1, t2) # 生成網格采樣點 7 x_test = np.stack((x1.flat, x2.flat), axis=1) # 測試點 8 9 cm_light = mpl.colors.ListedColormap(['#77E0A0', '#FF8080', '#A0A0FF']) 10 cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) 11 y_hat = lr.predict(x_test) # 預測值 12 y_hat = y_hat.reshape(x1.shape) # 使之與輸入的形狀相同 13 plt.pcolormesh(x1, x2, y_hat, cmap=cm_light) # 預測值的顯示 14 plt.scatter(x[:, 0], x[:, 1], c=y.ravel(), edgecolors='k', s=50, cmap=cm_dark) 15 plt.xlabel('petal length') 16 plt.ylabel('petal width') 17 plt.xlim(x1_min, x1_max) 18 plt.ylim(x2_min, x2_max) 19 plt.grid() 20 plt.savefig('2.png') 21 plt.show()
np.meshgrid()函數常用於生成網格數據,多用於繪制三維圖形。 mpl.colors.ListedColormap(['#77E0A0', '#FF8080', '#A0A0FF'])生成一個顏色的列表,plt.pcolormesh(x1, x2, y_hat, cmap=cm_light) 根據顏色列表中的值,給傳入的坐標進行繪圖。
繪制的圖片的效果如下:
4.計算模型的准確率
由於我們使用的是兩個特征進行數據集的分類,所以分類的准確率並不是高,代碼如下:
1 y_hat = lr.predict(x) 2 y = y.reshape(-1) 3 result = y_hat == y 4 print(y_hat) 5 print(result) 6 acc = np.mean(result) 7 print('准確度: %.2f%%' % (100 * acc))
具體的准確率是多少呢?同學們可以自己動手試一下哦!
歡迎關注我的公眾號,不定期分享機器學習模型原理!