KNN 演算法是一種根據距離的分類別和迴歸方法,其核心概念在於利用鄰近資料點的特性來預測新資料點的分類別或數值。在實際應用中,例如貸款違約預測,KNN 可以根據借款人的特徵,如債務收入比、信用餘額等,參考相似借款人的還款情況來預測新借款人的還款可能性。由於不同特徵的尺度差異可能影響模型的準確性,因此資料標準化是 KNN 的關鍵步驟。選擇合適的 K 值也至關重要,過小或過大的 K 值都可能影響模型的泛化能力。除了直接用於預測,KNN 還可以作為特徵工程的工具,例如根據借款人的特徵計算違約機率,並將其作為新的特徵新增到模型中,以提高預測準確性。此外,樹模型也是一種常用的分類別和迴歸方法,透過遞迴分割資料,將結果在每個最終細分中盡可能地均質化,可以有效地處理非線性關係。

機器學習與統計學的比較

在預測建模的背景下,機器學習和統計學之間的差異是什麼?兩者之間沒有明確的界限。機器學習更注重開發能夠擴充套件到大型資料的高效演算法,以最佳化預測模型。統計學通常更關注模型的機率理論和底層結構。Bagging和隨機森林(見“Bagging和隨機森林”第259頁)是在統計學領域發展起來的。Boosting(見“Boosting”第270頁)則在兩個領域都有所發展,但在機器學習領域受到更多關注。無論其歷史如何,Boosting的承諾確保了它將作為一種技術在統計學和機器學習領域蓬勃發展。

K-最近鄰(KNN)演算法

KNN背後的想法非常簡單。對於每個需要分類別或預測的記錄:

  1. 找到具有相似特徵(即相似預測值)的K個記錄。
  2. 對於分類別,找出這些相似記錄中的多數類別,並將該類別分配給新記錄。
  3. 對於預測(也稱為KNN迴歸),找出這些相似記錄的平均值,並預測新記錄的平均值。

KNN的關鍵術語

  • 鄰居:具有與另一記錄相似預測值的記錄。
  • 距離度量:用於匯總一條記錄與另一條記錄之間的距離的單一數字的度量。
  • 標準化:減去平均值並除以標準偏差。
  • 同義詞:正規化。
  • Z-分數:標準化後得到的值。
  • K:在最近鄰計算中考慮的鄰居數量。

KNN是較簡單的預測/分類別技術之一:不需要擬合模型(如迴歸)。這並不意味著使用KNN是一個自動化的過程。預測結果取決於特徵如何縮放、如何衡量相似性以及K的值。此外,所有預測變數必須是數值形式。

使用KNN進行貸款違約預測的小例子

表6-1顯示了來自LendingClub的個人貸款資料的幾個記錄。LendingClub是對等貸款的長官者,投資者池向個人提供個人貸款。分析的目標是預測新的潛在貸款的結果:已償還還是違約。

表6-1. LendingClub貸款資料的幾個記錄和欄位
結果貸款金額收入用途就業年限房屋所有權
已償還1000079100debt_consolidation11MORTGAGENV
已償還960048000moving5MORTGAGETN
已償還18800120036debt_consolidation11MORTGAGEMD
違約15250232000small_business9MORTGAGECA
已償還1705035000debt_consolidation4RENTMD
已償還550043000debt_consolidation4RENTKS

對於這個例子,我們將貸款資料集的第一行作為newloan,並將其從訓練資料集中排除。考慮一個非常簡單的模型,只有兩個預測變數:dti(債務付款(不包括抵押貸款)與收入的比率)和payment_inc_ratio(貸款付款與收入的比率)。兩個比率都乘以100。

使用具有已知二元結果(違約或未違約,在預測變數outcome200中指定)的小型貸款資料集loan200,並將K設定為20,可以使用R計算新的貸款newloan的KNN估計,其dti=22.5payment_inc_ratio=9

newloan <- loan200[1, 2:3, drop=FALSE]
knn_pred <- knn(train=loan200[-1, 2:3], test=newloan, cl=loan200[-1, 1], k=20)
knn_pred == 'paid off'
[1] TRUE

KNN預測的視覺化顯示

圖6-2給出了這個例子的視覺化顯示。要預測的新貸款是中間的十字。方塊(已償還)和圓圈(違約)是訓練資料。大的黑色圓圈顯示了最近20個點的邊界。在這種情況下,9個違約貸款位於圓圈內,而11個已償還貸款。因此,貸款的預測結果是已償還。

距離度量

相似性(接近度)是使用距離度量來確定的,距離度量是一種用於衡量一條記錄(x1,x2,…,xp)與另一條記錄(u1,u2,…,up)之間的距離的函式。兩個向量之間最流行的距離度量是歐幾裡得距離。要衡量兩個向量之間的歐幾裡得距離,請將一個向量減去另一個向量,對差異進行平方,求和,然後取平方根。

程式碼實作與解析

R語言實作KNN

# 載入必要的程式函式庫
library(FNN)

# 定義訓練資料和測試資料
train_data <- loan200[-1, 2:3]
test_data <- loan200[1, 2:3, drop=FALSE]

# 定義分類別結果
cl <- loan200[-1, 1]

# 設定K值
k <- 20

# 使用KNN進行預測
knn_pred <- knn(train=train_data, test=test_data, cl=cl, k=k)

# 檢視預測結果
print(knn_pred)

#### 內容解密:

  1. library(FNN):載入FNN程式函式庫,用於實作快速最近鄰搜尋。
  2. train_data <- loan200[-1, 2:3]:準備訓練資料,排除第一行並選取需要的欄位。
  3. test_data <- loan200[1, 2:3, drop=FALSE]:準備測試資料,即第一筆貸款資料。
  4. cl <- loan200[-1, 1]:準備分類別結果,即訓練資料的結果欄位。
  5. k <- 20:設定最近鄰的數量為20。
  6. knn_pred <- knn(train=train_data, test=test_data, cl=cl, k=k):使用KNN演算法進行預測。
  7. print(knn_pred):輸出預測結果。

Python語言實作KNN

# 載入必要的程式函式庫
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd

# 定義預測變數和結果變數
predictors = ['payment_inc_ratio', 'dti']
outcome = 'outcome'

# 定義新的貸款資料
newloan = loan200.loc[0:0, predictors]

# 定義訓練資料
X = loan200.loc[1:, predictors]
y = loan200.loc[1:, outcome]

# 建立KNN模型並進行訓練
knn = KNeighborsClassifier(n_neighbors=20)
knn.fit(X, y)

# 使用KNN進行預測
prediction = knn.predict(newloan)

# 檢視預測結果
print(prediction)

#### 內容解密:

  1. from sklearn.neighbors import KNeighborsClassifier:從scikit-learn程式函式庫中匯入KNeighborsClassifier類別,用於實作KNN演算法。
  2. predictors = ['payment_inc_ratio', 'dti']:定義用於預測的變數。
  3. outcome = 'outcome':定義結果變數。
  4. newloan = loan200.loc[0:0, predictors]:準備新的貸款資料用於預測。
  5. X = loan200.loc[1:, predictors]y = loan200.loc[1:, outcome]:準備訓練資料。
  6. knn = KNeighborsClassifier(n_neighbors=20):建立KNN模型,並設定最近鄰數量為20。
  7. knn.fit(X, y):使用訓練資料訓練KNN模型。
  8. prediction = knn.predict(newloan):使用訓練好的KNN模型進行預測。
  9. print(prediction):輸出預測結果。

距離度量在KNN中的應用

在KNN(K-近鄰)演算法中,距離度量是決定鄰居關係的關鍵因素。常見的距離度量方法包括歐幾裡得距離和曼哈頓距離。

歐幾裡得距離與曼哈頓距離

歐幾裡得距離是指兩個點之間的直線距離,而曼哈頓距離則是指在單一方向上行進的距離,例如在矩形城市區塊中行進的距離。曼哈頓距離在某些情況下是更好的選擇,例如當相似性被定義為點對點的旅行時間時。

歐幾裡得距離公式

歐幾裡得距離的計算公式為: $$ \sqrt{(x_1 - u_1)^2 + (x_2 - u_2)^2 + \cdots + (x_p - u_p)^2} $$

曼哈頓距離公式

曼哈頓距離的計算公式為: $$ |x_1 - u_1| + |x_2 - u_2| + \cdots + |x_p - u_p| $$

在衡量兩個向量之間的距離時,尺度較大的變數(特徵)將主導度量結果。例如,在貸款資料中,距離幾乎完全取決於收入和貸款金額這兩個變數。為瞭解決這個問題,需要對資料進行標準化處理。

其他距離度量方法

除了歐幾裡得距離和曼哈頓距離外,還有許多其他的距離度量方法。對於數值型資料,Mahalanobis距離是一種很有吸引力的方法,因為它考慮了兩個變數之間的相關性。

Mahalanobis距離的優缺點

Mahalanobis距離的優點在於它可以處理相關變數之間的距離問題,但缺點是計算複雜度較高,需要使用協方差矩陣進行計算。

獨熱編碼

貸款資料中包含許多因子(字串)變數,大多數統計和機器學習模型需要將這些變數轉換為一系列二元虛擬變數。獨熱編碼是一種常用的方法,它將一個因子變數轉換為一個向量,其中只有一個元素是1,其餘元素都是0。

獨熱編碼的例子

例如,將房屋所有權狀態轉換為四個二元變數:OWNS_WITH_MORTGAGE、OWNS_WITHOUT_MORTGAGE、OTHER和RENT。

OWNS_WITH_MORTGAGEOWNS_WITHOUT_MORTGAGEOTHERRENT
1000
1000
1000
1000
0001
0001

標準化(正規化,z-分數)

在測量中,我們往往更感興趣的是“與平均值的差異”而不是“多少”。標準化(正規化)透過減去平均值並除以標準差,將所有變數放在相同的尺度上。這樣可以確保某個變數不會因為其原始測量尺度而對模型產生過大的影響。

z-分數的計算公式

z-分數的計算公式為: $$ z = \frac{x - \bar{x}}{s} $$

KNN中的標準化

在KNN和其他一些程式中,標準化資料是非常重要的。未標準化的資料可能會導致某些變數主導鄰居的選擇,從而影響模型的準確性。

程式碼範例

from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

# 定義預測變數和目標變數
predictors = ['payment_inc_ratio', 'dti', 'revol_bal', 'revol_util']
outcome = 'outcome'

# 建立StandardScaler物件
scaler = StandardScaler()

# 對資料進行標準化
X_scaled = scaler.fit_transform(X)

# 建立KNN模型
knn = KNeighborsClassifier(n_neighbors=5)

# 對標準化後的資料進行KNN模型訓練
knn.fit(X_scaled, y)

內容解密:

  1. StandardScaler的使用StandardScalersklearn.preprocessing中的一個類別,用於對資料進行標準化處理。它透過減去平均值並除以標準差來將資料縮放到相同的尺度上。
  2. 資料標準化的重要性:在KNN等根據距離的演算法中,資料的尺度會對結果產生很大的影響。透過標準化,可以確保所有特徵都在相同的尺度上,避免某些特徵因尺度較大而主導鄰居的選擇。
  3. KNN模型的訓練:使用標準化後的資料對KNN模型進行訓練,可以提高模型的準確性和穩定性。

K-近鄰演算法(KNN)在資料標準化下的表現

K-近鄰演算法(KNN)是一種簡單且直觀的分類別方法,其效能高度依賴於特徵縮放(feature scaling)。在處理貸款資料(loan data)時,變數之間的尺度差異可能導致KNN演算法偏向於較大尺度的變數。

資料標準化對KNN的影響

使用R語言中的scale函式對貸款資料進行標準化處理,可以計算每個變數的z-score,從而使不同變數處於相同的尺度。這樣處理後,KNN演算法能夠更公平地對待每個變數。

loan_df <- model.matrix(~ -1 + payment_inc_ratio + dti + revol_bal + revol_util, data=loan_data)
loan_std <- scale(loan_df)
newloan_std <- loan_std[1, , drop=FALSE]
loan_std <- loan_std[-1,]
loan_df <- loan_df[-1,]
outcome <- loan_data[-1, 1]
knn_pred <- knn(train=loan_std, test=newloan_std, cl=outcome, k=5)
loan_df[attr(knn_pred, "nn.index"),]

內容解密:

  1. 使用model.matrix函式將貸款資料轉換為矩陣格式,並去除截距項。
  2. scale函式用於標準化資料,計算z-score,使資料具有零均值和單位方差。
  3. 將第一筆資料分離出來作為測試資料,其餘資料用於訓練KNN模型。
  4. knn函式執行KNN分類別,設定k=5,即選擇5個最近鄰。
  5. 輸出最近鄰的資料記錄。

Python中的實作

在Python中,可以使用sklearn.preprocessing.StandardScaler來實作資料標準化。

newloan = loan_data.loc[0:0, predictors]
X = loan_data.loc[1:, predictors]
y = loan_data.loc[1:, outcome]
scaler = preprocessing.StandardScaler()
scaler.fit(X * 1.0)
X_std = scaler.transform(X * 1.0)
newloan_std = scaler.transform(newloan * 1.0)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_std, y)
nbrs = knn.kneighbors(newloan_std)
X.iloc[nbrs[1][0], :]

內容解密:

  1. 分離出第一筆資料作為測試資料,其餘資料用於訓練。
  2. 使用StandardScaler對訓練資料進行標準化處理,並將其套用到測試資料上。
  3. 建立KNN分類別器,設定n_neighbors=5
  4. 使用標準化後的訓練資料訓練KNN模型。
  5. 找出測試資料的5個最近鄰,並輸出對應的原始資料記錄。

K值的選擇

選擇合適的K值對於KNN的效能至關重要。K值太小可能導致過擬合,而K值太大則可能導致過度平滑。通常透過驗證資料集的準確率來確定最佳的K值。一般而言,K值的範圍在1到20之間,並且通常選擇奇數以避免平局。

偏差-變異數權衡

KNN中的過擬合和過度平滑問題是偏差-變異數權衡的典型例子。增加K值可以減少變異數,但可能增加偏差。反之亦然。這種權衡可以透過交叉驗證來處理。

KNN作為特徵引擎

KNN可以用於產生新的特徵,新增到原始資料中,然後與其他分類別方法結合使用。這種方法可以視為整合學習或特徵工程的一種形式,能夠提高模型的預測能力。

K-Nearest Neighbors(KNN)演算法在統計機器學習中的應用

K-Nearest Neighbors(KNN)是一種簡單卻強大的機器學習演算法,用於分類別和迴歸問題。它的基本思想是根據相似的鄰居對新記錄進行分類別或預測數值。在本文中,我們將探討KNN在統計機器學習中的應用,及其與其他方法的比較。

KNN的基本原理

KNN的核心思想是透過計算新記錄與訓練資料中其他記錄之間的距離,找出最相似的K個鄰居,然後根據這些鄰居的類別或數值進行預測。常用的距離度量方法包括歐幾裡得距離等。

KNN的運作流程

  1. 選擇K值:決定要參考的鄰居數量。
  2. 計算距離:使用選定的距離度量方法計算新記錄與所有訓練資料之間的距離。
  3. 找出K個最近鄰居:根據計算出的距離,找出最接近的K個鄰居。
  4. 進行預測:對於分類別問題,採用多數投票法;對於迴歸問題,計算K個鄰居的平均值。

KNN在實際應用中的範例

房地產估價

房地產經紀人在估價房屋時,會參考最近銷售的相似房屋(稱為“comps”)。這本質上是一種手動的KNN方法。透過觀察相似房屋的銷售價格,可以估計出一棟房屋的售價。我們可以建立一個新的特徵,透過應用KNN到最近的銷售資料,來模擬房地產專業人士的做法。

from sklearn.neighbors import KNeighborsClassifier
import pandas as pd

# 假設loan_data是一個包含貸款資料的DataFrame
predictors = ['dti', 'revol_bal', 'revol_util', 'open_acc', 'delinq_2yrs_zero', 'pub_rec_zero']
outcome = 'outcome'
X = loan_data[predictors]
y = loan_data[outcome]

knn = KNeighborsClassifier(n_neighbors=20)
knn.fit(X, y)
loan_data['borrower_score'] = knn.predict_proba(X)[:, 1]

#### 內容解密:

  • predictors列出了用於預測的特徵變數,包括債務收入比(dti)、迴圈信用餘額(revol_bal)等。
  • outcome是目標變數,表示貸款結果。
  • 使用KNeighborsClassifier建立KNN模型,並設定n_neighbors=20,表示參考20個最近鄰居。
  • knn.fit(X, y)對模型進行訓練。
  • knn.predict_proba(X)[:, 1]計算每個借款人違約的機率,並將其作為新的特徵borrower_score新增到資料中。

樹模型(Tree Models)

樹模型,也稱為分類別和迴歸樹(CART),是一種有效的分類別和迴歸方法。它透過遞迴分割資料,將結果在每個最終細分中盡可能地均質化。

樹模型的基本概念

  • 遞迴分割:重複地劃分和再劃分資料,以使結果在每個最終細分中盡可能地均質。
  • 分割值:一個預測變數的值,將記錄分為小於和大於該值的兩部分。
  • 節點:在決策樹中,表示一個分割值。
  • 葉節點:決策樹的末端,表示一條分類別規則。

簡單範例

library(rpart)
loan_tree <- rpart(outcome ~ borrower_score + payment_inc_ratio, data=loan3000, control=rpart.control(cp=0.005))
plot(loan_tree, uniform=TRUE, margin=0.05)
text(loan_tree)
from sklearn.tree import DecisionTreeClassifier
from dmba import plotDecisionTree

predictors = ['borrower_score', 'payment_inc_ratio']
outcome = 'outcome'
X = loan3000[predictors]
y = loan3000[outcome]

loan_tree = DecisionTreeClassifier(random_state=1, criterion='entropy', min_impurity_decrease=0.003)
loan_tree.fit(X, y)
plotDecisionTree(loan_tree, feature_names=predictors, class_names=loan_tree.classes_)

#### 內容解密:

  • 使用rpart套件在R中擬合樹模型,或使用DecisionTreeClassifier在Python中擬合。
  • loan_tree表示擬合的樹模型,用於預測貸款結果。
  • plotDecisionTree函式用於視覺化決策樹。