免費Python機器學習課程四:邏輯回歸算法
自上世紀以來,邏輯回歸是一種流行的方法。它建立了分類變量和一個或多個自變量之間的關系。在機器學習中使用此關系來預測分類變量的結果。它被廣泛用于許多不同的領域,例如醫療領域,貿易和商業,技術等等。
本文介紹了二進制分類算法的開發過程,并將其在Kaggle的心臟病數據集上實現。
問題陳述
在本文中,我們將使用來自Kaggle的數據集,其中包含人口的健康數據。它的末尾有一列,其中包含一個人是否患有心臟病。我們的目標是使用表格中的其他列查看是否可以預測一個人是否患有心臟病。
在這里,我將加載數據集。我將為此使用Pandas:
- import pandas as pd
- import numpy as np
- df = pd.read_csv('Heart.csv')
- df.head()
數據集如下所示:
> Top five rows of the Haert.csv dataset
查看數據集的最后一列。是" AHD"。這表示心臟病。我們將使用其余的列來預測心臟病。因此,將來,如果我們擁有所有數據,則無需進行醫療檢查就可以預測一個人是否患有心臟病。
我們的輸出將為0或1。如果一個人患有心臟病,我們的算法將返回1;如果一個人沒有心臟病,該算法應返回0。
重要方程
記住線性回歸公式。直線的非常基本的公式:Y = A + BX
其中A是截距,B是斜率。如果在此方程式中避免使用"攔截" A,則公式將變為:Y = BX
傳統上,在機器學習中,它被壓為

在這里," h"是假設或預測值,而X是預測變量或輸入變量。Theta從一開始就隨機初始化,之后再進行更新。
對于logistic回歸,我們需要使用Sigmoid函數(返回值從0到1)轉換此簡單假設。Sigmoid函數也可以稱為logistic函數。Logistic回歸使用S形函數來預測輸出。這是S形激活函數:

z是輸入特征乘以隨機初始化的項theta。

在此,X是輸入特征,theta是將在此算法中更新的隨機初始化值。
我們需要使用邏輯函數的原因是,邏輯函數的曲線如下所示:
> Image by Author
從上圖可以看到,它返回0到1之間的值。因此,這對于分類非常有幫助。由于我們今天將進行二進制分類,
如果邏輯函數返回的值小于0.5,則返回零;如果邏輯函數返回的值大于或等于0.5,則返回1。
(1) 成本函數
成本函數為您提供了預測輸出(計算的假設" h")與原始輸出(數據集中的" AHD"列)相差多少的度量。
在深入探討邏輯回歸的成本函數之前,我想提醒您線性回歸的成本函數要簡單得多。線性回歸的成本為:

哪里,
y是原始標簽(數據集的" AND"列)
平均成本函數為:

哪里,m是訓練數據的數量
上面的等式首先考慮了預測標簽" h"和原始標簽" y"之間的差異。該公式包括平方以避免任何負值,并使用1/2優化該平方。
這個簡單明了的方程式適用于線性回歸,因為線性回歸使用一個簡單的線性方程式:(Y = A + BX)。
但是邏輯回歸使用不是線性的S型函數。
我們不能在這里使用該簡單的成本函數,因為它不會收斂到全局最小值。為了解決此問題,我們將使用日志對成本函數進行正則化,使其收斂到全局最小值。
這是我們用來保證全局最小值的成本函數:
- 如果y = 1,成本(h,y)= -log(h)
- 如果y = 0,Cost(h,y)= -log(1 — h)
簡化組合成本函數:
這是成本函數表達式:

為什么這樣的方程式?看,我們只能有兩種情況y = 0或1。在上面的成本函數方程中,我們有兩個條件:
- y * logh和
- (1-y)* log(1-h)。
如果y = 0,則第一項變為零,第二項變為log(1-h)。在等式中,我們已經在開頭放置了一個負號。
如果y = 1,則第二項變為零,僅保留ylogh項,并在開始處帶有負號。
我希望現在有道理!
(2) 梯度下降
我們需要更新隨機初始化的theta值。梯度下降方程式就是這樣做的。如果我們將成本函數與theta進行偏微分:

在梯度下降公式上方使用此表達式將變為:

在這里,alpha是學習率。
使用該方程式,θ值將在每次迭代中更新。當您將在python中實現Thin時,對您來說會更加清楚。
現在是時候使用以上所有方程式來開發算法了
模型開發
步驟1:建立假設。
該假設只是S形函數的實現。
- def hypothesis(X, theta):
- z = np.dot(theta, X.T)
- return 1/(1+np.exp(-(z))) - 0.0000001
由于成本函數中的此表達式,我從此處的輸出中扣除了0.0000001:

如果假設表達式的結果為1,則該表達式的結果將為零的對數。為了緩解這種情況,我最后使用了這個很小的數字。
步驟2:確定成本函數。
- def cost(X, y, theta):
- y1 = hypothesis(X, theta)
- return -(1/len(X)) * np.sum(y*np.log(y1) + (1-y)*np.log(1-y1))
這只是上面成本函數方程式的簡單實現。
步驟3:更新theta值。
Theta值需要不斷更新,直到成本函數達到最小值為止。我們應該獲得最終的theta值和每次迭代的成本作為輸出。
- def gradient_descent(X, y, theta, alpha, epochs):
- m =len(X)
- J = [cost(X, y, theta)]
- for i in range(0, epochs):
- h = hypothesis(X, theta)
- for i in range(0, len(X.columns)):
- theta[i] -= (alpha/m) * np.sum((h-y)*X.iloc[:, i])
- J.append(cost(X, y, theta))
- return J, theta
步驟4:計算最終預測和準確性
使用來自" gradient_descent"函數的theta值,并使用S型函數計算最終預測。然后,計算精度。
- def predict(X, y, theta, alpha, epochs):
- J, th = gradient_descent(X, y, theta, alpha, epochs)
- h = hypothesis(X, theta)
- for i in range(len(h)):
- h[i]=1 if h[i]>=0.5 else 0
- y = list(y)
- acc = np.sum([y[i] == h[i] for i in range(len(y))])/len(y)
- return J, acc
最終輸出是每個時期的成本清單和準確性。讓我們實現此模型以解決實際問題。
數據預處理
我已經在開始顯示了數據集。但是為了方便起見,我在這里再次添加了它:

注意,數據集中有一些分類特征。我們需要將它們轉換為數值數據。
- df["ChestPainx"]= df.ChestPain.replace({"typical": 1, "asymptomatic": 2, "nonanginal": 3, "nontypical": 4})
- df["Thalx"] = df.Thal.replace({"fixed": 1, "normal":2, "reversable":3})
- df["AHD"] = df.AHD.replace({"Yes": 1, "No":0})
為偏差增加一列。這應該是一列,因為任何實數乘以1都會保持不變。
- df = pd.concat([pd.Series(1, index = df.index, name = '00'), df], axis=1)
定義輸入要素和輸出變量。輸出列是我們要預測的類別列。輸入特征將是除我們之前修改的分類列以外的所有列。
- X = df.drop(columns=["Unnamed: 0", "ChestPain", "Thal"])
- y= df["AHD"]
獲取精度結果
最后,初始化列表中的theta值并預測結果并計算精度。在這里,我正在初始化theta值,例如0.5。可以將其初始化為其他任何值。由于每個要素應具有對應的theta值,因此應為X中的每個要素(包括偏置列)初始化一個theta值。
- theta = [0.5]*len(X.columns)
- J, acc = predict(X, y, theta, 0.0001, 25000)
最終精度為84.85%。我使用0.0001作為學習率,并進行25000次迭代。
我運行了幾次該算法來確定這一點。
請檢查下面提供的該項目的我的GitHub鏈接。
"預測"功能還會返回每次迭代的費用列表。在一個好的算法中,每次迭代的成本應不斷降低。繪制每次迭代的成本以可視化趨勢。
- %matplotlib inline
- import matplotlib.pyplot as plt
- plt.figure(figsize = (12, 8))
- plt.scatter(range(0, len(J)), J)
- plt.show()

成本從一開始就迅速下降,然后下降速度放慢。這是完美成本函數的行為!
結論
我希望這可以幫到你。如果您是初學者,那么一開始就很難掌握所有概念。但是我建議您自己在筆記本中運行所有代碼,并仔細觀察輸出。這將非常有幫助。這種類型的邏輯回歸有助于解決許多現實世界中的問題。希望您會用它來開發一些很棒的項目!
如果您在運行任何代碼時遇到問題,請在評論部分讓我知道。
在這里,您將找到完整的代碼:
https://github.com/rashida048/Machine-Learning-With-Python/blob/master/LogisticRegressionWithHeartDataset.ipynb