本筆記為參加阿里云“天池龍珠計(jì)劃 機(jī)器學(xué)習(xí)訓(xùn)練營”所做的學(xué)習(xí)記錄毯焕,代碼及知識(shí)內(nèi)容均來源于訓(xùn)練營,本人稍作擴(kuò)充糠惫。
4.2 基于鳶尾花(iris)數(shù)據(jù)集的邏輯回歸分類實(shí)踐
在實(shí)踐的最開始盯另,我們首先需要導(dǎo)入一些基礎(chǔ)的函數(shù)庫包括:numpy (python進(jìn)行科學(xué)計(jì)算的基礎(chǔ)軟件包)蛙吏,pandas(一種快速作谭,強(qiáng)大稽物,靈活且易于使用的開源數(shù)據(jù)分析和處理工具),matplotlib和seaborn繪圖折欠。
Step1:庫函數(shù)導(dǎo)入
## 基礎(chǔ)函數(shù)庫
import numpy as np
import pandas as pd
## 繪圖函數(shù)庫
import matplotlib.pyplot as plt
import seaborn as sns
本次我們選擇鳶花數(shù)據(jù)(iris)進(jìn)行方法的嘗試訓(xùn)練贝或,該數(shù)據(jù)集一共包含5個(gè)變量秧倾,其中4個(gè)特征變量,1個(gè)目標(biāo)分類變量傀缩。共有150個(gè)樣本,目標(biāo)變量為 花的類別 其都屬于鳶尾屬下的三個(gè)亞屬农猬,分別是山鳶尾 (Iris-setosa)赡艰,變色鳶尾(Iris-versicolor)和維吉尼亞鳶尾(Iris-virginica)。包含的三種鳶尾花的四個(gè)特征斤葱,分別是花萼長度(cm)慷垮、花萼寬度(cm)、花瓣長度(cm)揍堕、花瓣寬度(cm)料身,這些形態(tài)特征在過去被用來識(shí)別物種。
Step2:數(shù)據(jù)讀取/載入
## 我們利用 sklearn 中自帶的 iris 數(shù)據(jù)作為數(shù)據(jù)載入衩茸,并利用Pandas轉(zhuǎn)化為DataFrame格式
from sklearn.datasets import load_iris
data = load_iris() #得到數(shù)據(jù)特征
iris_target = data.target #得到數(shù)據(jù)對(duì)應(yīng)的標(biāo)簽
iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas轉(zhuǎn)化為DataFrame格式
Step3:數(shù)據(jù)信息簡單查看
## 利用.info()查看數(shù)據(jù)的整體信息
iris_features.info()
# Output:
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 150 entries, 0 to 149
# Data columns (total 4 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 sepal length (cm) 150 non-null float64
# 1 sepal width (cm) 150 non-null float64
# 2 petal length (cm) 150 non-null float64
# 3 petal width (cm) 150 non-null float64
# dtypes: float64(4)
# memory usage: 4.8 KB
## 進(jìn)行簡單的數(shù)據(jù)查看芹血,我們可以利用 .head() 頭部.tail()尾部
iris_features.head()
iris_features.tail()
## 其對(duì)應(yīng)的類別標(biāo)簽為,其中0幔烛,1囊蓝,2分別代表'setosa', 'versicolor', 'virginica'三種不同花的類別。
iris_target
# Output:
# 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函數(shù)查看每個(gè)類別數(shù)量
pd.Series(iris_target).value_counts()
# Output:
# 2 50
# 1 50
# 0 50
# dtype: int64
## 對(duì)于特征進(jìn)行一些統(tǒng)計(jì)描述
iris_features.describe()
Step4:可視化描述
## 合并標(biāo)簽和特征信息
iris_all = iris_features.copy() ##進(jìn)行淺拷貝狡恬,防止對(duì)于原始數(shù)據(jù)的修改
iris_all['target'] = iris_target
## 特征與標(biāo)簽組合的散點(diǎn)可視化
sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target')
plt.show()
從上圖可以發(fā)現(xiàn)蝎宇,在2D情況下不同的特征組合對(duì)于不同類別的花的散點(diǎn)分布弟劲,以及大概的區(qū)分能力函卒。
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()
利用箱型圖我們也可以得到不同類別在不同特征上的分布差異情況报嵌。
# 選取其前三個(gè)特征繪制三維散點(diǎn)圖
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()
Step5:利用 邏輯回歸模型 在二分類上 進(jìn)行訓(xùn)練和預(yù)測(cè)
## 為了正確評(píng)估模型性能,將數(shù)據(jù)劃分為訓(xùn)練集和測(cè)試集血筑,并在訓(xùn)練集上訓(xùn)練模型豺总,在測(cè)試集上驗(yàn)證模型性能喻喳。
from sklearn.model_selection import train_test_split
## 選擇其類別為0和1的樣本 (不包括類別為2的樣本)
iris_features_part = iris_features.iloc[:100]
iris_target_part = iris_target[:100]
## 測(cè)試集大小為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中導(dǎo)入邏輯回歸模型
from sklearn.linear_model import LogisticRegression
## 定義 邏輯回歸模型
clf = LogisticRegression(random_state=0, solver='lbfgs')
## 在訓(xùn)練集上訓(xùn)練邏輯回歸模型
clf.fit(x_train, y_train)
Output:
# LogisticRegression(random_state=0)
# 這里不同版本的sklearn顯示的內(nèi)容不一樣蹦哼;在訓(xùn)練營里使用的是0.19.1纲熏,參數(shù)顯示詳細(xì):
# LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
# intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
# penalty='l2', random_state=0, solver='lbfgs', tol=0.0001,
# verbose=0, warm_start=False)
## 查看其對(duì)應(yīng)的w
print('the weight of Logistic Regression:',clf.coef_)
## 查看其對(duì)應(yīng)的w0
print('the intercept(w0) of Logistic Regression:',clf.intercept_)
# Output:
# the weight of Logistic Regression: [[ 0.45181973 -0.81743611 2.14470304 0.89838607]]
# the intercept(w0) of Logistic Regression: [-6.53367714]
## 在訓(xùn)練集和測(cè)試集上分布利用訓(xùn)練好的模型進(jìn)行預(yù)測(cè)
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
from sklearn import metrics
## 利用accuracy(準(zhǔn)確度)【預(yù)測(cè)正確的樣本數(shù)目占總預(yù)測(cè)樣本數(shù)目的比例】評(píng)估模型效果
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))
## 查看混淆矩陣 (預(yù)測(cè)值和真實(shí)值的各類情況統(tǒng)計(jì)矩陣)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)
# 利用熱力圖對(duì)于結(jié)果進(jìn)行可視化
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 accuracy of the Logistic Regression is: 1.0
# The accuracy of the Logistic Regression is: 1.0
# The confusion matrix result:
# [[ 9 0]
# [ 0 11]]
Step6:利用 邏輯回歸模型 在三分類(多分類)上 進(jìn)行訓(xùn)練和預(yù)測(cè)
## 測(cè)試集大小為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')
## 在訓(xùn)練集上訓(xùn)練邏輯回歸模型
clf.fit(x_train, y_train)
# Output:
# LogisticRegression(random_state=0)
## 查看其對(duì)應(yīng)的w
print('the weight of Logistic Regression:\n',clf.coef_)
## 查看其對(duì)應(yīng)的w0
print('the intercept(w0) of Logistic Regression:\n',clf.intercept_)
## 由于這個(gè)是三分類宣脉,所有我們這里得到了三個(gè)邏輯回歸模型的參數(shù)塑猖,其三個(gè)邏輯回歸組合起來即可實(shí)現(xiàn)三分類羊苟。
# Output:
# the weight of Logistic Regression:
# [[-0.45928925 0.83069891 -2.26606529 -0.99743982]
# [ 0.33117319 -0.72863425 -0.06841147 -0.98711029]
# [ 0.12811606 -0.10206465 2.33447676 1.98455011]]
# the intercept(w0) of Logistic Regression:
# [ 9.43880657 3.93047365 -13.36928022]
## 在訓(xùn)練集和測(cè)試集上分布利用訓(xùn)練好的模型進(jìn)行預(yù)測(cè)
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
## 由于邏輯回歸模型是概率預(yù)測(cè)模型(前文介紹的 p = p(y=1|x,\theta)),所以我們可以利用 predict_proba 函數(shù)預(yù)測(cè)其概率
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)
## 其中第一列代表預(yù)測(cè)為0類的概率蜡励,第二列代表預(yù)測(cè)為1類的概率阻桅,第三列代表預(yù)測(cè)為2類的概率。
## 利用accuracy(準(zhǔn)確度)【預(yù)測(cè)正確的樣本數(shù)目占總預(yù)測(cè)樣本數(shù)目的比例】評(píng)估模型效果
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)
# 利用熱力圖對(duì)于結(jié)果進(jìn)行可視化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
# Output:
# The confusion matrix result:
# [[10 0 0]
# [ 0 8 2]
# [ 0 2 8]]
通過結(jié)果我們可以發(fā)現(xiàn)趟章,其在三分類的結(jié)果的預(yù)測(cè)準(zhǔn)確度上有所下降,其在測(cè)試集上的準(zhǔn)確度為:86.67%, 86.67%,赖淤,這是由于'versicolor'(1)和 'virginica'(2)這兩個(gè)類別的特征咱旱,我們從可視化的時(shí)候也可以發(fā)現(xiàn),其特征的邊界具有一定的模糊性(邊界類別混雜锨天,沒有明顯區(qū)分邊界)剃毒,所有在這兩類的預(yù)測(cè)上出現(xiàn)了一定的錯(cuò)誤赘阀。
5 重要知識(shí)點(diǎn)
邏輯回歸 原理簡介:
Logistic回歸雖然名字里帶“回歸”幅慌,但是它實(shí)際上是一種分類方法胰伍,主要用于二分類問題(即輸出只有兩種骂租,分別代表兩個(gè)類別)渗饮,所以利用了Logistic函數(shù)(或稱為Sigmoid函數(shù))互站,函數(shù)形式為:
其對(duì)應(yīng)的函數(shù)圖像可以表示如下
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()