實驗二 邏輯回歸算法實驗

【實驗目的】

理解邏輯回歸算法原理,掌握邏輯回歸算法框架;
理解邏輯回歸的sigmoid函數;
理解邏輯回歸的損失函數;
針對特定應用場景及數據,能應用邏輯回歸算法解決實際分類問題。

【實驗內容】

1.根據給定的數據集,編寫python代碼完成邏輯回歸算法程序,實現如下功能:

建立一個邏輯回歸模型來預測一個學生是否會被大學錄取。假設您是大學部門的管理員,您想根據申請人的兩次考試成績來確定他們的入學機會。您有來自以前申請人的歷史數據,可以用作邏輯回歸的訓練集。對於每個培訓示例,都有申請人的兩次考試成績和錄取決定。您的任務是建立一個分類模型,根據這兩門考試的分數估計申請人被錄取的概率。
算法步驟與要求:

(1)讀取數據;(2)繪製數據觀察數據分佈情況;(3)編寫sigmoid函數代碼;(4)編寫邏輯回歸代價函數代碼;(5)編寫梯度函數代碼;(6)編寫尋找最優化參數代碼(可使用scipy.opt.fmin_tnc()函數);(7)編寫模型評估(預測)代碼,輸出預測準確率;(8)尋找決策邊界,畫出決策邊界直線圖。

2. 針對iris數據集,應用sklearn庫的邏輯回歸算法進行類別預測。

要求:

(1)使用seaborn庫進行數據可視化;(2)將iri數據集分為訓練集和測試集(兩者比例為8:2)進行三分類訓練和預測;(3)輸出分類結果的混淆矩陣。

【實驗報告要求】

對照實驗內容,撰寫實驗過程、算法及測試結果;
代碼規範化:命名規則、注釋;
實驗報告中需要顯示並說明涉及的數學原理公式;
查閱文獻,討論邏輯回歸算法的應用場景;

一、

(1)數據導入

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#讀取數據
data=pd.read_csv("D:/機器學習/ex2data1.txt",delimiter=',',header=None,names=['exam1','exam2','isAdmitted'])
data.head(5)
print(data)

(2)繪製數據觀察數據分佈情況

#數據可視化
positive = data[data['isAdmitted']==1]    #獲取正樣本
negative = data[data['isAdmitted']==0]    #獲取負樣本
fig,ax = plt.subplots(figsize=(12,8))
ax.scatter(positive['exam1'],positive['exam2'],s=30,c='g',marker='o',label='admitted')
ax.scatter(negative['exam1'],negative['exam2'],s=30,c='r',marker='x',label='not admitted')
ax.legend(loc=1)    #顯示標籤位置
ax.set_xlabel("Exam1 Score")
ax.set_ylabel("Exam2 Score")
plt.show()

(3)編寫sigmod函數

#編寫sigmoid函數
def sigmoid(z):
    return 1/(1+np.exp(-z))

(4)編寫邏輯回歸的代價函數

#編寫代價函數代碼
def computeCost(theta,X,Y):
    theta = np.matrix(theta) #不能缺少,因為參數theta是一維數組,進行矩陣想乘時要把theta先轉換為矩陣
    h=sigmoid(np.dot(X,(theta.T)))
    a=np.multiply(-Y,np.log(h))
    b=np.multiply((1-Y),np.log(1-h))
    return np.sum(a-b)/len(X)
computeCost(theta,X,Y)  #當theta值為0時,計算此時的代價值

(5)編寫梯度函數

#編寫梯度函數代碼
def gradient(theta,X,Y):
    theta = np.matrix(theta) #要先把theta轉化為矩陣
    h=sigmoid(np.dot(X,(theta.T)))
    grad=np.dot(((h-Y).T),X)/len(X)
    return np.array(grad).flatten()  #因為下面尋找最優化參數的函數(opt.fmin_tnc())要求傳入的gradient函返回值需要是一維數組,因此需要利用flatten()將grad進行轉換以下

gradient(theta,X,Y) #測試一下,當theta值都為為0時,計算一下此時的梯度為多少

(6)尋優參數

#使scipy.optimize包下的fmin_tnc函數來求解最優參數
import scipy.optimize as opt
result = opt.fmin_tnc(func=computeCost, x0=theta, fprime=gradient, args=(X, Y)) 
print(result)
theta=result[0]

(7)編寫模型評估代碼,輸出準確率

#編寫模型評估(預測)代碼
def predict(theta, X):
    theta = np.matrix(theta)
    temp = sigmoid(X * theta.T)
    #print(temp)
    return [1 if x >= 0.5 else 0 for x in temp]
    
predictValues=predict(theta,X)
hypothesis=[1 if a==b else 0 for (a,b)in zip(predictValues,Y)]
accuracy=hypothesis.count(1)/len(hypothesis)
print ('accuracy = {0}%'.format(accuracy*100))

(8)尋找決策邊界,畫出邊界直方圖

#編寫決策邊界
def find_x2(x1,theta):
    return [(-theta[0]-theta[1]*x_1)/theta[2] for x_1 in x1]
x1 = np.linspace(30, 100, 1000)
x2=find_x2(x1,theta)

#數據可視化
positive=data[data['isAdmitted']==1]
negative=data[data['isAdmitted']==0]
fig,ax=plt.subplots(figsize=(12,8))
ax.scatter(positive['exam1'],positive['exam2'],marker='+',label='addmitted')
ax.scatter(negative['exam2'],negative['exam1'],marker='o',label="not addmitted")
ax.plot(x1,x2,color='r',label="decision boundary")
ax.legend(loc=1)
ax.set_xlabel('Exam1 score')
ax.set_ylabel('Exam2 score')
plt.show()

二、

(1)導入基礎包

##  基礎函數庫
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
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics

(2)數據分析、測試訓練

data = load_iris() #得到數據特徵
iris_target = data.target #得到數據對應的標籤
iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas轉化為DataFrame格式
# 合併標籤和特徵信息
iris_all = iris_features.copy() ## 進行淺拷貝,防止對於原始數據的修改
iris_all['target'] = iris_target
# pairplot用來進行數據分析,畫兩兩特徵圖。常用參數介紹:data:必不可少的數據 hue: 用一個特徵來顯示圖像上的顏色,類似於打標籤 marker: 每個label的顯示圖像變動,有的是三角,有的是原點 vars:只留幾個特徵兩兩比較,diag_kind--矩陣  hist直方圖 kde核密度曲線
sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target') 
#顯示所有的 figure(不管是阻塞模式的還是交互模式的)。若一個 figure 下一個 plt.show(),則只有關閉一個 figure,才會出現下一個 figure。若最後設置 plt.show(),則會顯示設置的所有 figure。簡單來說,看完一張圖才能看下一張
plt.show()  # plt.show():

## 測試集大小為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()
# 在訓練集上訓練邏輯回歸模型
clf.fit(x_train, y_train)
## 因為3分類,所有我們這裡得到了三個邏輯回歸模型的參數,其三個邏輯回歸組合起來即可實現三分類。
## 在訓練集和測試集上分別利用訓練好的模型進行預測
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
# 查看其對應的w
print('邏輯回歸的權重:',clf.coef_)
## 查看其對應的w0
print('邏輯回歸的截距(w0):',clf.intercept_)

 

(3)輸出混淆矩陣

from sklearn import metrics
##利用accuracy(準確度)【預測正確的樣本數目佔總預測樣本數目的比例】評估模型效果
print('邏輯回歸準確度:',metrics.accuracy_score(y_train,train_predict))
print('邏輯回歸準確度:',metrics.accuracy_score(y_test,test_predict))
 
##查看混淆矩陣(預測值和真實值的各類情況統計矩陣)
confusion_matrix_result=metrics.confusion_matrix(y_test,test_predict)
print('混淆矩陣結果:\n',confusion_matrix_result)
 
## 利用熱力圖對於結果進行可視化,畫混淆矩陣
plt.figure(figsize=(8,6))
sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
plt.xlabel('PredictLabel')
plt.ylabel('TrueLabel')
plt.show()

 

三、實驗小結

(1)運用的公式

(2)應用場景:

應用:

  • 用於分類:適合做很多分類算法的基礎組件。
  • 用於預測:預測事件發生的概率(輸出)。
  • 用於分析:單一因素對某一個事件發生的影響因素分析(特徵參數值)。

適用:

  • 基本假設:輸出類別服從伯努利二項分佈。
  • 樣本線性可分。
  • 特徵空間不是很大的情況。
  • 不必在意特徵間相關性的情景。
  • 後續會有大量新數據的情況。