文章目錄
- 一 無監督學習
- 什么是無監督學習?
- 核心特點:
- 無監督學習的主要類型
- 1. 聚類分析 (Clustering)
- 2. 降維 (Dimensionality Reduction)
- 3. 關聯規則學習 (Association Rule Learning)
- 4. 異常檢測 (Anomaly Detection)
- 5. 密度估計 (Density Estimation)
- 二 聚類分析
- 聚類概述
- 主要聚類算法
- 1. K-Means 聚類
- 2. 層次聚類
- 3. DBSCAN(基于密度的聚類)
- 4. Mean Shift(均值漂移)
- 5. 高斯混合模型(GMM)
- 聚類評估指標
- 內部指標(無真實標簽)
- 外部指標(有真實標簽)
- 聚類實踐指南
- 1. 數據預處理
- 2. 確定最佳簇數
- 3. 處理常見問題
- 高級聚類技術
- 1. 譜聚類
- 2. 模糊聚類
- 3. 時間序列聚類
- 聚類實際應用案例
- 客戶細分
- 圖像壓縮(顏色量化)
- 聚類挑戰與未來方向
- 當前挑戰
- 未來方向
- 結語
- KMean、KNN、Meanshift比較
- 關于
一 無監督學習
什么是無監督學習?
無監督學習是機器學習的一個重要分支,其核心目標是從未標記數據中發現隱藏的模式、結構或關系。與監督學習不同,無監督學習不需要預先標記的訓練數據,而是讓算法自主探索數據的內在特性。
核心特點:
- 無標簽數據:處理的數據沒有預先定義的輸出標簽
- 探索性分析:旨在揭示數據的內在結構和關系
- 數據驅動:算法自主發現模式,而非遵循預設目標
- 特征學習:自動學習有意義的特征表示
無監督學習的主要類型
1. 聚類分析 (Clustering)
將數據劃分為相似對象的組(簇)
常見算法:
- K-Means
- 層次聚類 (Hierarchical Clustering)
- DBSCAN
- 高斯混合模型 (GMM)
- 譜聚類 (Spectral Clustering)
2. 降維 (Dimensionality Reduction)
減少變量數量,同時保留重要信息
常見技術:
- 主成分分析 (PCA)
- t-分布隨機鄰域嵌入 (t-SNE)
- 自編碼器 (Autoencoders)
- 因子分析 (Factor Analysis)
3. 關聯規則學習 (Association Rule Learning)
發現變量之間的有趣關系
典型方法:
- Apriori算法
- FP-Growth算法
4. 異常檢測 (Anomaly Detection)
識別與大多數數據顯著不同的數據點
常用技術:
- 孤立森林 (Isolation Forest)
- 一類支持向量機 (One-Class SVM)
- 局部離群因子 (Local Outlier Factor)
5. 密度估計 (Density Estimation)
估計隨機變量的概率密度函數
主要方法:
- 核密度估計 (Kernel Density Estimation)
- 高斯混合模型
二 聚類分析
聚類概述
聚類是機器學習中最重要的無監督學習技術之一,其目標是將數據集中的樣本劃分為多個組(簇),使得:
- 組內相似性:同一簇內的樣本盡可能相似
- 組間差異性:不同簇的樣本盡可能不同
聚類在眾多領域有廣泛應用:
- 客戶細分:識別不同消費群體
- 圖像分割:分離圖像中的不同對象
- 異常檢測:發現異常數據點
- 生物信息學:基因表達分析
- 文檔組織:主題聚類
主要聚類算法
1. K-Means 聚類
核心思想:通過迭代優化,將數據劃分為K個球形簇
算法步驟:
- 隨機選擇K個初始質心
- 將每個點分配到最近的質心
- 重新計算每個簇的質心
- 重復步驟2-3直到質心不再變化
優點:
- 計算效率高,適合大規模數據集
- 實現簡單,易于理解
缺點:
- 需要預先指定K值
- 對初始質心敏感
- 假設簇為球形且大小相似
2. 層次聚類
核心思想:通過構建樹狀結構(樹狀圖)逐步合并或分裂簇
類型:
- 凝聚式:自底向上,每個點開始作為一個簇,逐步合并
- 分裂式:自頂向下,所有點開始在一個簇,逐步分裂
優點:
- 不需要預先指定簇數量
- 結果可解釋性強(樹狀圖)
缺點:
- 計算復雜度高(O(n3))
- 對噪聲敏感
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as pltZ = linkage(data, 'ward')
plt.figure(figsize=(10, 5))
dendrogram(Z)
plt.show()
3. DBSCAN(基于密度的聚類)
核心思想:通過樣本密度連接區域形成簇
關鍵參數:
- ε (eps):鄰域半徑
- MinPts:形成核心點所需的最小鄰居數
優點:
- 不需要預先指定簇數量
- 可以發現任意形狀的簇
- 對噪聲魯棒
缺點:
- 對參數敏感
- 處理密度差異大的數據效果不佳
from sklearn.cluster import DBSCANdbscan = DBSCAN(eps=0.5, min_samples=5)
clusters = dbscan.fit_predict(data)
4. Mean Shift(均值漂移)
核心思想:通過迭代尋找數據密度最大區域
算法流程:
- 對每個點,計算其鄰域內點的均值
- 將點移動到均值位置
- 重復直到收斂
優點:
- 不需要預先指定簇數量
- 對異常值魯棒
- 結果與初始化無關
缺點:
- 計算復雜度高
- 帶寬選擇影響結果
from sklearn.cluster import MeanShiftms = MeanShift(bandwidth=2)
clusters = ms.fit_predict(data)
5. 高斯混合模型(GMM)
核心思想:使用多個高斯分布的加權和來建模數據
優點:
- 提供概率聚類
- 更靈活的簇形狀(橢圓而非圓形)
缺點:
- 對初始化敏感
- 可能收斂到局部最優
from sklearn.mixture import GaussianMixturegmm = GaussianMixture(n_components=3)
clusters = gmm.fit_predict(data)
聚類評估指標
內部指標(無真實標簽)
-
輪廓系數:衡量簇內緊密度和簇間分離度
from sklearn.metrics import silhouette_score score = silhouette_score(data, clusters)
-
戴維斯-布爾丁指數:簇內距離與簇間距離的比率
-
Calinski-Harabasz指數:簇間離散度與簇內離散度的比率
外部指標(有真實標簽)
-
調整蘭德指數:衡量聚類結果與真實標簽的相似度
from sklearn.metrics import adjusted_rand_score ari = adjusted_rand_score(true_labels, clusters)
-
標準化互信息:衡量兩個標簽分配之間的相似性
聚類實踐指南
1. 數據預處理
-
標準化:確保所有特征具有相同尺度
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() data_scaled = scaler.fit_transform(data)
-
降維:PCA或t-SNE可視化高維數據
from sklearn.decomposition import PCA pca = PCA(n_components=2) data_pca = pca.fit_transform(data)
2. 確定最佳簇數
-
肘部法則:繪制不同K值的SSE(平方誤差和)
sse = [] for k in range(1, 11):kmeans = KMeans(n_clusters=k)kmeans.fit(data)sse.append(kmeans.inertia_)plt.plot(range(1, 11), sse, 'bx-') plt.xlabel('Number of clusters') plt.ylabel('SSE') plt.show()
-
輪廓分析:選擇輪廓系數最大的K值
3. 處理常見問題
- 分類變量:使用獨熱編碼或距離度量
- 缺失值:插補或使用支持缺失值的算法
- 高維數據:降維或使用子空間聚類
- 不同密度簇:使用DBSCAN或OPTICS
高級聚類技術
1. 譜聚類
原理:將聚類問題轉化為圖分割問題,在高維空間中有效處理非凸形狀
from sklearn.cluster import SpectralClusteringsc = SpectralClustering(n_clusters=3, affinity='nearest_neighbors')
clusters = sc.fit_predict(data)
2. 模糊聚類
原理:允許數據點以不同概率屬于多個簇,如模糊C均值算法
from sklearn_extensions.fuzzy_kmeans import FuzzyKMeansfkm = FuzzyKMeans(k=3)
fkm.fit(data)
membership = fkm.membership_
3. 時間序列聚類
特殊考量:使用動態時間規整(DTW)等特定距離度量
from tslearn.clustering import TimeSeriesKMeansmodel = TimeSeriesKMeans(n_clusters=3, metric="dtw")
clusters = model.fit_predict(time_series_data)
聚類實際應用案例
客戶細分
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler# 加載客戶數據
customer_data = pd.read_csv('customer_data.csv')# 選擇特征并標準化
features = ['age', 'income', 'spending_score']
X = customer_data[features]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)# 確定最佳K值(肘部法則)
sse = []
for k in range(1, 11):kmeans = KMeans(n_clusters=k, random_state=42)kmeans.fit(X_scaled)sse.append(kmeans.inertia_)# 選擇K=5進行聚類
kmeans = KMeans(n_clusters=5, random_state=42)
customer_data['cluster'] = kmeans.fit_predict(X_scaled)# 分析聚類特征
cluster_profiles = customer_data.groupby('cluster')[features].mean()
圖像壓縮(顏色量化)
from sklearn.cluster import MiniBatchKMeans
import cv2
import numpy as np# 加載圖像
image = cv2.imread('image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pixels = image.reshape(-1, 3)# 使用K-Means減少顏色數量
kmeans = MiniBatchKMeans(n_clusters=16)
kmeans.fit(pixels)
new_colors = kmeans.cluster_centers_[kmeans.predict(pixels)]# 重建壓縮圖像
compressed_image = new_colors.reshape(image.shape).astype('uint8')
聚類挑戰與未來方向
當前挑戰
- 高維數據:維數災難導致距離度量失效
- 可解釋性:復雜聚類結果難以解釋
- 參數選擇:算法參數對結果影響大
- 混合類型數據:同時處理數值型和類別型特征
未來方向
-
深度聚類:結合深度學習的表示學習和聚類
from sklearn.cluster import KMeans from tensorflow.keras.layers import Input, Dense from tensorflow.keras.models import Model# 自編碼器 input_layer = Input(shape=(data.shape[1],)) encoded = Dense(10, activation='relu')(input_layer) decoded = Dense(data.shape[1], activation='sigmoid')(encoded) autoencoder = Model(input_layer, decoded) autoencoder.compile(optimizer='adam', loss='mse') autoencoder.fit(data, data, epochs=50)# 在編碼空間聚類 encoder = Model(input_layer, encoded) encoded_data = encoder.predict(data) kmeans = KMeans(n_clusters=5) clusters = kmeans.fit_predict(encoded_data)
-
大規模數據聚類:開發更高效的分布式算法
-
多視圖聚類:整合來自多個來源的數據
-
可解釋聚類:提供可理解的聚類解釋
結語
聚類是探索性數據分析和模式發現的重要工具。選擇合適的方法需要考慮:
- 數據特征(大小、維度、分布)
- 期望的簇形狀和結構
- 計算資源限制
- 結果可解釋性需求
理解不同算法的原理、優缺點和適用場景,結合適當的預處理和評估方法,才能在實際應用中發揮聚類的最大價值。隨著深度學習和大數據技術的發展,聚類方法將繼續演進,解決更復雜的現實世界問題。
KMean、KNN、Meanshift比較
- 采用Kmeans算法實現2D數據自動聚類,預測V1=80,v2=60數據類別
- 計算預測準確率,完成結果矯正
- 采用KNN,Meanshift算法,重復步驟1-2
代碼如下所示:
import os
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans, MeanShift
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import warnings# 設置環境變量解決KMeans內存泄漏警告
os.environ['OMP_NUM_THREADS'] = '1'# 忽略特定警告
warnings.filterwarnings("ignore", category=UserWarning,message="KMeans is known to have a memory leak on Windows with MKL")# 加載數據
data = pd.read_csv('data.csv')
X = data[['V1', 'V2']].values
y_true = data['labels'].values
new_point = np.array([[80, 60]])# 1. KMeans 算法實現
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
kmeans_labels = kmeans.fit_predict(X)# 標簽對齊
label_map_kmeans = {}
for i in range(3):mask = (kmeans_labels == i)if sum(mask) > 0:true_label = np.argmax(np.bincount(y_true[mask]))label_map_kmeans[i] = true_label# 矯正標簽
kmeans_labels_corrected = np.array([label_map_kmeans[label] for label in kmeans_labels])
kmeans_pred = label_map_kmeans[kmeans.predict(new_point)[0]]# 計算準確率
kmeans_accuracy = accuracy_score(y_true, kmeans_labels_corrected)# 2. KNN 算法實現
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X, y_true)
knn_pred = knn.predict(new_point)[0]
knn_accuracy = accuracy_score(y_true, knn.predict(X))# 3. MeanShift 算法實現
ms = MeanShift(bandwidth=20, bin_seeding=True)
ms_labels = ms.fit_predict(X)# 標簽對齊
label_map_ms = {}
unique_labels = np.unique(ms_labels)
for label in unique_labels:mask = (ms_labels == label)if sum(mask) > 0:true_label = np.argmax(np.bincount(y_true[mask]))label_map_ms[label] = true_label# 矯正標簽
ms_labels_corrected = np.array([label_map_ms[label] for label in ms_labels])
ms_pred = label_map_ms[ms.predict(new_point)[0]]# 計算準確率
ms_accuracy = accuracy_score(y_true, ms_labels_corrected)# 4. 數據可視化
colors = ['#FF5733', '#33FF57', '#3357FF'] # 紅, 綠, 藍
cmap = ListedColormap(colors)plt.figure(figsize=(18, 12))# 1. 原始數據分布
plt.subplot(2, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap=cmap, s=15, alpha=0.7)
plt.scatter(80, 60, c='gold', marker='*', s=300, edgecolor='black')
plt.title('Original Data Distribution')
plt.xlabel('V1')
plt.ylabel('V2')
plt.grid(alpha=0.3)# 2. KMeans聚類結果
plt.subplot(2, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=kmeans_labels_corrected, cmap=cmap, s=15, alpha=0.7)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],c='black', marker='X', s=200, label='Centroids')
plt.scatter(80, 60, c='gold', marker='*', s=300, edgecolor='black')
plt.title(f'KMeans Clustering (Acc: {kmeans_accuracy:.2%})\nPredicted Class: {kmeans_pred}')
plt.xlabel('V1')
plt.ylabel('V2')
plt.grid(alpha=0.3)
plt.legend()# 3. KNN分類結果
plt.subplot(2, 2, 3)
x_min, x_max = X[:, 0].min() - 10, X[:, 0].max() + 10
y_min, y_max = X[:, 1].min() - 10, X[:, 1].max() + 10
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.5), np.arange(y_min, y_max, 0.5))
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)plt.contourf(xx, yy, Z, alpha=0.3, cmap=cmap)
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap=cmap, s=15, edgecolor='k', alpha=0.7)
plt.scatter(80, 60, c='gold', marker='*', s=300, edgecolor='black')
plt.title(f'KNN Classification (Acc: {knn_accuracy:.2%})\nPredicted Class: {knn_pred}')
plt.xlabel('V1')
plt.ylabel('V2')
plt.grid(alpha=0.3)# 4. MeanShift聚類結果
plt.subplot(2, 2, 4)
plt.scatter(X[:, 0], X[:, 1], c=ms_labels_corrected, cmap=cmap, s=15, alpha=0.7)
plt.scatter(ms.cluster_centers_[:, 0], ms.cluster_centers_[:, 1],c='black', marker='X', s=200, label='Centroids')
plt.scatter(80, 60, c='gold', marker='*', s=300, edgecolor='black')
plt.title(f'MeanShift Clustering (Acc: {ms_accuracy:.2%})\nPredicted Class: {ms_pred}')
plt.xlabel('V1')
plt.ylabel('V2')
plt.grid(alpha=0.3)
plt.legend()plt.suptitle('2D Data Clustering Comparison', fontsize=16, y=0.98)
plt.tight_layout()
plt.savefig('clustering_comparison.png', dpi=300)
plt.show()# 打印結果
print("="*50)
print(f"KMeans 結果: 準確率 = {kmeans_accuracy:.2%}, 新點(80,60)預測 = {kmeans_pred}")
print(f"KNN 結果: 準確率 = {knn_accuracy:.2%}, 新點(80,60)預測 = {knn_pred}")
print(f"MeanShift 結果: 準確率 = {ms_accuracy:.2%}, 新點(80,60)預測 = {ms_pred}")
print("="*50)
輸出如下:
==================================================
KMeans 結果: 準確率 = 99.70%, 新點(80,60)預測 = 2
KNN 結果: 準確率 = 99.93%, 新點(80,60)預測 = 2
MeanShift 結果: 準確率 = 99.70%, 新點(80,60)預測 = 2
==================================================
效果如下圖所示:
關于
?QQ:806797785
??倉庫地址:https://gitee.com/gaogzhen
??倉庫地址:https://github.com/gaogzhen
[1]AI人工智能從入門到精通全套教程[CP/OL].
[2]deepseek[CP/OL].