脚本如何实现文件内容谱聚类

wen 实用脚本 3

本文目录导读:

脚本如何实现文件内容谱聚类

  1. 谱聚类算法实现
  2. 测试脚本
  3. 使用scikit-learn的实现
  4. 参数优化脚本
  5. 完整使用示例
  6. 关键点说明

我来为你详细介绍如何使用脚本实现谱聚类算法,这里以Python为例,展示完整的实现过程:

谱聚类算法实现

import numpy as np
from sklearn.cluster import KMeans
from scipy.sparse.csgraph import connected_components
from scipy.spatial.distance import pdist, squareform
class SpectralClustering:
    def __init__(self, n_clusters=2, gamma=1.0, affinity='rbf'):
        """
        n_clusters: 聚类数量
        gamma: RBF核参数
        affinity: 相似度度量方式 ('rbf' 或 'nearest_neighbors')
        """
        self.n_clusters = n_clusters
        self.gamma = gamma
        self.affinity = affinity
    def _compute_similarity_matrix(self, X):
        """计算相似度矩阵"""
        n_samples = X.shape[0]
        if self.affinity == 'rbf':
            # 计算欧氏距离
            pairwise_dists = squareform(pdist(X, 'euclidean'))
            # RBF核相似度
            similarity_matrix = np.exp(-self.gamma * pairwise_dists ** 2)
        else:
            # 使用最近邻方法
            similarity_matrix = np.zeros((n_samples, n_samples))
            from sklearn.neighbors import kneighbors_graph
            knn_graph = kneighbors_graph(X, n_neighbors=10, mode='distance')
            similarity_matrix = knn_graph.toarray()
        return similarity_matrix
    def _compute_laplacian(self, similarity_matrix):
        """计算拉普拉斯矩阵"""
        # 度矩阵
        degree_matrix = np.diag(np.sum(similarity_matrix, axis=1))
        # 归一化拉普拉斯矩阵
        # L = D^(-1/2) * (D - W) * D^(-1/2)
        degree_inv_sqrt = np.linalg.inv(np.sqrt(degree_matrix))
        laplacian = degree_inv_sqrt @ (degree_matrix - similarity_matrix) @ degree_inv_sqrt
        return laplacian
    def fit_predict(self, X):
        """执行谱聚类"""
        # 1. 计算相似度矩阵
        similarity_matrix = self._compute_similarity_matrix(X)
        # 2. 计算拉普拉斯矩阵
        laplacian = self._compute_laplacian(similarity_matrix)
        # 3. 计算特征值和特征向量
        eigenvalues, eigenvectors = np.linalg.eigh(laplacian)
        # 4. 选择最小的k个特征值对应的特征向量
        idx = np.argsort(eigenvalues)[:self.n_clusters]
        selected_eigenvectors = eigenvectors[:, idx]
        # 5. 归一化特征向量(行归一化)
        row_norms = np.linalg.norm(selected_eigenvectors, axis=1, keepdims=True)
        normalized_vectors = selected_eigenvectors / (row_norms + 1e-10)
        # 6. 使用K-means进行聚类
        kmeans = KMeans(n_clusters=self.n_clusters, random_state=42)
        labels = kmeans.fit_predict(normalized_vectors)
        return labels
# 简化版谱聚类
def spectral_clustering_simple(X, n_clusters=2, gamma=1.0):
    """
    简化的谱聚类实现
    """
    # 计算相似度矩阵
    pairwise_dists = squareform(pdist(X, 'euclidean'))
    W = np.exp(-gamma * pairwise_dists ** 2)
    # 计算度矩阵
    D = np.diag(np.sum(W, axis=1))
    # 计算拉普拉斯矩阵
    D_inv_sqrt = np.linalg.inv(np.sqrt(D))
    L = D_inv_sqrt @ (D - W) @ D_inv_sqrt
    # 计算特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eigh(L)
    # 选择特征向量
    idx = np.argsort(eigenvalues)[:n_clusters]
    selected = eigenvectors[:, idx]
    # K-means聚类
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    labels = kmeans.fit_predict(selected)
    return labels

测试脚本

import matplotlib.pyplot as plt
from sklearn.datasets import make_moons, make_circles
def test_spectral_clustering():
    """测试谱聚类算法"""
    # 生成测试数据
    X_moons, y_moons = make_moons(n_samples=200, noise=0.05, random_state=42)
    X_circles, y_circles = make_circles(n_samples=200, noise=0.05, factor=0.5, random_state=42)
    # 创建谱聚类实例
    sc = SpectralClustering(n_clusters=2, gamma=10.0)
    # 对moon数据进行聚类
    labels_moons = sc.fit_predict(X_moons)
    # 对circle数据进行聚类
    labels_circles = sc.fit_predict(X_circles)
    # 可视化结果
    fig, axes = plt.subplots(2, 2, figsize=(12, 10))
    # moon数据原始标签
    axes[0, 0].scatter(X_moons[:, 0], X_moons[:, 1], c=y_moons, cmap='viridis')
    axes[0, 0].set_title('Moon Data - True Labels')
    # moon数据聚类结果
    axes[0, 1].scatter(X_moons[:, 0], X_moons[:, 1], c=labels_moons, cmap='viridis')
    axes[0, 1].set_title('Moon Data - Spectral Clustering')
    # circle数据原始标签
    axes[1, 0].scatter(X_circles[:, 0], X_circles[:, 1], c=y_circles, cmap='viridis')
    axes[1, 0].set_title('Circle Data - True Labels')
    # circle数据聚类结果
    axes[1, 1].scatter(X_circles[:, 0], X_circles[:, 1], c=labels_circles, cmap='viridis')
    axes[1, 1].set_title('Circle Data - Spectral Clustering')
    plt.tight_layout()
    plt.show()
if __name__ == "__main__":
    test_spectral_clustering()

使用scikit-learn的实现

from sklearn.cluster import SpectralClustering
from sklearn.preprocessing import StandardScaler
def sklearn_spectral_clustering(X, n_clusters=2):
    """
    使用scikit-learn的谱聚类实现
    """
    # 数据标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    # 创建谱聚类模型
    spectral = SpectralClustering(
        n_clusters=n_clusters,
        affinity='rbf',
        gamma=1.0,
        random_state=42
    )
    # 执行聚类
    labels = spectral.fit_predict(X_scaled)
    return labels

参数优化脚本

def tune_parameters(X, n_clusters_range=[2, 3, 4, 5], gamma_range=[0.1, 1, 10]):
    """参数调优"""
    from sklearn.metrics import silhouette_score
    best_score = -1
    best_params = {}
    for n_clusters in n_clusters_range:
        for gamma in gamma_range:
            sc = SpectralClustering(n_clusters=n_clusters, gamma=gamma)
            labels = sc.fit_predict(X)
            # 计算轮廓系数
            if len(np.unique(labels)) > 1:
                score = silhouette_score(X, labels)
                if score > best_score:
                    best_score = score
                    best_params = {
                        'n_clusters': n_clusters,
                        'gamma': gamma
                    }
    return best_params, best_score

完整使用示例

import numpy as np
from sklearn.datasets import make_blobs
# 生成测试数据
X, y = make_blobs(n_samples=300, centers=3, n_features=2, random_state=42)
# 方法1:使用自定义实现
sc_custom = SpectralClustering(n_clusters=3, gamma=1.0)
labels_custom = sc_custom.fit_predict(X)
# 方法2:使用scikit-learn
labels_sklearn = sklearn_spectral_clustering(X, n_clusters=3)
# 方法3:使用简化版
labels_simple = spectral_clustering_simple(X, n_clusters=3, gamma=1.0)
# 比较结果
print(f"自定义实现聚类结果:{np.unique(labels_custom)}")
print(f"Sklearn实现聚类结果:{np.unique(labels_sklearn)}")
print(f"简化版聚类结果:{np.unique(labels_simple)}")

关键点说明

  1. 相似度矩阵构建:使用RBF核或KNN
  2. 拉普拉斯矩阵:归一化版本更稳定
  3. 特征分解:选择最小的k个特征值
  4. 后处理:使用K-means对特征向量聚类

这个实现包含了谱聚类的核心步骤,可以直接用于实际数据聚类任务。

抱歉,评论功能暂时关闭!