從零開始學機器學習——邏輯迴歸

努力的小雨發表於2024-09-30

首先給大家介紹一個很好用的學習地址:https://cloudstudio.net/columns

在之前的學習中,我們學習了直線線性迴歸與多項式迴歸,我們今天的主題則是邏輯迴歸,我記得在前面有講解過這兩個迴歸的區別,那麼今天我們主要看下邏輯迴歸有哪些特徵需要我們識別的。

邏輯迴歸

邏輯迴歸主要用於解決二元分類問題,幫助我們預測某個事件是否會發生,例如判斷某種糖果是否為巧克力、某種疾病是否具有傳染性,或者某位顧客是否會選擇特定的產品,使我們能夠將複雜的資料轉化為簡單的“是”或“否”的結果,適用於許多實際場景。這種通常是邏輯迴歸解決的問題。

與線性迴歸不同,邏輯迴歸專注於預測二元分類結果,而線性迴歸則旨在預測連續值。例如,線上性迴歸中,我們可以根據南瓜的起源、收穫時間以及其他相關特徵來預測其價格可能上漲的幅度。然而,這個預測並不是絕對確定的,因為它依賴於歷史資料的趨勢和模式。透過分析過往的價格變動及其影響因素,線性迴歸能夠提供一個合理的估計值

其他分類

當然,除了二元分類問題,邏輯迴歸還可以擴充套件到多元分類問題。在多元分類中,目標變數可以有多個可能的固定答案,而每個答案都是明確的、可識別的正確選項。

除了多元分類之外,還有一種特別的分類問題稱為有序分類問題。在有序分類中,我們不僅關注類別的存在與否,還需要對結果進行邏輯上的排序,這在某些情況下非常有用。

例如,假設我們想根據南瓜的大小將其分類為不同的等級,如“迷你”(mini)、“小”(sm)、“中等”(med)、“大”(lg)、“超大”(xl)和“特超大”(xxl)。在這種情況下,這些類別之間存在明確的順序關係。

image

這裡單獨說一下順序邏輯迴歸,它是一種廣義線性模型,它適用於因變數是有序分類的情況。簡單來說就是:設定多個閾值 \(( T_1, T_2, T_......, T_{k-1} )\),將連續變數 \(Y^*\)劃分為 k個類別。假設 Y 有 k個類別,那麼有序邏輯迴歸的模型可以表示為:

image

還不懂的話,可以舉個例子:例如,一位野外生物學家想研究蠑螈的生存時間,而且希望確定生存時間是否與區域和水中毒性水平相關。該生物學家將生存時間分為三個類別:小於 10 天、11 到 30 天和 30 天以上。由於響應是順序變數,因此該生物學家使用順序邏輯迴歸。

什麼是因變數和自變數

再簡單說一下,怕有人不明白(其實我也忘記了),因變數和自變數是統計學和迴歸分析中的兩個基本概念,常用於建立模型以理解變數之間的關係。

  • 自變數,也稱為預測變數或解釋變數,在迴歸分析中,自變數通常是輸入資料。通常使用X表明。
  • 因變數,也稱為響應變數,是研究者關注的結果變數,通常是受到自變數影響的變數。因變數的變化是研究的目標。通常使用Y表明。

仍然是線性的

為什麼說邏輯迴歸仍然是線性的呢?主要是因為邏輯迴歸實際上可以視為線性迴歸的一種擴充套件。儘管它的主要應用是進行類別預測,但其基礎模型仍然依賴於線性關係。但是如果線性相關性更好的話,仍然能提高模型的效果。

如果自變數與因變數之間存在強烈的線性關係,模型就能夠更有效地捕捉這種關係,從而顯著提高預測的準確性。當線性關係十分明確時,模型在擬合資料時能夠更精準地反映變數之間的聯絡,從而減少預測誤差。

當自變數與因變數之間存在明顯的線性關係時,模型能夠更清晰地劃分類別邊界。以二維空間為例,如果不同類別的資料點分佈在一條直線的兩側,線性模型便能夠更準確地識別並確定這條分隔線。

變數不必相關

線性迴歸通常要求自變數與因變數之間存在一定程度的線性關係,這是其有效性的基礎。當這種關係較強時,模型能夠更準確地預測因變數的值。此外,線性迴歸對自變數之間的相關性也非常敏感,特別是在面對多個相關自變數的情況下,可能會導致多重共線性問題的出現,從而影響模型的穩定性和解釋能力。我們之前講解的時候是有一張圖的,大家可以去看一下。

邏輯迴歸模型則表現出更大的靈活性,它允許自變數與因變數之間的關係不必是嚴格的線性關係。這意味著,自變數可以在不必具有強相關性的情況下,依然影響因變數的分類結果。這種靈活性使得邏輯迴歸能夠適應多種不同的資料分佈和類別邊界,捕捉到更復雜的模式和趨勢。比如下面這種圖:

image

開始練習

我們還使用之前的南瓜資料集進行模型訓練。為了確保資料的質量和可靠性,首先需要對資料集進行適當的清理。具體而言,我們會刪除所有空值,以避免缺失資料對模型訓練造成的不利影響。

此外,我們將僅選擇與我們的分析目標相關的一些特定列,以簡化資料集並提高模型的效率。

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder

pumpkins = pd.read_csv('../data/US-pumpkins.csv')
pumpkins.head()

new_columns = ['Color','Origin','Item Size','Variety','City Name','Package']
new_pumpkins = pumpkins.drop([c for c in pumpkins.columns if c not in new_columns], axis=1)
#刪除空值
new_pumpkins.dropna(inplace=True)
#字串型別的變數轉換為數值型變數
new_pumpkins = new_pumpkins.apply(LabelEncoder().fit_transform)

new_pumpkins.info

接下來,讓我們展示列印出來的資料,這樣大家就可以清晰地瞭解該資料集的具體內容和結構。

<bound method DataFrame.info of       City Name  Package  Variety  Origin  Item Size  Color
2             1        3        4       3          3      0
3             1        3        4      17          3      0
4             1        3        4       5          2      0
5             1        3        4       5          2      0
6             1        4        4       5          3      0
...         ...      ...      ...     ...        ...    ...
1694         12        3        5       4          6      1
1695         12        3        5       4          6      1
1696         12        3        5       4          6      1
1697         12        3        5       4          6      1
1698         12        3        5       4          6      1

[991 rows x 6 columns]>

視覺化

正如我們在學習線性迴歸時所做的那樣,我們透過熱力圖成功識別出了所有變數之間的相關性,並找到了相關性最高的兩個欄位。對於邏輯迴歸而言,我們同樣需要藉助一些工具和方法,而不是手動逐一檢查每個值。今天,我們將重點學習並列網格這一技術。

Seaborn 提供了一系列巧妙而強大的方法來視覺化資料,使得資料分析變得更加直觀和易於理解。例如,使用並列網格,我們可以清晰地比較每個點的資料分佈。

import seaborn as sns

g = sns.PairGrid(new_pumpkins)
g.map(sns.scatterplot)

PairGrid:這是 Seaborn 提供的一個工具,用於建立變數之間成對的散點圖矩陣。

map:這個方法用於將一個繪圖函式應用到 PairGrid 中的每一對變數上。

那麼最後呈現的結果就是這樣的:

image

這張圖片你能看出很多東西,就比如那兩個最特別的跟大家說一下:

自己對自己的時候是一條直線:因為每個資料點的值與其自身完全相等。也就是說,對於任意一個變數 X,它與自己的關係是完全線性的,形成一個斜率為 1 的對角線。

在散點圖中,Color 變數對其他變數(如 Origin, Item Size, Variety, City Name, Package)顯示出兩排散點:這是因為color是有限的分類值、一個分類變數(如“紅色”、“藍色”),每個顏色對應的資料點在散點圖中形成不同的組。這種情況下,不同顏色的值可能在其他變數上表現出明顯的差異。

使用小提琴圖

從上述分析中,我們可以得出結論,color 變數是一個二元類別,具體而言,它可以分為“橙色”或“非橙色”。這種型別的變數被稱為“分類資料”,因此需要採用更專業和有效的方法來進行視覺化。

此外,還有許多其他技術和工具可以用來展示該類別與其他變數之間的關係,例如箱線圖、條形圖和小提琴圖等。

sns.catplot(x="Color", y="Item Size",kind="violin", data=new_pumpkins)

image

沒了解過小提琴圖的,我來講解一下,下面是一張標準的小提琴圖:

image

小提琴圖 (Violin Plot) 用於顯示資料分佈及其機率密度。

小提琴圖可以是一種單次顯示多個資料分佈的有效且有吸引力的方式,但請記住,估計過程受樣本大小的影響,相對較小樣本的小提琴可能看起來非常平滑,這種平滑具有誤導性。如果還不懂的話,我們可以拿身高舉例。來看下比如南方、北方人的身高分佈是咋樣的(資料僅學習為主)

image

一眼是不是就可以看出來南方人普遍身高了,而北方的很平滑基本看不出什麼,所以只能依靠其他手段分析了,小提琴就不能用來分析了。

好的,到此結束,現在我們已經瞭解了顏色的二元類別與更大的尺寸組之間的關係,讓我們探索邏輯迴歸來確定給定南瓜的可能顏色。

數學知識點

還記得我們當時在學習線性規劃時那個最小二乘法嗎?來計算最佳的直接來讓所有資料散點達到直線距離最小。在邏輯迴歸同樣也有一個數學推理演算法叫做Sigmoid 函式看起來像“S”形。它接受一個值並將其對映到0和1之間的某個位置。它的曲線也稱為“邏輯曲線”。它的公式如下所示:

image

他的影像是這樣的:

image

其中 sigmoid 的中點位於 x 的 0 點,L 是曲線的最大值,k 是曲線的陡度。如果函式的結果大於 0.5,則所討論的標籤將被賦予二進位制選擇的類“1”。否則,它將被分類為“0”。

當然,現在可用的工具和手段非常豐富,我們完全不必親自進行復雜的計算,因為各種框架和庫已經為我們封裝好了這些功能。然而,理解背後的原理依然至關重要。

建立你的模型

和線性迴歸一樣,使用 Scikit-learn 來構建模型來查詢這些二元分類,首先第一步永遠是從整體資料中分割出來一些測試集和訓練集。

from sklearn.model_selection import train_test_split

Selected_features = ['Origin','Item Size','Variety','City Name','Package']

X = new_pumpkins[Selected_features]
y = new_pumpkins['Color']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

接著就是使用訓練集資料訓練我們的模型了

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report 
from sklearn.linear_model import LogisticRegression

model = LogisticRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)

print(classification_report(y_test, predictions))
print('Predicted labels: ', predictions)
print('Accuracy: ', accuracy_score(y_test, predictions))

我來解釋一下新出現的方法classification_report。

classification_report是 Scikit-learn 中用於評估分類模型效能的一個函式。它提供了一些關鍵指標,幫助你理解模型在測試集上的表現,你可以看到傳了兩個引數,一個是實際結果的y_test,另一個是我們訓練模型根據測試集推測出來的測試結果。拿來作比較。顯示結果如下:

              precision    recall  f1-score   support

           0       0.83      0.98      0.90       166
           1       0.00      0.00      0.00        33

    accuracy                           0.81       199
   macro avg       0.42      0.49      0.45       199
weighted avg       0.69      0.81      0.75       199

當然了有很多指標展示,我們來慢慢看下:

Precision(精確率): 哪些標籤標記得很好,舉個例子:模型標記了 10 張照片為貓,其中 7 張是真正的貓,3 張是狗。精確率 = 真正的貓 / (真正的貓 + 誤報的狗) = 7 / (7 + 3) = 0.7(70%)

Recall(召回率): 實際為正類的樣本中,預測為正類的比例。在舉例子:繼續用檢測貓的例子:你總共有 15 張真實的貓照片,模型只找到了 7 張。召回率 = 真正的貓 / (真正的貓 + 漏報的貓) = 7 / (7 + 8) = 7 / 15 ≈ 0.47(47%)

F1 Score: 精確率和召回率的調和平均,綜合考慮了精確率和召回率。最好為1,最差為0

Support: 每個類的真實樣本數量。

Accuracy(準確率): 正確預測的樣本佔總樣本的比例。不要和精確率弄混。舉個例子:假設你有 100 張照片,模型正確標記了 90 張(包括貓和狗)。準確率 = 90 / 100 = 0.9(90%),為什麼包括貓和狗?因為貓和狗是為了說明分類模型在處理多類問題時的表現。

雖然我們可以透過各種指標得分去看下理解模型,但是透過使用混淆矩陣可以更容易地理解你的模型,幫助我們瞭解模型的效能。

混淆矩陣

“混淆矩陣”(或“誤差矩陣”)是一個表格,用於表示模型的真假陽性和真假陰性,從而衡量預測的準確性。

在一個二分類問題中,混淆矩陣通常是這樣的:

預測正類 (Positive) 預測負類 (Negative)
實際正類 (Positive) True Positive (TP) False Negative (FN)
實際負類 (Negative) False Positive (FP) True Negative (TN)

看下程式碼結果:

from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, predictions)

array([[162, 4],
[ 33, 0]])

舉個例子,假設我們的模型被要求對兩個二元類別之間的專案進行分類,即類別“南瓜”和類別“非南瓜”。

  • 如果你的模型將某物預測為南瓜並且它實際上屬於“南瓜”類別,我們將其稱為真陽性,由左上角的數字顯示。
  • 如果你的模型預測某物不是南瓜,並且它實際上屬於“南瓜”類別,我們將其稱為假陽性,如右上角的數字所示。
  • 如果你的模型將某物預測為南瓜並且它實際上屬於“非南瓜”類別,我們將其稱為假陰性,由左下角的數字顯示。
  • 如果你的模型預測某物不是南瓜,並且它實際上屬於“非南瓜”類別,我們將其稱為真陰性,如右下角的數字所示。

只要我們的模型的真陽性和真陰性,這意味著模型效能更好。所以如果你想要減少假陽性,請注意關注下召回率指標。

ROC曲線

ROC曲線(接收器操作特徵曲線)用於評估二分類模型的效能,根據圖示我們可以快速的瞭解Y 軸上的真陽性率和 X 軸上的假陽性率,我們先看下程式碼結果吧。

from sklearn.metrics import roc_curve, roc_auc_score
import seaborn as sns

y_scores = model.predict_proba(X_test)
# calculate ROC curve
fpr, tpr, thresholds = roc_curve(y_test, y_scores[:,1])
sns.lineplot(x=[0, 1], y=[0, 1])
sns.lineplot(x=fpr, y=tpr)

image

理想曲線:理想情況下,曲線應該儘量靠近左上角,這表明模型在低假陽性率下能保持高真正率。

隨機猜測線:對角線(從(0,0)到(1,1))代表隨機猜測。如果模型的ROC曲線與此線重合,說明模型沒有區分能力。

曲線下面積(AUC)AUC值,ROC曲線下的面積,值在0到1之間:

  • AUC = 1:完美模型。
  • AUC = 0.5:模型沒有區分能力,相當於隨機猜測。
  • AUC < 0.5:模型的效能不如隨機猜測。

我們計算一下:

auc = roc_auc_score(y_test,y_scores[:,1])
print(auc)

0.6976998904709749

透過分析ROC曲線和AUC值,你可以更好地理解模型的分類效能,尤其是在面對不同的預測閾值時。

為什麼藉助這麼多視覺化工具?

其實每一個工具所反饋的作用都不一樣,混淆矩陣直觀展示預測結果,分類報告提供全面效能指標,ROC曲線幫助選擇最佳閾值和評估整體效能。目的就是更好的去理解模型。然後去改進模型。

當然了,我們本次迴歸只檢視模型現狀,並沒有根據結果進行最佳化,那是下面要講的了。這裡先不說了。

總結

在學習了邏輯迴歸的基本概念和應用後,我們可以看到,這種方法不僅能夠處理二元分類問題,還能擴充套件到多元分類和有序分類的場景。邏輯迴歸的靈活性使得我們能夠在不同的情況下找到合適的解決方案,不論是簡單的“是”或“否”判斷,還是更復雜的多級分類任務。

值得注意的是,邏輯迴歸仍然基於線性關係,但與傳統的線性迴歸相比,它的目標和應用場景顯著不同。這種方法透過機率模型,利用Sigmoid函式將連續變數對映到0到1之間,為我們提供了對結果的直觀理解。

此外,在資料處理和視覺化過程中,我們運用了多種工具,如並列網格、小提琴圖等,這些工具不僅幫助我們分析資料之間的關係,也增強了資料的直觀性和可理解性。透過這些視覺化手段,我們能夠清晰地識別出變數之間的聯絡和分類的邊界。

在實踐環節中,我們對資料進行了清洗和特徵選擇,並使用Scikit-learn構建了邏輯迴歸模型。透過混淆矩陣和ROC曲線等方法評估模型效能,使得我們能夠更深入地理解模型的準確性和預測能力。

在以後的分類課程中,我們將一起學習如何迭代以提高模型的分數。但是現在,完結撒花!我們已經完成了這些迴歸課程!


我是努力的小雨,一名 Java 服務端碼農,潛心研究著 AI 技術的奧秘。我熱愛技術交流與分享,對開源社群充滿熱情。同時也是一位騰訊雲創作之星、阿里雲專家博主、華為云云享專家、掘金優秀作者。

💡 我將不吝分享我在技術道路上的個人探索與經驗,希望能為你的學習與成長帶來一些啟發與幫助。

🌟 歡迎關注努力的小雨!🌟

相關文章