seed 和 num_runs 在 KMeans 聚类中的重要性
Importance of seed and num_runs in the KMeans clustering
ML 新手,因此试图理解以下代码。具体
- 在
for run in np.arange(1, num_runs+1)
中,这个循环需要什么?为什么作者没有使用KMeans
的setMaxIter
方法?
- 播种在聚类中的重要性是什么?
- 为什么作者选择明确设置种子而不是使用默认种子?
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
我会根据我对 material 的阅读来回答您的问题。
- 这个循环的原因是作者使用
int(np.random.randint(100, size=1))
为每个循环设置了一个新的seed
。如果特征变量表现出自动将它们分组到可见簇中的模式,则起始种子不应对最终簇成员产生影响。然而,如果数据是均匀分布的,那么我们可能会根据初始随机变量得到不同的集群成员。我相信作者正在为每个 运行 测试不同的初始分布更改这些种子。使用 setMaxIter
将为相同的 seed
(初始分布)设置最大迭代次数。
- 与上述类似 - 种子定义
k
点的初始分布,您将围绕这些点进行聚类。根据您的基础数据分布,集群可以收敛于不同的最终分布。
- 作者可以控制种子,如第 1 点和第 2 点中所讨论的。您可以看到您的代码根据需要围绕集群收敛了哪些种子,以及您可能无法收敛哪些种子。此外,如果您迭代 100 个不同的种子并且您的代码仍然收敛到相同的最终集群,您可以删除默认种子,因为它可能无关紧要。另一个用途是从更多软件工程的角度来看,如果您想为您的代码编写测试并且不希望它随机失败,则设置显式种子非常重要。
ML 新手,因此试图理解以下代码。具体
- 在
for run in np.arange(1, num_runs+1)
中,这个循环需要什么?为什么作者没有使用KMeans
的setMaxIter
方法? - 播种在聚类中的重要性是什么?
- 为什么作者选择明确设置种子而不是使用默认种子?
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
我会根据我对 material 的阅读来回答您的问题。
- 这个循环的原因是作者使用
int(np.random.randint(100, size=1))
为每个循环设置了一个新的seed
。如果特征变量表现出自动将它们分组到可见簇中的模式,则起始种子不应对最终簇成员产生影响。然而,如果数据是均匀分布的,那么我们可能会根据初始随机变量得到不同的集群成员。我相信作者正在为每个 运行 测试不同的初始分布更改这些种子。使用setMaxIter
将为相同的seed
(初始分布)设置最大迭代次数。 - 与上述类似 - 种子定义
k
点的初始分布,您将围绕这些点进行聚类。根据您的基础数据分布,集群可以收敛于不同的最终分布。 - 作者可以控制种子,如第 1 点和第 2 点中所讨论的。您可以看到您的代码根据需要围绕集群收敛了哪些种子,以及您可能无法收敛哪些种子。此外,如果您迭代 100 个不同的种子并且您的代码仍然收敛到相同的最终集群,您可以删除默认种子,因为它可能无关紧要。另一个用途是从更多软件工程的角度来看,如果您想为您的代码编写测试并且不希望它随机失败,则设置显式种子非常重要。