一 无监督学习
什么是无监督学习?
无监督学习是机器学习的一个重要分支,其核心目标是从未标记数据中发现隐藏的模式、结构或关系。与监督学习不同,无监督学习不需要预先标记的训练数据,而是让算法自主探索数据的内在特性。
核心特点:
- 无标签数据:处理的数据没有预先定义的输出标签
- 探索性分析:旨在揭示数据的内在结构和关系
- 数据驱动:算法自主发现模式,而非遵循预设目标
- 特征学习:自动学习有意义的特征表示
无监督学习的主要类型
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(n³))
- 对噪声敏感
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
Z = linkage(data, 'ward')
plt.figure(figsize=(10, 5))
dendrogram(Z)
plt.show()
3. DBSCAN(基于密度的聚类)
核心思想:通过样本密度连接区域形成簇
关键参数:
- ε (eps):邻域半径
- MinPts:形成核心点所需的最小邻居数
优点:
- 不需要预先指定簇数量
- 可以发现任意形状的簇
- 对噪声鲁棒
缺点:
- 对参数敏感
- 处理密度差异大的数据效果不佳
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(eps=0.5, min_samples=5)
clusters = dbscan.fit_predict(data)
4. Mean Shift(均值漂移)
核心思想:通过迭代寻找数据密度最大区域
算法流程:
- 对每个点,计算其邻域内点的均值
- 将点移动到均值位置
- 重复直到收敛
优点:
- 不需要预先指定簇数量
- 对异常值鲁棒
- 结果与初始化无关
缺点:
- 计算复杂度高
- 带宽选择影响结果
from sklearn.cluster import MeanShift
ms = MeanShift(bandwidth=2)
clusters = ms.fit_predict(data)
5. 高斯混合模型(GMM)
核心思想:使用多个高斯分布的加权和来建模数据
优点:
- 提供概率聚类
- 更灵活的簇形状(椭圆而非圆形)
缺点:
- 对初始化敏感
- 可能收敛到局部最优
from sklearn.mixture import GaussianMixture
gmm = 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 SpectralClustering
sc = SpectralClustering(n_clusters=3, affinity='nearest_neighbors')
clusters = sc.fit_predict(data)
2. 模糊聚类
原理:允许数据点以不同概率属于多个簇,如模糊C均值算法
from sklearn_extensions.fuzzy_kmeans import FuzzyKMeans
fkm = FuzzyKMeans(k=3)
fkm.fit(data)
membership = fkm.membership_
3. 时间序列聚类
特殊考量:使用动态时间规整(DTW)等特定距离度量
from tslearn.clustering import TimeSeriesKMeans
model = 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].