文章目錄
- 一、支持向量機概述
- 什么是支持向量機?
- 超平面和支持向量
- 大邊距直覺
- 二、數據預處理與可視化
- 數據集的基本信息
- 導入必要的庫
- 加載數據集
- 數據概況
- 數據可視化
- 特征對的散點圖矩陣
- 類別分布條形圖
- 平均面積與平均光滑度的散點圖
- 變量之間的相關性熱圖
- 三、模型訓練(問題解決)
- 數據準備與預處理
- 評估模型性能
- 支持向量機(SVM)
- 線性核 SVM
- 多項式核 SVM
- 徑向基函數(RBF)核 SVM
- 總結
- 四、SVM 數據準備
- 模型訓練與評估
- 多項式核 SVM
- 徑向基函數(Radial Basis Function)核 SVM
- 支持向量機超參數調優
- 五、主成分分析
- PCA 簡介
- PCA 可視化
- 解釋組件
- 支持向量機(SVM)模型的參數調整
- 六、總結
支持向量機 (SVM) 是一種功能強大且用途廣泛的機器學習模型,適用于線性和非線性分類、回歸以及異常值檢測。本文將介紹支持向量機算法及其在 scikit-learn 中的實現,并簡要探討主成分分析及其在 scikit-learn 中的應用。
一、支持向量機概述
支持向量機(SVM)是一種在機器學習領域廣泛使用的算法,以其在較少計算資源下提供顯著準確性的特點而受到青睞。SVM 可用于分類和回歸任務,但在分類問題中應用最為廣泛。
什么是支持向量機?
支持向量機的目標是在 N N N 維空間( N N N 為特征數)中找到一個能夠明確區分數據點的超平面。該超平面使得不同類別的數據點被分開,并且盡可能遠離超平面,從而確保分類的穩健性。
為了實現數據點的有效分離,可能存在多個超平面。我們的目標是選擇一個具有最大邊距的超平面,即兩個類別之間的最大距離。最大化邊距有助于提高分類的準確性。
超平面和支持向量
超平面是劃分數據點的決策邊界。位于超平面兩側的數據點可以被分為不同的類別。超平面的維度取決于特征的數量:如果輸入特征為 2,則超平面是直線;如果特征為 3,則超平面是二維平面。當特征數量超過 3 時,超平面變得難以直觀理解。
支持向量是指那些離超平面最近的點,這些點影響了超平面的位置和方向。通過這些支持向量,我們可以最大化分類器的邊距。刪除支持向量會改變超平面的位置,因此它們對構建 SVM 至關重要。
大邊距直覺
在邏輯回歸中,我們使用 S 型函數將線性函數的輸出值壓縮到 [0,1] 范圍內,并根據閾值(0.5)分配標簽。而在 SVM 中,我們使用線性函數的輸出值來決定分類:如果輸出大于 1,則屬于一個類;如果輸出為 -1,則屬于另一個類。SVM 通過將輸出值的閾值設為 1 和 -1,形成了邊際范圍 [-1,1]。
二、數據預處理與可視化
使用支持向量機來預測癌癥診斷的良惡性。
數據集的基本信息
- 特征數為30個,例如:
- 半徑(從中心到周長點的距離平均值)
- 紋理(灰度值的標準偏差)
- 周長
- 面積
- 平滑度(半徑長度的局部變化)
- 緊湊度(周長^2 / 面積 - 1.0)
- 凹度(輪廓凹陷部分的嚴重程度)
- 凹點(輪廓凹陷部分的數量)
- 對稱性
- 分形維數(“海岸線近似” - 1)
- 數據集包含 569 個樣本,類別分布為 212 個惡性樣本和 357 個良性樣本。
- 目標類別:
- 惡性
- 良性
導入必要的庫
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns%matplotlib inline
sns.set_style('whitegrid')
加載數據集
from sklearn.datasets import load_breast_cancercancer = load_breast_cancer()# 創建 DataFrame
col_names = list(cancer.feature_names)
col_names.append('target')
df = pd.DataFrame(np.c_[cancer.data, cancer.target], columns=col_names)
df.head()
數據概況
df.info()print(cancer.target_names)
# ['malignant', 'benign']# 數據描述:
df.describe()
# 統計摘要:
df.info()
數據可視化
特征對的散點圖矩陣
sns.pairplot(df, hue='target', vars=['mean radius', 'mean texture', 'mean perimeter', 'mean area','mean smoothness', 'mean compactness', 'mean concavity','mean concave points', 'mean symmetry', 'mean fractal dimension'
])
類別分布條形圖
sns.countplot(x=df['target'], label="Count")
平均面積與平均光滑度的散點圖
plt.figure(figsize=(10, 8))
sns.scatterplot(x='mean area', y='mean smoothness', hue='target', data=df)
變量之間的相關性熱圖
plt.figure(figsize=(20,10))
sns.heatmap(df.corr(), annot=True)
三、模型訓練(問題解決)
在機器學習中,模型訓練是尋找問題解決方案的關鍵步驟。下面我們將介紹如何使用 scikit-learn
進行模型訓練,并展示支持向量機(SVM)在不同內核下的性能表現。
數據準備與預處理
首先,我們需要準備和預處理數據。以下是數據預處理的代碼示例:
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, MinMaxScalerX = df.drop('target', axis=1)
y = df.targetprint(f"'X' shape: {X.shape}")
print(f"'y' shape: {y.shape}")
# 'X' shape: (569, 30)
# 'y' shape: (569,)pipeline = Pipeline([('min_max_scaler', MinMaxScaler()),('std_scaler', StandardScaler())
])X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
在代碼中,我們使用 MinMaxScaler
和 StandardScaler
對數據進行縮放。數據被分為訓練集和測試集,其中 30% 的數據用于測試。
評估模型性能
為了評估模型的性能,我們定義了一個 print_score
函數,該函數可以輸出訓練和測試結果的準確率、分類報告和混淆矩陣:
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import pandas as pddef print_score(clf, X_train, y_train, X_test, y_test, train=True):if train:pred = clf.predict(X_train)clf_report = pd.DataFrame(classification_report(y_train, pred, output_dict=True))print("Train Result:\n================================================")print(f"Accuracy Score: {accuracy_score(y_train, pred) * 100:.2f}%")print("_______________________________________________")print(f"CLASSIFICATION REPORT:\n{clf_report}")print("_______________________________________________")print(f"Confusion Matrix: \n {confusion_matrix(y_train, pred)}\n")else:pred = clf.predict(X_test)clf_report = pd.DataFrame(classification_report(y_test, pred, output_dict=True))print("Test Result:\n================================================") print(f"Accuracy Score: {accuracy_score(y_test, pred) * 100:.2f}%")print("_______________________________________________")print(f"CLASSIFICATION REPORT:\n{clf_report}")print("_______________________________________________")print(f"Confusion Matrix: \n {confusion_matrix(y_test, pred)}\n")
支持向量機(SVM)
支持向量機(SVM)是一種強大的分類算法,其性能受超參數的影響。下面將介紹 SVM 的主要參數及其對模型性能的影響:
- C 參數:控制正確分類訓練點和擁有平滑決策邊界之間的權衡。較小的 C C C(寬松)使誤分類成本(懲罰)較低(軟邊距),而較大的 C C C(嚴格)使誤分類成本較高(硬邊距),迫使模型更嚴格地解釋輸入數據。
- gamma 參數:控制單個訓練集的影響范圍。較大的 γ \gamma γ 使影響范圍較近(較近的數據點具有較高的權重),較小的 γ \gamma γ 使影響范圍較廣(更廣泛的解決方案)。
- degree 參數:多項式核函數(
'poly'
)的度,被其他內核忽略。可以通過網格搜索來找到最佳超參數值。
線性核 SVM
線性核 SVM 適用于大多數情況,特別是當數據集具有大量特征時。以下是使用線性核 SVM 的代碼示例:
from sklearn.svm import LinearSVCmodel = LinearSVC(loss='hinge', dual=True)
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練和測試結果如下:
訓練結果:
Accuracy Score: 86.18%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 1.000000 0.819079 0.861809 0.909539 0.886811
recall 0.630872 1.000000 0.861809 0.815436 0.861809
f1-score 0.773663 0.900542 0.861809 0.837103 0.853042
support 149.000000 249.000000 0.861809 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[ 94 55][ 0 249]]
測試結果:
Accuracy Score: 89.47%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 1.000000 0.857143 0.894737 0.928571 0.909774
recall 0.714286 1.000000 0.894737 0.857143 0.894737
f1-score 0.833333 0.923077 0.894737 0.878205 0.890013
support 63.000000 108.000000 0.894737 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 45 18][ 0 108]]
多項式核 SVM
多項式核 SVM 適用于非線性數據。以下是使用二階多項式核的代碼示例:
from sklearn.svm import SVCmodel = SVC(kernel='poly', degree=2, gamma='auto', coef0=1, C=5)
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練和測試結果如下:
訓練結果:
Accuracy Score: 96.98%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.985816 0.961089 0.969849 0.973453 0.970346
recall 0.932886 0.991968 0.969849 0.962427 0.969849
f1-score 0.958621 0.976285 0.969849 0.967453 0.969672
support 149.000000 249.000000 0.969849 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[139 10][ 2 247]]
測試結果:
Accuracy Score: 97.08%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.967742 0.972477 0.97076 0.970109 0.970733
recall 0.952381 0.981481 0.97076 0.966931 0.970760
f1-score 0.960000 0.976959 0.97076 0.968479 0.970711
support 63.000000 108.000000 0.97076 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 60 3][ 2 106]]
徑向基函數(RBF)核 SVM
徑向基函數(RBF)核適用于處理非線性數據。以下是使用 RBF 核的代碼示例:
model = SVC(kernel='rbf', gamma=0.5, C=0.1)
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練和測試結果如下:
訓練結果:
Accuracy Score: 62.56%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.0 0.625628 0.625628 0.312814 0.392314
recall 0.0 1.000000 0.625628 0.500000 0.625628
f1-score 0.0 0.769231 0.625628 0.384615 0.615385
support 149.0 249.0 0.625628 398.0 398.0
_______________________________________________
Confusion Matrix: [[ 0 149][ 0 249]]
測試結果:
Accuracy Score: 64.97%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.0 0.655172 0.649661 0.327586 0.409551
recall 0.0 1.000000 0.649661 0.500000 0.649661
f1-score 0.0 0.792453 0.649661 0.396226 0.628252
support 63.0 108.0 0.649661 171.0 171.0
_______________________________________________
Confusion Matrix: [[ 0 63][ 0 108]]
總結
通過以上模型訓練和評估過程,我們可以觀察到不同 SVM 內核的性能差異。線性核 SVM 在準確性和訓練時間上表現良好,適用于數據維度較高的情況。多項式核 SVM 和 RBF 核 SVM 在非線性數據上具有更好的表現,但在某些參數設置下可能會導致過擬合。選擇合適的內核和超參數對于模型性能的提升至關重要。
四、SVM 數據準備
數字輸入:SVM 假設輸入數據為數字。如果輸入數據為分類變量,可能需要將其轉換為二進制虛擬變量(每個類別一個變量)。
二元分類:基本的 SVM 適用于二元分類問題。雖然 SVM 主要用于二元分類,但也有擴展版本用于回歸和多類分類。
X_train = pipeline.fit_transform(X_train)
X_test = pipeline.transform(X_test)
模型訓練與評估
以下展示了不同 SVM 內核的訓練和測試結果:
線性核 SVM
print("=======================Linear Kernel SVM==========================")
model = SVC(kernel='linear')
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練結果:
Accuracy Score: 98.99%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 1.000000 0.984190 0.98995 0.992095 0.990109
recall 0.973154 1.000000 0.98995 0.986577 0.989950
f1-score 0.986395 0.992032 0.98995 0.989213 0.989921
support 149.000000 249.000000 0.98995 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[145 4][ 0 249]]測試結果Accuracy Score: 97.66%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.968254 0.981481 0.976608 0.974868 0.976608
recall 0.968254 0.981481 0.976608 0.974868 0.976608
f1-score 0.968254 0.981481 0.976608 0.974868 0.976608
support 63.000000 108.000000 0.976608 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 61 2][ 2 106]]
多項式核 SVM
print("=======================Polynomial Kernel SVM==========================")
from sklearn.svm import SVCmodel = SVC(kernel='poly', degree=2, gamma='auto')
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練結果:
Accuracy Score: 85.18%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.978723 0.812500 0.851759 0.895612 0.874729
recall 0.617450 0.991968 0.851759 0.804709 0.851759
f1-score 0.757202 0.893309 0.851759 0.825255 0.842354
support 149.000000 249.000000 0.851759 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[ 92 57][ 2 247]]測試結果:Accuracy Score: 82.46%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.923077 0.795455 0.824561 0.859266 0.842473
recall 0.571429 0.972222 0.824561 0.771825 0.824561
f1-score 0.705882 0.875000 0.824561 0.790441 0.812693
support 63.000000 108.000000 0.824561 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 36 27][ 3 105]]
徑向基函數(Radial Basis Function)核 SVM
print("=======================Radial Kernel SVM==========================")
from sklearn.svm import SVCmodel = SVC(kernel='rbf', gamma=1)
model.fit(X_train, y_train)print_score(model, X_train, y_train, X_test, y_test, train=True)
print_score(model, X_train, y_train, X_test, y_test, train=False)
訓練結果:
Accuracy Score: 100.00%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 1.0 1.0 1.0 1.0 1.0
recall 1.0 1.0 1.0 1.0 1.0
f1-score 1.0 1.0 1.0 1.0 1.0
support 149.0 249.0 1.0 398.0 398.0
_______________________________________________
Confusion Matrix: [[149 0][ 0 249]]測試結果:Accuracy Score: 63.74%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 1.000000 0.635294 0.637427 0.817647 0.769659
recall 0.015873 1.000000 0.637427 0.507937 0.637427
f1-score 0.031250 0.776978 0.637427 0.404114 0.502236
support 63.000000 108.000000 0.637427 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 1 62][ 0 108]]
支持向量機超參數調優
from sklearn.model_selection import GridSearchCVparam_grid = {'C': [0.01, 0.1, 0.5, 1, 10, 100], 'gamma': [1, 0.75, 0.5, 0.25, 0.1, 0.01, 0.001], 'kernel': ['rbf', 'poly', 'linear']} grid = GridSearchCV(SVC(), param_grid, refit=True, verbose=1, cv=5)
grid.fit(X_train, y_train)best_params = grid.best_params_
print(f"Best params: {best_params}")svm_clf = SVC(**best_params)
svm_clf.fit(X_train, y_train)
print_score(svm_clf, X_train, y_train, X_test, y_test, train=True)
print_score(svm_clf, X_train, y_train, X_test, y_test, train=False)
訓練結果:
Accuracy Score: 98.24%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.986301 0.980159 0.982412 0.983230 0.982458
recall 0.966443 0.991968 0.982412 0.979205 0.982412
f1-score 0.976271 0.986028 0.982412 0.981150 0.982375
support 149.000000 249.000000 0.982412 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[144 5][ 2 247]]測試結果:Accuracy Score: 98.25%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.983871 0.981651 0.982456 0.982761 0.982469
recall 0.968254 0.990741 0.982456 0.979497 0.982456
f1-score 0.976000 0.986175 0.982456 0.981088 0.982426
support 63.000000 108.000000 0.982456 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 61 2][ 1 107]]
五、主成分分析
PCA 簡介
主成分分析(PCA)是一種通過將數據投影到較低維空間來實現線性降維的技術,具體步驟如下:
- 使用奇異值分解:通過奇異值分解將數據投影到低維空間。
- 無監督學習:PCA 不需要標記數據來進行降維。
- 特征轉換:嘗試找出哪些特征可以解釋數據中的最大差異。
PCA 可視化
由于高維數據難以直接可視化,我們可以使用 PCA 找到前兩個主成分,并在二維空間中可視化數據。為了實現這一點,需要先對數據進行標準化,使每個特征的方差為單位方差。
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt# 數據標準化
scaler = StandardScaler()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)# PCA 降維
pca = PCA(n_components=2)
X_train = pca.fit_transform(X_train)
X_test = pca.transform(X_test)# 可視化前兩個主成分
plt.figure(figsize=(8,6))
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap='plasma')
plt.xlabel('First Principal Component')
plt.ylabel('Second Principal Component')
plt.show()
通過前兩個主成分,我們可以在二維空間中輕松分離不同類別的數據點。
解釋組件
降維雖然強大,但組件的含義較難直接理解。每個組件對應于原始特征的組合,這些組件可以通過擬合 PCA 對象獲得。
組件的相關屬性包括:
- 成分得分:變換后的變量值。
- 載荷(權重):特征的組合權重。
- 數據壓縮和信息保存:通過 PCA 實現數據的壓縮同時保留關鍵信息。
- 噪聲過濾:降維過程中可以過濾掉噪聲。
- 特征提取和工程:用于提取和構造新的特征。
支持向量機(SVM)模型的參數調整
在使用支持向量機(SVM)進行模型訓練時,我們需要調整超參數以獲得最佳模型。以下是使用網格搜索(GridSearchCV)調整 SVM 參數的示例代碼:
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV# 定義參數網格
param_grid = {'C': [0.01, 0.1, 0.5, 1, 10, 100], 'gamma': [1, 0.75, 0.5, 0.25, 0.1, 0.01, 0.001], 'kernel': ['rbf', 'poly', 'linear']} # 網格搜索
grid = GridSearchCV(SVC(), param_grid, refit=True, verbose=1, cv=5)
grid.fit(X_train, y_train)
best_params = grid.best_params_
print(f"Best params: {best_params}")# 使用最佳參數訓練模型
svm_clf = SVC(**best_params)
svm_clf.fit(X_train, y_train)
訓練結果:
Accuracy Score: 96.48%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.978723 0.957198 0.964824 0.967961 0.965257
recall 0.926174 0.987952 0.964824 0.957063 0.964824
f1-score 0.951724 0.972332 0.964824 0.962028 0.964617
support 149.000000 249.000000 0.964824 398.000000 398.000000
_______________________________________________
Confusion Matrix: [[138 11][ 3 246]]測試結果:Accuracy Score: 96.49%
_______________________________________________
CLASSIFICATION REPORT:0.0 1.0 accuracy macro avg weighted avg
precision 0.967213 0.963636 0.964912 0.965425 0.964954
recall 0.936508 0.981481 0.964912 0.958995 0.964912
f1-score 0.951613 0.972477 0.964912 0.962045 0.964790
support 63.000000 108.000000 0.964912 171.000000 171.000000
_______________________________________________
Confusion Matrix: [[ 59 4][ 2 106]]
六、總結
本文我們學習了以下內容:
- 支持向量機(SVM):了解了 SVM 的基本概念及其在 Python 中的實現。
- SVM 核函數:包括線性、徑向基函數(RBF)和多項式核函數。
- 數據準備:如何為 SVM 算法準備數據。
- 超參數調整:通過網格搜索調整 SVM 的超參數。
- 主成分分析(PCA):如何使用 PCA 降低數據的復雜性,并在 scikit-learn 中進行重用。
參考:Support Vector Machine & PCA Tutorial for Beginner
推薦我的相關專欄:
- python 錯誤記錄
- python 筆記
- 數據結構