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

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

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

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

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

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

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

在梯度下降公式上方使用此表達式將變?yōu)椋?/p>

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

如果假設(shè)表達式的結(jié)果為1,則該表達式的結(jié)果將為零的對數(shù)。為了緩解這種情況,我最后使用了這個很小的數(shù)字。
步驟2:確定成本函數(shù)。
- 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))
這只是上面成本函數(shù)方程式的簡單實現(xiàn)。
步驟3:更新theta值。
Theta值需要不斷更新,直到成本函數(shù)達到最小值為止。我們應(yīng)該獲得最終的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:計算最終預(yù)測和準(zhǔn)確性
使用來自" gradient_descent"函數(shù)的theta值,并使用S型函數(shù)計算最終預(yù)測。然后,計算精度。
- 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
最終輸出是每個時期的成本清單和準(zhǔn)確性。讓我們實現(xiàn)此模型以解決實際問題。
數(shù)據(jù)預(yù)處理
我已經(jīng)在開始顯示了數(shù)據(jù)集。但是為了方便起見,我在這里再次添加了它:

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

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