精华内容
下载资源
问答
  • python——聚类

    2020-04-01 16:19:28
    目录Cluster Analysis聚类分析Introduction to Unsupervised Learning无监督学习简介ClusteringDistance or Similarity Function距离或相似度函数Clustering as an Optimization Problem聚类是一个优化问题Types of ...

    Cluster Analysis聚类分析

    1. Introduction to Unsupervised Learning
    2. Clustering
    3. Similarity or Distance Calculation
    4. Clustering as an Optimization Function
    5. Types of Clustering Methods
    6. Partitioning Clustering - KMeans & Meanshift
    7. Hierarchial Clustering - Agglomerative
    8. Density Based Clustering - DBSCAN
    9. Measuring Performance of Clusters

    1.无监督学习简介

    2.聚类

    3.相似度或距离计算

    4.聚类作为优化函数

    5.聚类方法的类型

    6.分区聚类-KMeans和Meanshift

    7.层次聚类-聚集

    8.基于密度的群集-DBSCAN

    9.衡量集群的绩效

    10.比较所有聚类方法

    Introduction to Unsupervised Learning无监督学习简介

    • Unsupervised Learning is a type of Machine learning to draw inferences from unlabelled datasets.
    • Model tries to find relationship between data.
    • Most common unsupervised learning method is clustering which is used for exploratory data analysis to find hidden patterns or grouping in data
    • 无监督学习是一种机器学习,可以从未标记的数据集中得出推论。
    • 模型试图查找数据之间的关系。
    • 最常见的无监督学习方法是聚类,用于探索性数据分析以发现隐藏模式或数据分组

    Clustering

    • A learning technique to group a set of objects in such a way that objects of same group are more similar to each other than from objects of other group.

    • Applications of clustering are as follows

      • Automatically organizing the data
      • Labeling data
      • Understanding hidden structure of data
      • News Cloustering for grouping similar news together
      • Customer Segmentation
      • Suggest social groups
    • 一种将一组对象进行分组的学习技术,使得同一组的对象比来自其他组的对象彼此更相似。

    • 集群的应用如下:

      • 自动整理数据
      • 标签数据
      • 了解数据的隐藏结构
      • 新闻汇总,将相似的新闻分组在一起
      • 客户细分
      • 建议社交团体
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline
    from sklearn.datasets import make_blobs#make_blobs 产生多类数据集,对每个类的中心和标准差有很好的控制
    
    • Generating natural cluster
    • 生成自然簇
    X,y = make_blobs(n_features=2, n_samples=1000, centers=3, cluster_std=1, random_state=3)
    plt.scatter(X[:,0], X[:,1], s=5, alpha=.5)
    

    在这里插入图片描述

    Distance or Similarity Function距离或相似度函数

    • Data belonging to same cluster are similar & data belonging to different cluster are different.
    • We need mechanisms to measure similarity & differences between data.
    • This can be achieved using any of the below techniques.
    • Minkowiski breed of distance calculation:
    • Manhatten (p=1), Euclidian (p=2)

    • Cosine: Suited for text data

    • 属于同一集群的数据相似,而属于不同集群的数据则不同。

    • 我们需要一种机制来衡量数据之间的相似性和差异。

    • 这可以使用以下任何一种技术来实现。

      • Minkowiski距离计算品种:
      • 曼哈顿(p = 1),欧几里得(p = 2)

      • 余弦:适用于文本数据

    from sklearn.metrics.pairwise import euclidean_distances,cosine_distances,manhattan_distances
    X = [[0, 1], [1, 1]]
    print(euclidean_distances(X, X))
    print(euclidean_distances(X, [[0,0]]))
    print(euclidean_distances(X, [[0,0]]))
    print(manhattan_distances(X,X))
    
    [[0. 1.]
     [1. 0.]]
    [[1.        ]
     [1.41421356]]
    [[1.        ]
     [1.41421356]]
    [[0. 1.]
     [1. 0.]]
    

    Clustering as an Optimization Problem聚类是一个优化问题

    • Maximize inter-cluster distances

    • Minimize intra-cluster distances

    • 最大化集群间距离

    • 最小化集群内距离

    Types of Clustering聚类的类型

    • Partitioning methods
      • Partitions n data into k partitions
      • Initially, random partitions are created & gradually data is moved across different partitions.
      • It uses distance between points to optimize clusters.
      • KMeans & Meanshift are examples of Partitioning methods
    • Hierarchical methods
      • These methods does hierarchical decomposition of datasets.
      • One approach is, assume each data as cluster & merge to create a bigger cluster
      • Another approach is start with one cluster & continue splitting
    • Density-based methods
      • All above techniques are distance based & such methods can find only spherical clusters and not suited for clusters of other shapes.
      • Continue growing the cluster untill the density exceeds certain threashold.
    • 分区方法
      • 将n个数据分区为k个分区
      • 最初,创建随机分区,然后逐渐在不同分区之间移动数据。
      • 它使用点之间的距离来优化聚类。
      • KMeans和Meanshift是分区方法的示例
    • 分层方法
      • 这些方法对数据集进行分层分解。
      • 一种方法是,将每个数据假定为群集并合并以创建更大的群集
      • 另一种方法是从一个群集开始并继续拆分
    • 基于密度的方法
      • 所有上述技术都是基于距离的,并且此类方法只能找到球形簇,而不适合其他形状的簇。
      • 继续生长群集,直到密度超过特定阈值。

    Partitioning Method

    KMeans

    • Minimizing creteria : within-cluster-sum-of-squares.
    • The centroids are chosen in such a way that it minimizes within cluster sum of squares.

    • The k-means algorithm divides a set of NN samples XX into KK disjoint clusters CC, each described by the mean of the samples in the cluster. μ\mu

    KMeans Algorithm

    1. Initialize k centroids.
    2. Assign each data to the nearest centroid, these step will create clusters.
    3. Recalculate centroid - which is mean of all data belonging to same cluster.
    4. Repeat steps 2 & 3, till there is no data to reassign a different centroid.

    Animation to explain algo - http://tech.nitoyon.com/en/blog/2013/11/07/k-means/

    KMeans

    • 最小化标准:集群内平方和。

    *选择质心的方式应使其在簇的平方和之内最小。

    • k均值算法将一组$ N 个样本 X 划分为 K 个不相交的聚类 C $,每个聚类由聚类中样本的平均值来描述。 $ \ mu $

    KMeans算法

    1.初始化k个质心。
    2.将每个数据分配给最近的质心,这些步骤将创建聚类。
    3.重新计算质心-这是属于同一群集的所有数据的平均值。
    4.重复步骤2和3,直到没有数据可重新分配其他质心。

    解释算法的动画-http://tech.nitoyon.com/zh/blog/2013/11/07/k-means/

    from sklearn.datasets import make_blobs, make_moons
    from sklearn.datasets import make_circles  
    from sklearn.datasets import make_moons  
    import matplotlib.pyplot as plt  
    import numpy as np  
      
    fig=plt.figure(1)  
    x1,y1=make_circles(n_samples=1000,factor=0.5,noise=0.1)
    # datasets.make_circles()专门用来生成圆圈形状的二维样本.factor表示里圈和外圈的距离之比.每圈共有n_samples/2个点,、
    
    plt.subplot(121)  
    plt.title('make_circles function example')  
    plt.scatter(x1[:,0],x1[:,1],marker='o',c=y1)  
      
    plt.subplot(122)  
    x1,y1=make_moons(n_samples=1000,noise=0.1)  
    plt.title('make_moons function example')  
    plt.scatter(x1[:,0],x1[:,1],marker='o',c=y1)  
    plt.show()
    

    在这里插入图片描述

    X,y = make_blobs(n_features=2, n_samples=1000, cluster_std=.5)
    
    plt.scatter(X[:,0], X[:,1],s=10)
    

    在这里插入图片描述

    from sklearn.cluster import KMeans, MeanShift
    
    kmeans = KMeans(n_clusters=3)
    kmeans.fit(X)
    plt.scatter(X[:,0], X[:,1],s=10, c=kmeans.predict(X))
    

    在这里插入图片描述

    X, y = make_moons(n_samples=1000, noise=.09)
    plt.scatter(X[:,0], X[:,1],s=10)
    

    在这里插入图片描述

    kmeans = KMeans(n_clusters=2)
    kmeans.fit(X)
    plt.scatter(X[:,0], X[:,1],s=10, c=kmeans.predict(X))
    

    在这里插入图片描述

    Limitations of KMeans.KMeans的局限性

    • Assumes that clusters are convex & behaves poorly for elongated clusters.
    • Probability for participation of data to multiple clusters.
    • KMeans tries to find local minima & this depends on init value.
    • 假设簇是凸的,并且对于拉长的簇表现不佳。
    • 数据参与多个集群的可能性。
    • KMeans尝试查找局部最小值,这取决于init值。

    Meanshift

    • Centroid based clustering algorithm.
    • Mode can be understood as highest density of data points.
    • 基于质心的聚类算法。
    • 模式可以理解为最高数据点密度。
    kmeans = KMeans(n_clusters=4)
    centers = [[1, 1], [-.75, -1], [1, -1], [-3, 2]]
    X, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)
    plt.scatter(X[:,0], X[:,1],s=10)
    

    在这里插入图片描述

    kmeans = KMeans(n_clusters=4)
    ms = MeanShift()
    kmeans.fit(X)
    ms.fit(X)
    plt.scatter(X[:,0], X[:,1],s=10, c=ms.predict(X))
    

    在这里插入图片描述

    plt.scatter(X[:,0], X[:,1],s=10, c=kmeans.predict(X))
    

    在这里插入图片描述

    Hierarchial Clustering层次集群

    • A method of clustering where you combine similar clusters to create a cluster or split a cluster into smaller clusters such they now they become better.
    • Two types of hierarchaial Clustering
      • Agglomerative method, a botton-up approach.
      • Divisive method, a top-down approach.
    • 一种群集方法,您可以组合相似的群集以创建群集或将群集拆分为较小的群集,这样它们现在变得更好。
    • 两种类型的层次聚类
      • 凝聚法,自下而上的方法。
      • 分裂方法,自上而下的方法。

    Agglomerative method凝聚法

    • Start with assigning one cluster to each data.
    • Combine clusters which have higher similarity.
    • Differences between methods arise due to different ways of defining distance (or similarity) between clusters. The following sections describe several agglomerative techniques in detail.
      • Single Linkage Clustering
      • Complete linkage clustering
      • Average linkage clustering
      • Average group linkage
    • 从为每个数据分配一个群集开始。
    • 合并具有更高相似性的聚类。
    • 方法之间的差异是由于定义聚类之间距离(或相似性)的方式不同而引起的。 以下各节详细介绍了几种凝聚技术。
      • 单链接集群
      • 完整的链接集群
      • 平均链接聚类
      • 平均组链接
    X, y = make_moons(n_samples=1000, noise=.05)
    plt.scatter(X[:,0], X[:,1],s=10)
    

    在这里插入图片描述

    from sklearn.cluster import AgglomerativeClustering
    agc = AgglomerativeClustering(linkage='single')
    agc.fit(X)
    plt.scatter(X[:,0], X[:,1],s=10,c=agc.labels_)
    

    在这里插入图片描述

    agc.labels_
    
    array([1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1,
           0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1,
           1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
           0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
           1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
           0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1,
           0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0,
           0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0,
           1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0,
           1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0,
           0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
           1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
           0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0,
           0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1,
           1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0,
           0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1,
           0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
           1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1,
           1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
           1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1,
           0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
           0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,
           0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1,
           1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0,
           1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1,
           0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1,
           1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0,
           0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0,
           1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1,
           0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
           0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0,
           1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
           0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
           0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
           0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0,
           0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0,
           1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1,
           1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
           1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1,
           0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1,
           1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0,
           1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0,
           1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1,
           1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0,
           0, 1, 1, 0, 0, 1, 1, 1, 1, 1], dtype=int64)
    

    Density Based Clustering - DBSCAN

    centers = [[1, 1], [-1, -1], [1, -1]]
    X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4,
                                random_state=0)
    plt.scatter(X[:,0], X[:,1],s=10)
    

    在这里插入图片描述

    from sklearn.cluster import DBSCAN
    from sklearn.preprocessing import StandardScaler
    X = StandardScaler().fit_transform(X)
    
    db = DBSCAN(eps=0.3, min_samples=10).fit(X)
    core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
    core_samples_mask[db.core_sample_indices_] = True
    labels = db.labels_
    
    plt.scatter(X[:,0], X[:,1],s=10,c=labels)
    

    在这里插入图片描述

    Measuring Performance of Clusters衡量聚类的性能

    • Two forms of evaluation
    • supervised, which uses a ground truth class values for each sample.
      • completeness_score
      • homogeneity_score
    • unsupervised, which measures the quality of model itself
      • silhoutte_score
      • calinski_harabaz_score
    • 两种评估形式
    • 有监督的,它对每个样本使用基本事实类别值。
      • completeness_score
      • homogenity_score
    • 无人监督,它衡量模型本身的质量
      • silhoutte_score
      • calinski_harabaz_score

    completeness_score

    • A clustering result satisfies completeness if all the data points that are members of a given class are elements of the same cluster.
    • Accuracy is 1.0 if data belonging to same class belongs to same cluster, even if multiple classes belongs to same cluster
    • 如果属于给定类的所有数据点都是同一群集的元素,则群集结果将满足完整性要求
    • 如果属于同一类别的数据属于同一群集,则即使多个类别属于同一群集,精度也为1.0
    from sklearn.metrics.cluster import completeness_score
    
    completeness_score( labels_true=[10,10,11,11],labels_pred=[1,1,0,0])
    
    1.0
    
    • The acuracy is 1.0 because all the data belonging to same class belongs to same cluster
    completeness_score( labels_true=[11,22,22,11],labels_pred=[1,0,1,1])
    
    0.3836885465963443
    
    • The accuracy is .3 because class 1 - [11,22,11], class 2 - [22]
    print(completeness_score([10, 10, 11, 11], [0, 0, 0, 0]))
    
    1.0
    
    homogeneity_score
    • A clustering result satisfies homogeneity if all of its clusters contain only data points which are members of a single class.
    from sklearn.metrics.cluster import homogeneity_score
    
    homogeneity_score([0, 0, 1, 1], [1, 1, 0, 0])
    
    1.0
    
    homogeneity_score([0, 0, 1, 1], [0, 1, 2, 3])
    
    0.9999999999999999
    
    homogeneity_score([0, 0, 0, 0], [1, 1, 0, 0])
    
    1.0
    
    • Same class data is broken into two clusters

    silhoutte_score

    • The Silhouette Coefficient is calculated using the mean intra-cluster distance (a) and the mean nearest-cluster distance (b) for each sample.
    • The Silhouette Coefficient for a sample is (b - a) / max(a, b). To clarify, b is the distance between a sample and the nearest cluster that the sample is not a part of.
    Example : Selecting the number of clusters with silhouette analysis on KMeans clustering
    from sklearn.datasets import make_blobs
    X, Y = make_blobs(n_samples=500,
                      n_features=2,
                      centers=4,
                      cluster_std=1,
                      center_box=(-10.0, 10.0),
                      shuffle=True,
                      random_state=1)
    
    plt.scatter(X[:,0],X[:,1],s=10)
    

    在这里插入图片描述

    range_n_clusters = [2, 3, 4, 5, 6]
    from sklearn.cluster import KMeans
    from sklearn.metrics import silhouette_score
    for n_cluster in range_n_clusters:
        kmeans = KMeans(n_clusters=n_cluster)
        kmeans.fit(X)
        labels = kmeans.predict(X)
        print (n_cluster, silhouette_score(X,labels))
    
    2 0.7049787496083262
    3 0.5882004012129721
    4 0.6505186632729437
    5 0.5745029081702377
    6 0.4544511749648251
    
    • Optimal number of clusters seems to be 2

    calinski_harabaz_score

    • The score is defined as ratio between the within-cluster dispersion and the between-cluster dispersion.
    • 群集的最佳数量似乎是2
    • 分数定义为群集内分散度和群集间分散度之间的比率。
    from sklearn.metrics import calinski_harabaz_score
    
    for n_cluster in range_n_clusters:
        kmeans = KMeans(n_clusters=n_cluster)
        kmeans.fit(X)
        labels = kmeans.predict(X)
        print (n_cluster, calinski_harabaz_score(X,labels))
    
    2 1604.112286409658
    3 1809.991966958033
    4 2704.4858735121097
    5 2281.933655783649
    6 2016.011232059114
    
    展开全文
  • python 文本聚类

    千次阅读 2017-10-23 21:34:56
    在本教程中,我会利用 Python 来说明怎样聚类一系列的文档。我所演示的实例会识别出 top 100 电影的(来自 IMDB 列表)剧情简介的隐藏结构。关于这个例子的详细讨论在初始版本里。本教程包括:对所有剧情简介分词...
    原地址:http://python.jobbole.com/85481/

    title

    在本教程中,我会利用 Python 来说明怎样聚类一系列的文档。我所演示的实例会识别出 top 100 电影的(来自 IMDB 列表)剧情简介的隐藏结构。关于这个例子的详细讨论在初始版本里。本教程包括:对所有剧情简介分词(tokenizing)和词干化(stemming)

    整个项目在我的 github repo 都可以找到。其中‘cluster_analysis ‘工作簿是一个完整的版本;‘cluster_analysis_web’ 为了创建教程则经过了删减。欢迎下载代码并使用‘cluster_analysis’ 进行单步调试(step through)。

    如果你有任何问题,欢迎用推特来联系我 @brandonmrose

    在此之前,我先在前面导入所有需要用到的库

    出于走查的目的,想象一下我有 2 个主要的列表:

    • ‘titles’:按照排名的影片名称
    • ‘synopses’:对应片名列表的剧情简介

    我在 github 上 po 出来的完整工作簿已经导入了上述列表,但是为了简洁起见,我会直接使用它们。其中最最重要的是 ‘synopses’ 列表了,‘titles’ 更多是作为了标记用的。

    停用词,词干化与分词

    本节我将会定义一些函数对剧情简介进行处理。首先,我载入 NLTK 的英文停用词列表。停用词是类似“a”,“the”,或者“in”这些无法传达重要意义的词。我相信除此之外还有更好的解释。

    接下来我导入 NLTK 中的 Snowball 词干分析器(Stemmer)词干化(Stemming)的过程就是将词打回原形。

    以下我定义了两个函数:

    • tokenize_and_stem:对每个词例(token)分词(tokenizes)(将剧情简介分割成单独的词或词例列表)并词干化
    • tokenize_only: 分词即可

    我利用上述两个函数创建了一个重要的字典,以防我在后续算法中需要使用词干化后的词(stems)。出于展示的目的,后面我又会将这些词转换回它们原本的的形式。猜猜看会怎样,我实在想试试看!

    接下来我会使用上述词干化/分词和分词函数遍历剧情简介列表以生成两个词汇表:经过词干化和仅仅经过分词后。

    利用上述两个列表,我创建了一个 pandas 的 DataFrame,以词干化后的词汇表作为索引,分词后的词为列。这么做便于观察词干化后的词转换回完整的词例。以下展示词干化后的词变回原词例是一对多(one to many)的过程:词干化后的“run”能够关联到“ran”,“runs”,“running”等等。在我看来这很棒——我非常愿意将我需要观察的词干化过后的词转换回第一个联想到的词例。

    你会注意到有些重复的地方。我可以把它清理掉,不过鉴于 DataFrame 只有 312209 项,并不是很庞大,可以用 stem-index 来观察词干化后的词。

    Tf-idf 与文本相似度

    下面,我定义词频-逆向文件频率(tf-idf)的向量化参数,把剧情简介列表都转换成 tf-idf 矩阵。

    为了得到 TF-IDF 矩阵,首先计算词在文档中的出现频率,它会被转换成文档-词矩阵(dtm),也叫做词频(term frequency)矩阵。dtm 的例子如下图所示:

    tf-idf

    接着使用 TF-IDF 权重:某些词在某个文档中出现频率高,在其他文中却不常出现,那么这些词具有更高的 TF-IDF 权重,因为这些词被认为在相关文档中携带更多信息。

    注意我下面定义的几个参数:

    • max_df:这个给定特征可以应用在 tf-idf 矩阵中,用以描述单词在文档中的最高出现率。假设一个词(term)在 80% 的文档中都出现过了,那它也许(在剧情简介的语境里)只携带非常少信息。
    • min_df:可以是一个整数(例如5)。意味着单词必须在 5 个以上的文档中出现才会被纳入考虑。在这里我设置为 0.2;即单词至少在 20% 的文档中出现 。因为我发现如果我设置更小的 min_df,最终会得到基于姓名的聚类(clustering)——举个例子,好几部电影的简介剧情中老出现“Michael”或者“Tom”这些名字,然而它们却不携带什么真实意义。
    • ngram_range:这个参数将用来观察一元模型(unigrams),二元模型( bigrams) 和三元模型(trigrams)。参考n元模型(n-grams)

    “terms” 这个变量只是 tf-idf 矩阵中的特征(features)表,也是一个词汇表。

    dist 变量被定义为 1 – 每个文档的余弦相似度。余弦相似度用以和 tf-idf 相互参照评价。可以评价全文(剧情简介)中文档与文档间的相似度。被 1 减去是为了确保我稍后能在欧氏(euclidean)平面(二维平面)中绘制余弦距离。

    注意 dist 可以用以评估任意两个或多个剧情简介间的相似度。

    K-means 聚类

    下面开始好玩的部分。利用 tf-idf 矩阵,你可以跑一长串聚类算法来更好地理解剧情简介集里的隐藏结构。我首先用 k-means 算法。这个算法需要先设定聚类的数目(我设定为 5)。每个观测对象(observation)都会被分配到一个聚类,这也叫做聚类分配(cluster assignment)。这样做是为了使组内平方和最小。接下来,聚类过的对象通过计算来确定新的聚类质心(centroid)。然后,对象将被重新分配到聚类,在下一次迭代操作中质心也会被重新计算,直到算法收敛。

    跑了几次这个算法以后我发现得到全局最优解(global optimum)的几率要比局部最优解(local optimum)大。

    利用 joblib.dump pickle 模型(model),一旦算法收敛,重载模型并分配聚类标签(labels)。

    下面,我创建了一个字典,包含片名,排名,简要剧情,聚类分配,还有电影类型(genre)(排名和类型是从 IMDB 上爬下来的)。

    为了方便起见,我将这个字典转换成了 Pandas DataFrame。我是 Pandas 的脑残粉,我强烈建议你了解一下它惊艳的功能。这些我下面就会使用到,但不会深入。

    clusters 4 和 clusters 0 的排名最低,说明它们包含的影片在 top 100 列表中相对没那么棒。

    在这选取 n(我选 6 个) 个离聚类质心最近的词对聚类进行一些好玩的索引(indexing)和排列(sorting)。这样可以更直观观察聚类的主要主题。

    聚类中的前几项:

    聚类 0 中的单词: family, home, mother, war, house, dies,

    聚类 0 中的片名: Schindler’s List, One Flew Over the Cuckoo’s Nest, Gone with the Wind, The Wizard of Oz, Titanic, Forrest Gump, E.T. the Extra-Terrestrial, The Silence of the Lambs, Gandhi, A Streetcar Named Desire, The Best Years of Our Lives, My Fair Lady, Ben-Hur, Doctor Zhivago, The Pianist, The Exorcist, Out of Africa, Good Will Hunting, Terms of Endearment, Giant, The Grapes of Wrath, Close Encounters of the Third Kind, The Graduate, Stagecoach, Wuthering Heights,

    聚类 1 中的单词: police, car, killed, murders, driving, house,

    聚类 1 中的片名: Casablanca, Psycho, Sunset Blvd., Vertigo, Chinatown, Amadeus, High Noon, The French Connection, Fargo, Pulp Fiction, The Maltese Falcon, A Clockwork Orange, Double Indemnity, Rebel Without a Cause, The Third Man, North by Northwest,

    聚类 2 中的单词: father, new, york, new, brothers, apartments,

    聚类 2 中的片名: The Godfather, Raging Bull, Citizen Kane, The Godfather: Part II, On the Waterfront, 12 Angry Men, Rocky, To Kill a Mockingbird, Braveheart, The Good, the Bad and the Ugly, The Apartment, Goodfellas, City Lights, It Happened One Night, Midnight Cowboy, Mr. Smith Goes to Washington, Rain Man, Annie Hall, Network, Taxi Driver, Rear Window,

    聚类 3 中的单词: george, dance, singing, john, love, perform,

    聚类 3 中的片名: West Side Story, Singin’ in the Rain, It’s a Wonderful Life, Some Like It Hot, The Philadelphia Story, An American in Paris, The King’s Speech, A Place in the Sun, Tootsie, Nashville, American Graffiti, Yankee Doodle Dandy,

    聚类 4 中的单词: killed, soldiers, captain, men, army, command,

    聚类 4 中的片名: The Shawshank Redemption, Lawrence of Arabia, The Sound of Music, Star Wars, 2001: A Space Odyssey, The Bridge on the River Kwai, Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb, Apocalypse Now, The Lord of the Rings: The Return of the King, Gladiator, From Here to Eternity, Saving Private Ryan, Unforgiven, Raiders of the Lost Ark, Patton, Jaws, Butch Cassidy and the Sundance Kid, The Treasure of the Sierra Madre, Platoon, Dances with Wolves, The Deer Hunter, All Quiet on the Western Front, Shane, The Green Mile, The African Queen, Mutiny on the Bounty,

    多维尺度分析(Multidimensional scaling)

    利用下面多维尺度分析(MDS)的代码将距离矩阵转化为一个二维数组。我并不想假装我很了解MDS,不过这个算法很管用。另外可以用 特征降维(principal component analysis)来完成这个任务。

    可视化文档聚类

    本节中,我会演示怎样利用 matplotlib 和 mpld3(将 matplotlib 封装成 D3.js)来实现文档聚类的可视化。

    首先,我定义了一些字典,让聚类的编号和聚类绘色,聚类名称一一对应。其中聚类对应的名称是从离聚类质心最近的单词中挑选出来的。

    下面我会用 matplotlib 来绘制彩色的带标签的观测对象(影片,片名)。关于 matplotlib 绘图我不想讨论太多,但我尽可能提供一些有用的注释。

    k-means

    绘制的聚类分布图看起来不错,但是重叠在一起的标签真是亮瞎了眼。因为之前使用过 D3.js,所以我知道有个解决方案是基于浏览器和 javascript 交互的。所幸我最近偶然发现了 mpld3,是基于 matplotlib 的 D3 封装。Mpld3 主要可以让你使用 matplotlib 的语法实现网页交互。它非常容易上手,当你遇到感兴趣的内容,鼠标停驻的时候,利用高效的接口可以添加气泡提示。

    另外,它还提供了缩放和拖动这么炫的功能。以下的 javascript 片段主要自定义了缩放和拖动的位置。别太担心,实际上你用不到它,但是稍后导出到网页的时候有利于格式化。你唯一想要改变的应该是借助 x 和 y 的 attr 来改变工具栏的位置。

    下面是对于交互式散点图的实际操作。我同样不会深入这个问题因为是直接从 mpld3 的例程移植过来的。虽然我用 pandas 对聚类进行了归类,但它们一一迭代后会分布在散点图上。和原生 D3 相比,用 mpld3 来做这项工作并且嵌入到 python 的工作簿中简单多了。如果你看了我网站上的其它内容,你就知道我有多么爱 D3 了。但以后一些基本的交互我可能还是会用 mpld3。

    记住 mpld3 还可以自定义 CSS,像我设计的字体,坐标轴还有散点图左边的间距(margin)。