首页 > 解决方案 > KMeans 聚类中种子和 num_runs 的重要性

问题描述

ML 新手,因此试图理解以下代码。具体来说

  1. for run in np.arange(1, num_runs+1)中,这个循环需要什么?为什么作者不使用setMaxIter方法KMeans
  2. 播种在聚类中的重要性是什么?
  3. 为什么作者选择显式设置种子而不是使用默认种子?
from pyspark.ml.clustering import KMeans
from pyspark.ml.evaluation import ClusteringEvaluator
    
def optimal_k(df_in,index_col,k_min, k_max,num_runs):
        '''
        Determine optimal number of clusters by using Silhoutte Score Analysis.
        :param df_in: the input dataframe
        :param index_col: the name of the index column
        :param k_min: the train dataset
        :param k_min: the minmum number of the clusters
        :param k_max: the maxmum number of the clusters
        :param num_runs: the number of runs for each fixed clusters
    
        :return k: optimal number of the clusters
        :return silh_lst: Silhouette score
        :return r_table: the running results table
    
        :author: Wenqiang Feng
        :email:  von198@gmail.com.com
        '''
    
        start = time.time()
        silh_lst = []
        k_lst = np.arange(k_min, k_max+1)
    
        r_table = df_in.select(index_col).toPandas()
        r_table = r_table.set_index(index_col)
        centers = pd.DataFrame()
    
        for k in k_lst:
            silh_val = []
            for run in np.arange(1, num_runs+1):
    
                # Trains a k-means model.
                kmeans = KMeans()\
                        .setK(k)\
                        .setSeed(int(np.random.randint(100, size=1)))
                model = kmeans.fit(df_in)
    
                # Make predictions
                predictions = model.transform(df_in)
                r_table['cluster_{k}_{run}'.format(k=k, run=run)]= predictions.select('prediction').toPandas()
    
                # Evaluate clustering by computing Silhouette score
                evaluator = ClusteringEvaluator()
                silhouette = evaluator.evaluate(predictions)
                silh_val.append(silhouette)
    
            silh_array=np.asanyarray(silh_val)
            silh_lst.append(silh_array.mean())
    
        elapsed =  time.time() - start
    
        silhouette = pd.DataFrame(list(zip(k_lst,silh_lst)),columns = ['k', 'silhouette'])
    
        print('+------------------------------------------------------------+')
        print("|         The finding optimal k phase took %8.0f s.       |" %(elapsed))
        print('+------------------------------------------------------------+')
    
    
        return k_lst[np.argmax(silh_lst, axis=0)], silhouette , r_table

标签: pandasmachine-learningpysparkcluster-analysishierarchical-clustering

解决方案


我将尝试根据我对材料的阅读来回答您的问题。

  1. 这个循环的原因是作者seed为每个循环设置了一个新的int(np.random.randint(100, size=1))。如果特征变量表现出自动将它们分组到可见集群中的模式,那么起始种子不应该对最终集群成员产生影响。但是,如果数据是均匀分布的,那么我们最终可能会根据初始随机变量得到不同的集群成员。我相信作者会为每次运行更改这些种子以测试不同的初始分布。使用setMaxIter将设置相同的最大迭代seed(初始分布)。
  2. 与上述类似 - 种子定义了k您将围绕其进行聚类的点的初始分布。根据您的基础数据分布,集群可以在不同的最终分布中收敛。
  3. 作者可以控制种子,如第 1 点和第 2 点所述。您可以查看代码根据需要在集群周围收敛的种子,以及您可能无法收敛的种子。此外,如果您迭代 100 个不同的种子,并且您的代码仍然会聚到相同的最终集群中,您可以删除默认种子,因为它可能无关紧要。另一个用途是从更软件工程的角度来看,例如,如果您想为您的代码编写测试并且不希望它随机失败,那么设置显式种子非常重要。

推荐阅读