【问题标题】:Grid search for hyperparameter evaluation of clustering in scikit-learnscikit-learn 中聚类超参数评估的网格搜索
【发布时间】:2016-04-09 05:45:02
【问题描述】:

我正在对大约 100 条记录(未标记)的样本进行聚类,并尝试使用 grid_search 来评估具有各种超参数的聚类算法。我正在使用 silhouette_score 进行评分,效果很好。

我这里的问题是我不需要使用GridSearchCV/RandomizedSearchCV的交叉验证方面,但是我找不到简单的GridSearch/RandomizedSearch。我可以自己编写,但 ParameterSamplerParameterGrid 对象非常有用。

我的下一步是继承BaseSearchCV 并实现我自己的_fit() 方法,但我认为有必要问一下是否有更简单的方法可以做到这一点,例如通过传递一些东西给cv 参数?

def silhouette_score(estimator, X):
    clusters = estimator.fit_predict(X)
    score = metrics.silhouette_score(distance_matrix, clusters, metric='precomputed')
    return score

ca = KMeans()
param_grid = {"n_clusters": range(2, 11)}

# run randomized search
search = GridSearchCV(
    ca,
    param_distributions=param_dist,
    n_iter=n_iter_search,
    scoring=silhouette_score,
    cv= # can I pass something here to only use a single fold?
    )
search.fit(distance_matrix)

【问题讨论】:

  • 您不会在 无监督 数据挖掘中进行交叉验证(或网格搜索)。只需计算 10 次 k-means 运行,然后使用最好的。
  • 显然你不做交叉验证,但为什么不做网格搜索给定适当的评分指标,如轮廓分数?
  • 另外,kmeans 在这里只是一个例子。我想测试一些不同的算法及其超参数。
  • 你还不如直接优化轮廓。不要指望聚类结果会以这种方式真正改善。最后,您只需看看哪些参数与 Silhouette 最吻合。这只是 SSE 之外的另一个标准。
  • 啊,我明白了。不过,我可能想在评分方法中添加额外的东西(簇的首选大小、簇大小的相似性等),所以我真的在寻找一种类似于网格搜索的方法。不过感谢您的建议。

标签: python scikit-learn cluster-analysis scoring


【解决方案1】:

clusteval 库将帮助您评估数据并找到最佳聚类数。该库包含五种可用于评估聚类的方法:silhouettedbindexderivativedbscan 和 hdbscan.

pip install clusteval

根据您的数据,可以选择评估方法。

# Import library
from clusteval import clusteval

# Set parameters, as an example dbscan
ce = clusteval(method='dbscan')

# Fit to find optimal number of clusters using dbscan
results= ce.fit(X)

# Make plot of the cluster evaluation
ce.plot()

# Make scatter plot. Note that the first two coordinates are used for plotting.
ce.scatter(X)

# results is a dict with various output statistics. One of them are the labels.
cluster_labels = results['labx']

【讨论】:

  • 这非常酷 - 知道如何将其放入管道中以优化早期阶段,例如 TFIDF 等吗?
【解决方案2】:

好的,这可能是一个老问题,但我使用这种代码:

首先,我们要生成所有可能的参数组合:

def make_generator(parameters):
    if not parameters:
        yield dict()
    else:
        key_to_iterate = list(parameters.keys())[0]
        next_round_parameters = {p : parameters[p]
                    for p in parameters if p != key_to_iterate}
        for val in parameters[key_to_iterate]:
            for pars in make_generator(next_round_parameters):
                temp_res = pars
                temp_res[key_to_iterate] = val
                yield temp_res

然后创建一个循环出来:

# add fix parameters - here - it's just a random one
fixed_params = {"max_iter":300 } 

param_grid = {"n_clusters": range(2, 11)}

for params in make_generator(param_grid):
    params.update(fixed_params)
    ca = KMeans( **params )
    ca.fit(_data)
    labels = ca.labels_
    # Estimate your clustering labels and 
    # make decision to save or discard it!

当然,它可以组合成一个漂亮的函数。所以这个解决方案主要是一个例子。

希望它对某人有所帮助!

【讨论】:

    【解决方案3】:

    最近我遇到了类似的问题。我定义了自定义可迭代cv_custom,它定义了拆分策略,并且是交叉验证参数cv 的输入。这个可迭代的每个折叠应该包含一对,其中的样本由它们的索引标识,例如([fold1_train_ids], [fold1_test_ids]), ([fold2_train_ids], [fold2_test_ids]), ... 在我们的例子中,我们只需要一对一对,其中包含训练中所有示例的索引以及测试部分中的索引([train_ids], [test_ids])

    N = len(distance_matrix)
    cv_custom = [(range(0,N), range(0,N))]
    scores = cross_val_score(clf, X, y, cv=cv_custom)
    

    【讨论】:

      猜你喜欢
      • 2014-10-03
      • 2016-07-12
      • 2017-03-27
      • 2019-06-02
      • 2019-06-10
      • 2013-06-04
      • 1970-01-01
      • 2017-03-30
      • 2017-12-29
      相关资源
      最近更新 更多