1. 程式人生 > >吳恩達機器學習邏輯迴歸python實現[對應ex2-ex2data1.txt資料集]

吳恩達機器學習邏輯迴歸python實現[對應ex2-ex2data1.txt資料集]

研一學生,初學機器學習,重心放在應用,弱化公式推導,能力有限,文中難免會有錯誤,懇請指正!QQ:245770710
此文是對網易雲課堂上吳恩達老師的機器學習課程邏輯迴歸一章對應的課後作業的python實現。

1. 先對資料集進行觀察,使用matplotlib將資料集繪製出散點圖。

​ 拿到一份資料想從中分析出一些內容,首先要了解拿到的資料,因此我們先把資料以散點圖的形式繪製出來,觀察其中的規律以確定用什麼模型進行預測。

# 匯入Matploylib庫
from matplotlib import pyplot as plt
import matplotlib.ticker as ticker

# 匯入訓練資料
train_data = open("data/ex2data1.txt")
# 獲取資料集的行數
lines = train_data.readlines()
# 定義x y資料 x1 y1:未通過 x2 y2:通過
x1 = []
y1 = []
x2 = []
y2 = []
# 迴圈處理所有的資料
for line in lines:
    scores = line.split(",")
    isQualified = scores[2].replace("\n", "")
    if isQualified == "0":
        x1.append(float(scores[0]))
        y1.append(float(scores[1]))
    else:
        x2.append(float(scores[0]))
        y2.append(float(scores[1]))
# 畫圖
plt.xlabel("Exam 1 score")
plt.ylabel("Exam 2 score")
#                   記號形狀      顏色      點的大小 設定標籤
plt.scatter(x1, y1, marker='o', color='red', s=15, label='Not admitted')
plt.scatter(x2, y2, marker='x', color='green', s=15, label='Admitted')
# 註釋的顯示位置:右上角
plt.legend(loc='upper right')
# 設定座標軸上刻度的精度
plt.gca().xaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))
plt.gca().yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))

plt.show()

資料集散點圖

在這裡插入圖片描述

2.觀察測試資料集的影象,定義預測函式h(x)

​ 觀察影象可得,對測試資料集進行分類只需一條直線即可,因為有兩個輸入引數(即第一次的分數x1和第二次的分數2),所以設
h θ ( x )

= θ 0 + θ 1 x 1
+ θ 2 x 2 = θ 0 x 0 + θ 1 x 1 + θ 2 x 2 = θ T X h_θ(x) = θ_0+θ_1x_1+θ_2x_2=θ_0x_0+θ_1x_1+θ_2x_2=θ^TX
其中x0均為1,此處需要注意的是,在程式碼中實現時我們的特徵矩陣是n+1個,多出來的一個特徵就是x0,並且x0都為1,之所以新增一個x0的原因是在程式碼中進行計算時是以矩陣的形式進行的,因此θ矩陣轉置後的行數必須與特徵矩陣X的列數一致,如果這兩個數不一致則無法進行矩陣運算。

​ 因此 sigmoid 函式為
g ( z ) = g ( h θ ( x ) ) = 1 1 + e h θ ( x ) g(z) = g( hθ(x) ) = \frac{1}{1+e^{-h_θ(x)}}

python 程式碼定義h(x)函式:

# 定義h(x)預測函式:theta為轉置後的矩陣,即theta是一個n行1列的矩陣
def hypothesis(theta, x):
    return np.dot(x, theta)

python程式碼定義sigmoid函式:

# 定義sigmoid函式
def sigmoid(theta, x):
    z = hypothesis(theta, x)
    return 1.0 / (1 + exp(-z))

3.定義代價函式

​ 根據Andrew Ng的視訊,邏輯迴歸的代價函式如下;
J ( θ ) = 1 M i = 1 m [ y ( i ) l o g ( θ 0 + θ 1 x 1 i + θ 2 x 2 i ) ( 1 y ( i ) ) l o g ( 1 θ 0 θ 1 x 1 i θ 2 x 2 i ) ] J(θ)=\frac{1}{M} \sum_{i=1}^{m}[-y^{(i)}log(θ_0+θ_1x_1^i+θ_2x_2^i)-(1-y^{(i)})log(1-θ_0-θ_1x_1^i-θ_2x_2^i)]
此處需要注意的是我們在python程式碼中實現時採用的矩陣運算(當然也可以使用for迴圈代替矩陣),因此需要對代價函式進行向量化。使用矩陣運算的速度遠高於for迴圈,具體的對比見https://www.cnblogs.com/liaohuiqiang/p/7663616.html,本文不再贅述。從代價函式到向量化的過程請參考https://blog.csdn.net/quiet_girl/article/details/70098009?locationNum=5&fps=1,在這篇文章中講的線性迴歸的向量化過程,邏輯迴歸代價函式的向量化請參照此篇文章自行理解,此處直接給出該代價函式的向量化後的結果,如下所示。

在這裡插入圖片描述

​ 根據向量化後的代價函式定義python程式碼:

# 定義代價函式
def cost(theta, X, y):
    return np.mean(-y * np.log(sigmoid(theta, X)) - (1 - y) * np.log(1 - sigmoid(theta, X)))

​ 在代價函式這一部分,需要注意的是:代價函式的定義方式決定了下一步是採用梯度下降演算法還是梯度上升演算法,梯度上升和梯度下降都是求預測值和真實值最接近時theta的值,不同的是梯度上升用於求最大值,梯度下降用於求最小值,具體介紹請參考https://blog.csdn.net/xiaoxiangzi222/article/details/55097570

​ 而Andrew Ng 在視訊直接給出了代價函式J(θ),但是沒有給出具體的過程。實際上在此處代價函式可以有兩種形式,一種是Andrew Ng給出的代價函式,也就是上文中給出的J(θ),另外一種是在J(θ)的基礎上新增一個符號即“-J(θ)”,新增一個負號以後,影象的開口方向就會變反,因此這兩個代價函式一個採用梯度下降另外一個採用梯度上升。由於Andrew Ng在前面的視訊中先講解了梯度下降法,因此在邏輯迴歸部分他繼續沿用梯度下降,因此他將代價函式定義為
J ( θ ) = 1 M i = 1 m [ y ( i ) l o g ( θ 0 + θ 1 x 1 i + θ 2 x 2 i ) ( 1 y ( i ) ) l o g ( 1 θ 0 θ 1 x 1 i θ 2 x 2 i ) ] J(θ)=\frac{1}{M} \sum_{i=1}^{m}[-y^{(i)}log(θ_0+θ_1x_1^i+θ_2x_2^i)-(1-y^{(i)})log(1-θ_0-θ_1x_1^i-θ_2x_2^i)]
​ 此處我們沿用Andrew Ng定義的代價函式。

4.對應的梯度下降函式

​ 採用批量梯度下降,對應的向量化為:
在這裡插入圖片描述

​ 對應的python程式碼為:

# 梯度下降函式
def gradient(theta, X, y):
    return (1 / len(X)) * X.T @ (sigmoid(theta, X) - y)

5.求解最優解

​ 因3中定義的代價函式如下,帶有負號,因此需要採用梯度下降法求解。
J ( θ ) = 1 M i = 1 m [ y ( i ) l o g ( θ 0 + θ 1 x 1 i + θ 2 x 2 i ) ( 1 y ( i ) ) l o g ( 1 θ 0 θ 1 x 1 i θ 2 x 2 i ) ] J(θ)=\frac{1}{M} \sum_{i=1}^{m}[-y^{(i)}log(θ_0+θ_1x_1^i+θ_2x_2^i)-(1-y^{(i)})log(1-θ_0-θ_1x_1^i-θ_2x_2^i)]