聲明:本次撰寫以Datawhale團隊提供的學習材料以自學爲主,代碼爲Datawhale團隊提供,利用阿里雲天池實驗室與編輯器pycharm完成測試。
學習目標:
*瞭解 邏輯迴歸的理論
*掌握邏輯迴歸的sklearn 函數調用使用並將其運用到鳶尾花數據集預測
代碼流程:
Part1 Demo實踐python
Part2 基於鳶尾花(iris)數據集的邏輯迴歸分類實踐dom
邏輯迴歸原理簡介:
邏輯斯蒂迴歸是統計學中經典的分類方法,具體的內容能夠參考李航老師編著的《統計學習方法》第二版與周志華老師所著《機器學習》即西瓜書,裏面有着詳細的介紹。
如圖3.21所示。
其中用到的邏輯斯諦函數可用python代碼以下表示:機器學習
import numpy as np import matplotlib.pyplot as plt x = np.arange(-5,5,0.01) y = 1/(1+np.exp(-x)) plt.plot(x,y) plt.xlabel('z') plt.ylabel('y') plt.grid() plt.show()
如圖所示:
編輯器
Part1 Demo實踐函數
#!/usr/bin/env python # -*- coding:utf-8 -*- ## 基礎函數庫 import numpy as np ## 導入畫圖庫 import matplotlib.pyplot as plt import seaborn as sns ## 導入邏輯迴歸模型函數 from sklearn.linear_model import LogisticRegression ##Demo演示LogisticRegression分類 ## 構造數據集 x_fearures = np.array([[-1, -2], [-2, -1], [-3, -2], [1, 3], [2, 1], [3, 2]]) y_label = np.array([0, 0, 0, 1, 1, 1]) ## 調用邏輯迴歸模型 lr_clf = LogisticRegression() ## 用邏輯迴歸模型擬合構造的數據集 lr_clf = lr_clf.fit(x_fearures, y_label) #其擬合方程爲 y=w0+w1*x1+w2*x2 ##查看其對應模型的w print('the weight of Logistic Regression:',lr_clf.coef_) ##查看其對應模型的w0 print('the intercept(w0) of Logistic Regression:',lr_clf.intercept_) ##the weight of Logistic Regression:[[0.73462087 0.6947908]] ##the intercept(w0) of Logistic Regression:[-0.03643213] ## 可視化構造的數據樣本點 plt.figure() plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis') plt.title('Dataset') plt.show() # 可視化決策邊界 plt.figure() plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis') plt.title('Dataset') nx, ny = 200, 100 x_min, x_max = plt.xlim() y_min, y_max = plt.ylim() x_grid, y_grid = np.meshgrid(np.linspace(x_min, x_max, nx),np.linspace(y_min, y_max, ny)) z_proba = lr_clf.predict_proba(np.c_[x_grid.ravel(), y_grid.ravel()]) z_proba = z_proba[:, 1].reshape(x_grid.shape) plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue') plt.show() ### 可視化預測新樣本 plt.figure() ## new point 1 x_fearures_new1 = np.array([[0, -1]]) plt.scatter(x_fearures_new1[:,0],x_fearures_new1[:,1], s=50, cmap='viridis') plt.annotate(s='New point 1',xy=(0,-1),xytext=(-2,0),color='blue',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red')) ## new point 2 x_fearures_new2 = np.array([[1, 2]]) plt.scatter(x_fearures_new2[:,0],x_fearures_new2[:,1], s=50, cmap='viridis') plt.annotate(s='New point 2',xy=(1,2),xytext=(-1.5,2.5),color='red',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red')) ## 訓練樣本 plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis') plt.title('Dataset') # 可視化決策邊界 plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue') plt.show() ### 可視化預測新樣本 plt.figure() ## new point 1 x_fearures_new1 = np.array([[0, -1]]) plt.scatter(x_fearures_new1[:,0],x_fearures_new1[:,1], s=50, cmap='viridis') plt.annotate(s='New point 1',xy=(0,-1),xytext=(-2,0),color='blue',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red')) ## new point 2 x_fearures_new2 = np.array([[1, 2]]) plt.scatter(x_fearures_new2[:,0],x_fearures_new2[:,1], s=50, cmap='viridis') plt.annotate(s='New point 2',xy=(1,2),xytext=(-1.5,2.5),color='red',arrowprops=dict(arrowstyle='-|>',connectionstyle='arc3',color='red')) ## 訓練樣本 plt.scatter(x_fearures[:,0],x_fearures[:,1], c=y_label, s=50, cmap='viridis') plt.title('Dataset') # 可視化決策邊界 plt.contour(x_grid, y_grid, z_proba, [0.5], linewidths=2., colors='blue') plt.show()
出圖:
能夠發現訓練好的迴歸模型將X_new1預測爲了類別0(判別面左下側),X_new2預測爲了類別1(判別面右上側)。其訓練獲得的邏輯迴歸模型的機率爲0.5的判別面爲上圖中藍色的線。
可是提供的代碼也存在着一些小問題,好比說:工具
import seaborn as sns
雖然導入了seaborn庫,可是程序中並無用到。性能
在實踐的最開始,咱們首先須要導入一些基礎的函數庫包括:numpy (Python進行科學計算的基礎軟件包)(但實際的代碼運行過程當中並不須要numpy包),pandas(pandas是一種快速,強大,靈活且易於使用的開源數據分析和處理工具),matplotlib和seaborn繪圖。
本次咱們選擇鳶花數據(iris)進行方法的嘗試訓練,該數據集一共包含5個變量,其中4個特徵變量,1個目標分類變量。共有150個樣本,目標變量爲 花的類別 其都屬於鳶尾屬下的三個亞屬,分別是山鳶尾 (Iris-setosa),變色鳶尾(Iris-versicolor)和維吉尼亞鳶尾(Iris-virginica)。包含的三種鳶尾花的四個特徵,分別是花萼長度(cm)、花萼寬度(cm)、花瓣長度(cm)、花瓣寬度(cm),這些形態特徵在過去被用來識別物種。
數據集如圖:
學習
## 基礎函數庫 import numpy as np import pandas as pd ## 繪圖函數庫 import matplotlib.pyplot as plt import seaborn as sns ##咱們利用sklearn中自帶的iris數據做爲數據載入,並利用Pandas轉化爲DataFrame格式 from sklearn.datasets import load_iris data = load_iris() # 獲得數據特徵 iris_target = data.target # 獲得數據對應的標籤 iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) # 利用Pandas轉化爲DataFrame格式 ##利用.info()查看數據的總體信息 iris_features.info() ##<class'pandas.core.frame.DataFrame'> ##RangeIndex:150entries,0to149 ##Datacolumns(total4columns): ###ColumnNon-NullCountDtype ##---------------------------- ##0sepallength(cm)150non-nullfloat64 ##1sepalwidth(cm)150non-nullfloat64 ##2petallength(cm)150non-nullfloat64 ##3petalwidth(cm)150non-nullfloat64 ##dtypes:float64(4) ##memoryusage:4.8KB ##進行簡單的數據查看,咱們能夠利用.head()頭部.tail()尾部 iris_features.head() ##其對應的類別標籤爲,其中0,1,2分別表明'setosa','versicolor','virginica'三種不一樣花的類別 iris_target ##array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ##0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ##0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ##1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ##1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2, ##2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, ##2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]) ##利用value_counts函數查看每一個類別數量 pd.Series(iris_target).value_counts() ##2 50 ##1 50 ##0 50 ##dtype:int64 ##利用value_counts函數查看每一個類別數量 pd.Series(iris_target).value_counts() ##2 50 ##1 50 ##0 50 ##dtype:int64 ## 合併標籤和特徵信息 iris_all = iris_features.copy() ##進行淺拷貝,防止對於原始數據的修改 iris_all['target'] = iris_target ## 特徵與標籤組合的散點可視化 sns.pairplot(data=iris_all, diag_kind='hist', hue='target') plt.show() for col in iris_features.columns: sns.boxplot(x='target', y=col, saturation=0.5, palette='pastel', data=iris_all) plt.title(col) plt.show() # 選取其前三個特徵繪製三維散點圖 from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='3d') iris_all_class0 = iris_all[iris_all['target'] == 0].values iris_all_class1 = iris_all[iris_all['target'] == 1].values iris_all_class2 = iris_all[iris_all['target'] == 2].values # 'setosa'(0), 'versicolor'(1), 'virginica'(2) ax.scatter(iris_all_class0[:, 0], iris_all_class0[:, 1], iris_all_class0[:, 2], label='setosa') ax.scatter(iris_all_class1[:, 0], iris_all_class1[:, 1], iris_all_class1[:, 2], label='versicolor') ax.scatter(iris_all_class2[:, 0], iris_all_class2[:, 1], iris_all_class2[:, 2], label='virginica') plt.legend() plt.show() ##爲了正確評估模型性能,將數據劃分爲訓練集和測試集,並在訓練集上訓練模型,在測試集上驗證模型性能。 from sklearn.model_selection import train_test_split ##選擇其類別爲0和1的樣本(不包括類別爲2的樣本) iris_features_part = iris_features.iloc[:100] iris_target_part = iris_target[:100] ##測試集大小爲20%,80%/20%分 x_train, x_test, y_train, y_test = train_test_split(iris_features_part, iris_target_part, test_size=0.2, random_state=2020) ##從sklearn中導入邏輯迴歸模型 from sklearn.linear_model import LogisticRegression ##定義邏輯迴歸模型 clf = LogisticRegression(random_state=0, solver='lbfgs') ##在訓練集上訓練邏輯迴歸模型 clf.fit(x_train, y_train) ##查看其對應的w print('the weight of Logistic Regression:', clf.coef_) ##查看其對應的w0 print('the intercept(w0) of Logistic Regression:', clf.intercept_) ##在訓練集和測試集上分佈利用訓練好的模型進行預測 train_predict = clf.predict(x_train) test_predict = clf.predict(x_test) from sklearn import metrics ##利用accuracy(準確度)【預測正確的樣本數目佔總預測樣本數目的比例】評估模型效果 print('The accuracy of the Logistic Regression is:', metrics.accuracy_score(y_train, train_predict)) print('The accuracy of the Logistic Regression is:', metrics.accuracy_score(y_test, test_predict)) ##查看混淆矩陣(預測值和真實值的各種狀況統計矩陣) confusion_matrix_result = metrics.confusion_matrix(test_predict, y_test) print('The confusion matrix result:\n', confusion_matrix_result) ##利用熱力圖對於結果進行可視化 plt.figure(figsize=(8, 6)) sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues') plt.xlabel('Predictedlabels') plt.ylabel('Truelabels') plt.show() ##The accuracy of the Logistic Regressionis:1.0 ##The accuracy of the Logistic Regressionis:1.0 ##The confusion matrix result: ##[[9 0] ##[0 11]] ##測試集大小爲20%,80%/20%分 x_train, x_test, y_train, y_test = train_test_split(iris_features, iris_target, test_size=0.2, random_state=2020) ##定義邏輯迴歸模型 clf = LogisticRegression(random_state=0, solver='lbfgs') ##在訓練集上訓練邏輯迴歸模型 clf.fit(x_train, y_train) ##在訓練集上訓練邏輯迴歸模型 clf.fit(x_train, y_train) ##查看其對應的w print('the weight of Logistic Regression:\n', clf.coef_) ##查看其對應的w0 print('the intercept(w0) of Logistic Regression:\n', clf.intercept_) ##因爲這個是3分類,全部咱們這裏獲得了三個邏輯迴歸模型的參數,其三個邏輯迴歸組合起來便可實現三分類 ##在訓練集和測試集上分佈利用訓練好的模型進行預測 train_predict = clf.predict(x_train) test_predict = clf.predict(x_test) ##因爲邏輯迴歸模型是機率預測模型(前文介紹的p=p(y=1|x,\theta)),全部咱們能夠利用predict_proba函數預測其機率 train_predict_proba = clf.predict_proba(x_train) test_predict_proba = clf.predict_proba(x_test) print('The test predict Probability of each class:\n', test_predict_proba) ##其中第一列表明預測爲0類的機率,第二列表明預測爲1類的機率,第三列表明預測爲2類的機率。 ##利用accuracy(準確度)【預測正確的樣本數目佔總預測樣本數目的比例】評估模型效果 print('The accuracy of the Logistic Regression is:', metrics.accuracy_score(y_train, train_predict)) print('The accuracy of the Logistic Regression is:', metrics.accuracy_score(y_test, test_predict)) ##查看混淆矩陣 confusion_matrix_result = metrics.confusion_matrix(test_predict, y_test) print('The confusion matrix result:\n', confusion_matrix_result) ##利用熱力圖對於結果進行可視化 plt.figure(figsize=(8, 6)) sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues') plt.xlabel('Predicted labels') plt.ylabel('True labels') plt.show() ##The confusion matrix result: ##[[10 0 0] ##[0 8 2] ##[0 2 8]]
出圖:
從上圖能夠發現,在2D狀況下不一樣的特徵組合對於不一樣類別的花的散點分佈,以及大概的區分能力。
利用箱型圖咱們也能夠獲得不一樣類別在不一樣特徵上的分佈差別狀況。
咱們能夠發現其準確度爲1,表明全部的樣本都預測正確了。
[1] 周志華,機器學習
[1] 李航,統計學習方法(第二版)測試