> Photo by Alice Washington on Unsplash
使用實際資料集開發演算法
自上世紀以來,邏輯迴歸是一種流行的方法。它建立了分類變數和一個或多個自變數之間的關係。在機器學習中使用此關係來預測分類變數的結果。它被廣泛用於許多不同的領域,例如醫療領域,貿易和商業,技術等等。
本文介紹了二進位制分類演算法的開發過程,並將其在Kaggle的心臟病資料集上實現。
問題陳述在本文中,我們將使用來自Kaggle的資料集,其中包含人口的健康資料。它的末尾有一列,其中包含一個人是否患有心臟病。我們的目標是使用表格中的其他列檢視是否可以預測一個人是否患有心臟病。
在這裡,我將載入資料集。我將為此使用Pandas:
import pandas as pdimport numpy as npdf = 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。
成本函式
成本函式為您提供了預測輸出(計算的假設" 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項,並在開始處帶有負號。
我希望現在有道理!
梯度下降
我們需要更新隨機初始化的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 inlineimport matplotlib.pyplot as pltplt.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