赞
踩
本文深入讲解了无监督学习中的K-means、层次聚类、密度聚类、PCA、t-SNE和自编码器算法,涵盖其原理、数学基础、实现步骤及应用实例,并提供了详细的代码示例。
关注作者,复旦AI博士,分享AI领域全维度知识与研究。拥有10+年AI领域研究经验、复旦机器人智能实验室成员,国家级大学生赛事评审专家,发表多篇SCI核心期刊学术论文,上亿营收AI产品研发负责人。
无监督学习(Unsupervised Learning)是一类机器学习任务,其中算法在没有标签的情况下,从未标记的数据中学习模式和结构。与有监督学习不同,无监督学习不依赖于预定义的输出,而是从数据本身提取信息,用于发现数据的内在规律和特征。
无监督学习的应用背景非常广泛,尤其是在数据标注成本高昂或数据标签缺失的领域中。例如,生物信息学中的基因表达分析、天文学中的星系分类、社交网络分析中的社区检测等。随着数据规模的不断增长,无监督学习的重要性也日益凸显。
无监督学习在许多领域中都有广泛的应用。以下是一些典型的应用场景:
数据聚类是无监督学习的一种主要任务,旨在将相似的数据点分组。例如,市场营销中的客户细分、图像处理中的图像分割、文本分析中的文档聚类等。
降维技术用于减少数据的维度,以便更好地可视化和分析数据。例如,主成分分析(PCA)和t-SNE常用于高维数据的降维和可视化,帮助研究人员发现数据中的潜在结构和模式。
无监督学习还用于检测数据中的异常点或异常模式。例如,在网络安全中检测异常流量,在金融行业中检测异常交易行为等。
有监督学习依赖于大量标记数据进行训练,模型通过已知的输入-输出对进行学习。无监督学习则不需要标记数据,完全依赖数据的内在结构进行学习。
有监督学习的目标是预测或分类,例如图像分类、语音识别等。无监督学习的目标是发现数据的模式和结构,例如聚类、降维等。
无监督学习的挑战在于其不确定性。由于缺乏标签,评估无监督学习模型的效果往往更加复杂,需要依赖于外部指标或人为判断。
聚类算法是无监督学习中最常见的技术之一。其目的是将相似的数据点分组,使同一组内的数据点尽可能相似,而不同组之间的数据点尽可能不同。常见的聚类算法包括K-means、层次聚类和DBSCAN。
降维技术用于减少数据的维度,同时保留尽可能多的有用信息。这对于高维数据的处理和可视化尤为重要。主成分分析(PCA)和t-SNE是两种常见的降维技术。
生成模型如生成对抗网络(GAN)和变分自编码器(VAE)近年来在无监督学习中取得了显著的进展。这些模型通过学习数据的分布来生成与原始数据相似的新数据,广泛应用于图像生成、数据增强等领域。
K-means算法是一种经典且广泛应用的聚类算法,旨在将数据集分割成K个簇,使得同一簇内的数据点尽可能相似,而不同簇之间的数据点差异尽可能大。本文将详细介绍K-means算法的原理、数学基础、优化方法,并通过代码示例展示其具体实现。
K-means算法通过迭代优化以下两个步骤实现数据的聚类:
该过程不断重复,直到簇中心不再发生显著变化或达到预设的迭代次数。
尽管K-means算法简单且高效,但其结果依赖于初始簇中心的选择,容易陷入局部最优解。以下是几种常见的优化方法:
以下是使用Python和SciPy库实现K-means算法的示例代码:
import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from scipy.spatial.distance import cdist def initialize_centroids(X, k): """随机初始化k个簇中心""" indices = np.random.choice(X.shape[0], k, replace=False) return X[indices] def assign_clusters(X, centroids): """分配数据点到最近的簇中心""" distances = cdist(X, centroids, 'euclidean') return np.argmin(distances, axis=1) def update_centroids(X, labels, k): """更新簇中心为簇内所有数据点的平均值""" new_centroids = np.zeros((k, X.shape[1])) for i in range(k): points = X[labels == i] new_centroids[i] = points.mean(axis=0) return new_centroids def kmeans(X, k, max_iters=100, tol=1e-4): """K-means算法实现""" centroids = initialize_centroids(X, k) for _ in range(max_iters): labels = assign_clusters(X, centroids) new_centroids = update_centroids(X, labels, k) if np.all(np.abs(new_centroids - centroids) < tol): break centroids = new_centroids return labels, centroids # 生成样本数据 X, y = make_blobs(n_samples=300, centers=4, random_state=42) # 执行K-means算法 k = 4 labels, centroids = kmeans(X, k) # 可视化聚类结果 plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', marker='o') plt.scatter(centroids[:, 0], centroids[:, 1], s=300, c='red', marker='x') plt.title("K-means Clustering") plt.xlabel("Feature 1") plt.ylabel("Feature 2") plt.show()
initialize_centroids
函数通过随机选择数据点作为初始簇中心。assign_clusters
函数计算每个数据点到所有簇中心的欧几里得距离,并将数据点分配到最近的簇。update_centroids
函数计算每个簇的新中心,即簇内所有数据点的平均值。kmeans
函数在给定的迭代次数和收敛阈值下执行K-means算法,返回最终的簇标签和簇中心。层次聚类(Hierarchical Clustering)是一种无监督学习方法,通过建立层次结构将数据集进行聚类。与K-means等平面聚类方法不同,层次聚类创建一个树状结构(或称为树状图),能够展示数据点之间的嵌套关系。本文将详细介绍层次聚类的基本原理、类型、计算方法及其应用,并通过代码示例展示具体实现。
层次聚类分为两种主要方法:凝聚(自下而上)和分裂(自上而下)。
层次聚类中,定义簇之间的距离是关键步骤。常用的距离度量方法包括:
层次聚类算法的核心在于不断计算和更新簇间距离,具体步骤如下:
以下是使用Python和SciPy库实现凝聚层次聚类的示例代码:
import numpy as np import matplotlib.pyplot as plt from scipy.cluster.hierarchy import dendrogram, linkage, fcluster from sklearn.datasets import make_blobs # 生成样本数据 X, y = make_blobs(n_samples=300, centers=4, random_state=42) # 计算层次聚类的链接矩阵 Z = linkage(X, method='ward') # 绘制树状图 plt.figure(figsize=(10, 7)) dendrogram(Z) plt.title('Hierarchical Clustering Dendrogram') plt.xlabel('Sample index') plt.ylabel('Distance') plt.show() # 根据距离阈值提取簇 max_d = 50 # 距离阈值 clusters = fcluster(Z, max_d, criterion='distance') # 可视化聚类结果 plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='viridis', marker='o') plt.title('Agglomerative Clustering') plt.xlabel('Feature 1') plt.ylabel('Feature 2') plt.show()
make_blobs
生成一个包含四个簇的样本数据集。linkage
函数计算层次聚类的链接矩阵,方法选择ward
,即最小方差法。dendrogram
函数绘制层次聚类的树状图,展示聚类的层次结构。fcluster
函数根据距离阈值提取簇,max_d
为距离阈值。层次聚类广泛应用于各种领域,例如:
密度聚类算法是一类基于数据点密度的无监督学习方法,能够有效处理具有复杂形状和噪声的数据集。最著名的密度聚类算法是DBSCAN(Density-Based Spatial Clustering of Applications with Noise)。本文将详细介绍DBSCAN算法的原理、数学基础、参数选择、优缺点,并通过代码示例展示其具体实现。
DBSCAN算法通过以下步骤实现聚类:
DBSCAN算法依赖于两个重要参数:
选择合适的ε和MinPts参数对DBSCAN的效果至关重要:
以下是使用Python和Scikit-learn库实现DBSCAN算法的示例代码:
import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.cluster import DBSCAN from sklearn.preprocessing import StandardScaler # 生成样本数据 X, y = make_blobs(n_samples=300, centers=4, random_state=42) # 数据标准化处理 X = StandardScaler().fit_transform(X) # DBSCAN聚类 db = DBSCAN(eps=0.3, min_samples=10).fit(X) labels = db.labels_ # 获取核心点和噪声点 core_samples_mask = np.zeros_like(labels, dtype=bool) core_samples_mask[db.core_sample_indices_] = True n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) n_noise_ = list(labels).count(-1) # 可视化聚类结果 unique_labels = set(labels) colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, len(unique_labels))] plt.figure(figsize=(10, 7)) for k, col in zip(unique_labels, colors): if k == -1: # 黑色用于噪声点 col = [0, 0, 0, 1] class_member_mask = (labels == k) xy = X[class_member_mask & core_samples_mask] plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col), markeredgecolor='k', markersize=14) xy = X[class_member_mask & ~core_samples_mask] plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col), markeredgecolor='k', markersize=6) plt.title(f'Estimated number of clusters: {n_clusters_}\n' f'Number of noise points: {n_noise_}') plt.xlabel('Feature 1') plt.ylabel('Feature 2') plt.show()
make_blobs
生成一个包含四个簇的样本数据集。StandardScaler
对数据进行标准化处理,确保不同特征在相同尺度上。DBSCAN
函数进行聚类,设置参数eps
和min_samples
。core_sample_indices_
获取核心点,并统计簇的数量和噪声点的数量。DBSCAN广泛应用于各种领域,例如:
主成分分析(Principal Component Analysis,PCA)是一种经典的降维技术,通过线性变换将高维数据映射到低维空间,同时尽可能保留原始数据中的主要信息。PCA在数据预处理、特征提取、模式识别和数据可视化等领域具有广泛应用。本文将详细介绍PCA的原理、数学基础、实现步骤,并通过代码示例展示其具体实现。
PCA通过寻找数据的主成分,将数据投影到这些主成分构成的子空间中。主成分是数据在变换后的坐标系中的新基向量,这些基向量是按数据方差大小排序的。具体步骤如下:
以下是PCA算法的具体实现步骤:
以下是使用Python和Scikit-learn库实现PCA的示例代码:
import numpy as np import matplotlib.pyplot as plt from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_iris # 加载示例数据集 data = load_iris() X = data.data y = data.target # 数据标准化 scaler = StandardScaler() X_std = scaler.fit_transform(X) # PCA降维,选择前2个主成分 pca = PCA(n_components=2) X_pca = pca.fit_transform(X_std) # 可视化降维后的数据 plt.figure(figsize=(10, 7)) plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis', edgecolor='k', s=150) plt.title('PCA of Iris Dataset') plt.xlabel('Principal Component 1') plt.ylabel('Principal Component 2') plt.colorbar() plt.show()
load_iris
函数加载鸢尾花数据集。StandardScaler
对数据进行标准化处理,确保每个特征具有零均值和单位方差。PCA
类对标准化后的数据进行降维,选择前两个主成分。PCA广泛应用于各种领域,例如:
t-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维技术,尤其擅长在低维空间中保持高维数据的局部结构。t-SNE广泛应用于数据可视化,特别是在处理高维数据时,能够揭示数据的内在结构和模式。本文将详细介绍t-SNE的原理、数学基础、实现步骤,并通过代码示例展示其具体实现。
t-SNE通过构建高维数据点之间的相似度,然后将这些相似度映射到低维空间中,使得相似的数据点在低维空间中尽可能靠近。其核心思想包括以下几个步骤:
以下是使用Python和Scikit-learn库实现t-SNE的示例代码:
import numpy as np import matplotlib.pyplot as plt from sklearn.manifold import TSNE from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_digits # 加载示例数据集 data = load_digits() X = data.data y = data.target # 数据标准化 scaler = StandardScaler() X_std = scaler.fit_transform(X) # t-SNE降维 tsne = TSNE(n_components=2, perplexity=30, n_iter=300) X_tsne = tsne.fit_transform(X_std) # 可视化降维后的数据 plt.figure(figsize=(10, 7)) scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='viridis', edgecolor='k', s=100) plt.title('t-SNE of Digits Dataset') plt.xlabel('t-SNE Component 1') plt.ylabel('t-SNE Component 2') plt.colorbar(scatter) plt.show()
load_digits
函数加载手写数字数据集。StandardScaler
对数据进行标准化处理,确保每个特征具有零均值和单位方差。t-SNE
类对标准化后的数据进行降维,设置参数n_components
为2(即二维空间),perplexity
为30,n_iter
为300。t-SNE广泛应用于各种领域,例如:
自编码器(Autoencoder)是一类用于无监督学习的神经网络,主要用于降维、特征提取和数据生成。自编码器通过将输入数据编码为低维表示,然后再解码为原始数据,来学习数据的有效表示。本文将详细介绍自编码器的原理、数学基础、常见变种及其实现步骤,并通过代码示例展示其具体实现。
在输入数据上添加噪声,通过去噪训练自编码器,使其更具鲁棒性。
在编码器中添加稀疏性约束,鼓励模型学习稀疏表示。
基于概率模型的自编码器,通过学习数据的潜在分布生成新数据。
以下是使用Python和PyTorch实现一个简单自编码器的示例代码:
import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms from torch.utils.data import DataLoader # 定义自编码器模型 class Autoencoder(nn.Module): def __init__(self): super(Autoencoder, self).__init__() self.encoder = nn.Sequential( nn.Linear(28 * 28, 128), nn.ReLU(True), nn.Linear(128, 64), nn.ReLU(True), nn.Linear(64, 12), nn.ReLU(True), nn.Linear(12, 3) ) self.decoder = nn.Sequential( nn.Linear(3, 12), nn.ReLU(True), nn.Linear(12, 64), nn.ReLU(True), nn.Linear(64, 128), nn.ReLU(True), nn.Linear(128, 28 * 28), nn.Tanh() ) def forward(self, x): x = self.encoder(x) x = self.decoder(x) return x # 数据加载和预处理 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))]) train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True) train_loader = DataLoader(dataset=train_dataset, batch_size=128, shuffle=True) # 初始化模型、损失函数和优化器 model = Autoencoder() criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=1e-3) # 模型训练 num_epochs = 20 for epoch in range(num_epochs): for data in train_loader: img, _ = data img = img.view(img.size(0), -1) output = model(img) loss = criterion(output, img) optimizer.zero_grad() loss.backward() optimizer.step() print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 可视化重建结果 import matplotlib.pyplot as plt # 获取一个批次的测试数据 test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True) test_loader = DataLoader(dataset=test_dataset, batch_size=10, shuffle=True) dataiter = iter(test_loader) images, _ = dataiter.next() images = images.view(images.size(0), -1) # 重建图像 outputs = model(images) # 展示原始图像和重建图像 fig, axes = plt.subplots(2, 10, figsize=(10, 2)) for i in range(10): axes[0, i].imshow(images[i].view(28, 28).detach().numpy(), cmap='gray') axes[1, i].imshow(outputs[i].view(28, 28).detach().numpy(), cmap='gray') plt.show()
torchvision
加载MNIST数据集,并对数据进行标准化处理。自编码器在多个领域具有广泛应用,例如:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。