聊天視窗

數據之鏡:從資料洞察到決策智慧 - 第 6 章

第六章 非監督式模型與異常偵測

發布於 2026-02-25 19:07

# 第六章 非監督式模型與異常偵測 本章聚焦於在無標籤資料情境下,如何發掘結構、分群、並辨識異常。雖然監督式學習以預測為主,非監督式方法在許多商業場景(如客戶分群、欺詐偵測、設備健康監控)同樣不可或缺。章節結構如下: 1. [分群(Clustering)概念與評估](#分群概念與評估) 2. [K‑means](#k-means) 3. [DBSCAN(基於密度的聚類)](#dbscan) 4. [Isolation Forest(異常偵測)](#isolation-forest) 5. [主成分分析(PCA)與可視化](#主成分分析pca) 6. [實務案例:信用卡欺詐偵測](#實務案例信用卡欺詐偵測) 7. [工具與實作建議](#工具與實作建議) 8. [小結](#小結) --- ## 分群概念與評估 - **聚類目標**:將資料分成若干群組,使同一群內的樣本相似度高,而不同群間相似度低。 - **常見評估指標**: - **輪廓係數(Silhouette Coefficient)**:-1 ~ 1,越高表示聚類效果越好。 - **肘部法(Elbow Method)**:觀察總變異平方和(Within‑Cluster Sum of Squares, WCSS)隨聚類數變化的拐點。 - **Calinski–Harabasz 指數**:群內變異與群間變異之比,值越大表示聚類效果好。 > **實務提示**:在實際業務中,聚類往往與業務目標結合,如「高價值客戶」分群,應先定義業務 KPI,再選擇合適的聚類方法與評估指標。 --- ## K‑means K‑means 是最常用且易於實作的聚類演算法。核心思路是: 1. 隨機選擇 `K` 個中心點。 2. 分配每個樣本到最近的中心。 3. 重新計算每個群的中心為群內樣本均值。 4. 重複步驟 2‑3,直到中心不再變動或達到預設迭代上限。 ### 參數說明 | 參數 | 說明 | |------|------| | `n_clusters` | 群數 K | | `init` | 初始化方法 (`k-means++` 建議) | | `max_iter` | 最大迭代次數 | | `tol` | 迭代收斂容忍度 | | `random_state` | 隨機種子 | ### 典型程式碼(Python / scikit‑learn) python from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler import pandas as pd # 讀取資料 X = pd.read_csv('customer_features.csv').drop('customer_id', axis=1) # 特徵標準化(K‑means 受尺度影響) X_scaled = StandardScaler().fit_transform(X) # 決定 K 值(肘部法) wcss = [] for k in range(1, 11): kmeans = KMeans(n_clusters=k, init='k-means++', random_state=42) kmeans.fit(X_scaled) wcss.append(kmeans.inertia_) # 選擇 K=4(假設肘部在此) kmeans = KMeans(n_clusters=4, init='k-means++', random_state=42) clusters = kmeans.fit_predict(X_scaled) # 結果匯出 X['cluster'] = clusters X.to_csv('customer_clusters.csv', index=False) ### 適用情境 - 客戶分群(市場細分) - 產品特徵聚類(同類產品組合) - 供應鏈風險分層 --- ## DBSCAN(基於密度的聚類) DBSCAN 針對密度分佈不均且含噪聲的資料非常有效。它不需要預先指定聚類數,且能自動辨識噪聲點。核心概念: - **eps**:鄰域半徑,決定鄰域範圍。 - **min_samples**:鄰域內最小樣本數,定義核心點。 ### 參數說明 | 參數 | 說明 | |------|------| | `eps` | 鄰域半徑(可通過 k‑distance 曲線確定) | | `min_samples` | 核心點最小鄰域樣本數 | | `metric` | 距離度量(默認 `euclidean`) | ### 典型程式碼 python from sklearn.cluster import DBSCAN from sklearn.preprocessing import StandardScaler import numpy as np import pandas as pd X = pd.read_csv('purchase_data.csv').drop(['order_id', 'timestamp'], axis=1) X_scaled = StandardScaler().fit_transform(X) # 確定 eps(k‑distance 曲線) from sklearn.neighbors import NearestNeighbors nbrs = NearestNeighbors(n_neighbors=5).fit(X_scaled) distances, _ = nbrs.kneighbors(X_scaled) distances = np.sort(distances[:, 4]) # 第 5 個最近鄰距離 import matplotlib.pyplot as plt plt.plot(distances) plt.title('k-distance curve') plt.xlabel('Points sorted by distance') plt.ylabel('Distance to 5th nearest neighbor') plt.show() # 假設在拐點處選取 eps=0.5 dbscan = DBSCAN(eps=0.5, min_samples=5) labels = dbscan.fit_predict(X_scaled) X['cluster'] = labels X.to_csv('dbscan_clusters.csv', index=False) ### 適用情境 - 地理空間聚類(衛星影像、城市規劃) - 網路流量異常聚類 - 生物資訊(基因表達)聚類 --- ## Isolation Forest(異常偵測) Isolation Forest 基於樹結構將異常樣本「孤立」的原理,計算平均孤立深度(average path length)作為異常分數。 ### 參數說明 | 參數 | 說明 | |------|------| | `n_estimators` | 隨機樹數量 | | `max_samples` | 每棵樹抽樣的樣本數(可設 `auto`) | | `contamination` | 估計異常比例 | | `behaviour` | 取樣方式 (`old` / `new`) | ### 典型程式碼 python from sklearn.ensemble import IsolationForest import pandas as pd X = pd.read_csv('sensor_readings.csv') iso_forest = IsolationForest(n_estimators=200, contamination=0.01, random_state=42) iso_forest.fit(X) scores = iso_forest.decision_function(X) # -1 為異常,1 為正常 anomaly_labels = iso_forest.predict(X) # -1 / 1 X['anomaly_score'] = scores X['anomaly'] = anomaly_labels X.to_csv('anomaly_detection.csv', index=False) > **注意**:若資料含大量噪聲,建議先做 `StandardScaler`,並考慮對離群值進行處理後再訓練。 ### 適用情境 - 工業 IoT 故障預警 - 銀行交易異常 - 網站入侵偵測 --- ## 主成分分析(PCA) PCA 是線性降維工具,亦常作為分群前的資料預處理或後續可視化手段。核心在於找到資料中方差最大的方向(主成分),並保留前幾個主成分以近似原資料。 ### 步驟 1. 標準化特徵。 2. 計算協方差矩陣。 3. 求其特徵值與特徵向量。 4. 選擇前 `k` 個特徵值最大之特徵向量作為主成分。 ### 典型程式碼 python from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler import pandas as pd import matplotlib.pyplot as plt X = pd.read_csv('credit_card_features.csv').drop(['customer_id', 'timestamp'], axis=1) X_scaled = StandardScaler().fit_transform(X) pca = PCA(n_components=2, random_state=42) X_pca = pca.fit_transform(X_scaled) plt.scatter(X_pca[:, 0], X_pca[:, 1], c='steelblue', alpha=0.5) plt.title('PCA 2‑D Projection') plt.xlabel('PC1') plt.ylabel('PC2') plt.show() ### 小技巧 - **方差比**:`pca.explained_variance_ratio_`,可用於決定保留多少主成分。 - **可視化**:t‑SNE / UMAP 可與 PCA 結合產生更有意義的 2‑D / 3‑D 投影。 --- ## 實務案例:信用卡欺詐偵測 ### 背景 在信用卡交易資料中,正常交易佔 99.9% 以上,欺詐交易僅佔 0.1%。此類極端不平衡資料適合使用 Isolation Forest 或聚類+異常偵測結合的管道。 ### 數據示例(`creditcard.csv`) - `V1` ~ `V28`:PCA 變換特徵。 - `Amount`:交易金額。 - `Class`:標籤(1 為欺詐)。 ### 分析流程 | 步驟 | 目的 | |------|------| | 1. 讀取資料 | 檢視標籤分布 | | 2. 特徵縮放 | `StandardScaler` | | 3. 先用 Isolation Forest 取得異常分數 | | 4. 以分數做二分,取得預測標籤 | | 5. 交叉驗證(Precision‑Recall, ROC‑AUC) | ### 典型程式碼 python import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.ensemble import IsolationForest from sklearn.metrics import classification_report, precision_recall_curve, roc_auc_score import matplotlib.pyplot as plt # 讀取資料 data = pd.read_csv('creditcard.csv') X = data.drop('Class', axis=1) y_true = data['Class'] # 標準化 X_scaled = StandardScaler().fit_transform(X) # Isolation Forest iso = IsolationForest(n_estimators=200, contamination=0.001, random_state=42) iso.fit(X_scaled) # 異常分數(decision_function) scores = iso.decision_function(X_scaled) labels_pred = iso.predict(X_scaled) # -1: anomaly, 1: normal # 轉為 0/1 labels_pred = (labels_pred == -1).astype(int) # 評估 print('ROC‑AUC:', roc_auc_score(y_true, scores)) print(classification_report(y_true, labels_pred)) # Precision‑Recall 曲線 prec, recall, _ = precision_recall_curve(y_true, scores) plt.plot(recall, prec) plt.title('Precision‑Recall Curve') plt.xlabel('Recall') plt.ylabel('Precision') plt.show() > **結果說明**:Isolation Forest 在此場景通常能達到 **AUC ≈ 0.99**,但 Precision‑Recall 曲線會因欺詐比例極低而變得敏感。可考慮結合 `SMOTE`、`KNN` 失真重樣本或使用 `One‑Class SVM` 進行細化。 --- ## 工具與實作建議 | 底層框架 | 特色 | |----------|------| | **scikit‑learn** | K‑means、DBSCAN、Isolation Forest、PCA 全部支援,易於快速原型開發。 | **H2O.ai** | 提供基於 MapReduce 的大規模聚類與 Isolation Forest,支援 Spark。 | **MLlib (Spark)** | `KMeans`, `BisectingKMeans`, `RandomForest`(Isolation Forest 類)可在分布式環境下處理 TB‑級資料。 | **TensorFlow/Keras** | 可透過自訂 auto‑encoder + `IsolationForest` 的結合,進行深度聚類。 ### 設計提示 1. **資料前處理**:特徵縮放、缺失值填補、離散化等直接影響聚類與異常偵測。 2. **模型解釋**:聚類結果應配合可視化(散點圖、熱力圖)及商業指標說明,避免「黑箱」效應。 3. **更新機制**:對於持續流動資料,採用 `incremental learning` 或滑動窗口更新模型。 4. **警報閾值**:異常分數可設成「動態閾值」,根據業務週期或成本敏感度調整。 --- ## 小結 - **K‑means**:簡單、快速,但對離散噪聲不敏感,適合規模中等且相似度高的資料。 - **DBSCAN**:不需預設群數,能自動處理噪聲,適合密度不均或含異常點的資料。 - **Isolation Forest**:針對高維異常偵測表現優秀,計算成本低。 - **PCA**:作為降維工具,可提升聚類表現並視覺化高維結構。 - **評估指標**:輪廓係數、肘部法、ROC‑AUC 等是判斷模型好壞的客觀量化方法。 - **實務關鍵**:非監督式方法往往需要與業務需求緊密結合,確定 KPI、調整參數、並透過可視化與解釋提升決策支持。 > **下一步**:在第七章中,我們將探討「深度學習中的自監督式(Self‑Supervised)方法」,進一步擴展在無標籤資料中的模型開發。