【问题标题】:How can GridSearchCV be used for clustering (MeanShift or DBSCAN)?GridSearchCV 如何用于聚类(MeanShift 或 DBSCAN)?
【发布时间】:2014-10-27 07:24:21
【问题描述】:

我正在尝试使用scikit-learn 对一些文本文档进行聚类。我正在尝试 DBSCAN 和 MeanShift,并想确定哪些超参数(例如,bandwidth 用于 MeanShift,eps 用于 DBSCAN)最适合我正在使用的数据类型(新闻文章)。

我有一些由预先标记的集群组成的测试数据。我一直在尝试使用scikit-learnGridSearchCV,但不明白在这种情况下如何(或是否可以)应用,因为它需要拆分测试数据,但我想运行评估整个数据集并将结果与​​预先标记的数据进行比较。

我一直在尝试指定一个评分函数,将估算器的标签与真实标签进行比较,但它当然不起作用,因为只有数据样本被聚类,而不是全部。

这里有什么合适的方法?

【问题讨论】:

  • 你最后做了什么?
  • Scikit learn 提供来自 sklearn.model_selection 的 ParameterGrid,它应该可以帮助您循环超参数网格。

标签: flutter scikit-learn cluster-analysis


【解决方案1】:

以下 DBSCAN 函数可能会有所帮助。我已经编写它来迭代超参数 eps 和 min_samples 并包含 min 和 max 集群的可选参数。由于 DBSCAN 是无监督的,所以我没有包含评估参数。

def dbscan_grid_search(X_data, lst, clst_count, eps_space = 0.5,
                       min_samples_space = 5, min_clust = 0, max_clust = 10):

    """
Performs a hyperparameter grid search for DBSCAN.

Parameters:
    * X_data            = data used to fit the DBSCAN instance
    * lst               = a list to store the results of the grid search
    * clst_count        = a list to store the number of non-whitespace clusters
    * eps_space         = the range values for the eps parameter
    * min_samples_space = the range values for the min_samples parameter
    * min_clust         = the minimum number of clusters required after each search iteration in order for a result to be appended to the lst
    * max_clust         = the maximum number of clusters required after each search iteration in order for a result to be appended to the lst


Example:

# Loading Libraries
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
import pandas as pd

# Loading iris dataset
iris = datasets.load_iris()
X = iris.data[:, :] 
y = iris.target

# Scaling X data
dbscan_scaler = StandardScaler()

dbscan_scaler.fit(X)

dbscan_X_scaled = dbscan_scaler.transform(X)

# Setting empty lists in global environment
dbscan_clusters = []
cluster_count   = []


# Inputting function parameters
dbscan_grid_search(X_data = dbscan_X_scaled,
                   lst = dbscan_clusters,
                   clst_count = cluster_count
                   eps_space = pd.np.arange(0.1, 5, 0.1),
                   min_samples_space = pd.np.arange(1, 50, 1),
                   min_clust = 3,
                   max_clust = 6)

"""

    # Importing counter to count the amount of data in each cluster
    from collections import Counter


    # Starting a tally of total iterations
    n_iterations = 0


    # Looping over each combination of hyperparameters
    for eps_val in eps_space:
        for samples_val in min_samples_space:

            dbscan_grid = DBSCAN(eps = eps_val,
                                 min_samples = samples_val)


            # fit_transform
            clusters = dbscan_grid.fit_predict(X = X_data)


            # Counting the amount of data in each cluster
            cluster_count = Counter(clusters)


            # Saving the number of clusters
            n_clusters = sum(abs(pd.np.unique(clusters))) - 1


            # Increasing the iteration tally with each run of the loop
            n_iterations += 1


            # Appending the lst each time n_clusters criteria is reached
            if n_clusters >= min_clust and n_clusters <= max_clust:

                dbscan_clusters.append([eps_val,
                                        samples_val,
                                        n_clusters])


                clst_count.append(cluster_count)

    # Printing grid search summary information
    print(f"""Search Complete. \nYour list is now of length {len(lst)}. """)
    print(f"""Hyperparameter combinations checked: {n_iterations}. \n""")

【讨论】:

    【解决方案2】:

    您是否考虑过自己实现搜索

    实现 for 循环并不是特别难。即使你想优化两个参数,它仍然相当容易。

    对于 DBSCAN 和 MeanShift,我建议首先了解您的相似性度量。根据对度量的理解而不是参数优化来匹配某些标签(这有很高的过度拟合风险)来选择参数更有意义。

    换句话说,两篇文章应该在多远的距离被聚类?

    如果这个距离从一个数据点到另一个数据点变化太大,这些算法将严重失败;并且您可能需要找到一个归一化的距离函数,以使实际的相似度值再次有意义。 TF-IDF 是文本的标准,但主要是在 retrieval 上下文中。它们在集群环境中可能会更糟糕。

    还要注意 MeanShift(类似于 k-means)需要重新计算坐标 - 在文本数据上,这可能会产生不希望的结果;更新后的坐标实际上变得更糟,而不是更好。

    【讨论】:

    • 是的,我正在自己实施它。我只是想知道scikit-learn 是否支持这种开箱即用的功能,而我忽略了一些东西。我的计划是在几个不同的预先标记的数据集上运行网格搜索,并深入了解您指出的潜在问题 - 感谢您指出风险!
    • sklearn.cross_validation 有各种迭代器,可以产生数据集的拆分(交叉验证、随机拆分等)。这些应该使这个循环很容易编写。
    猜你喜欢
    • 2015-03-08
    • 2015-09-13
    • 2016-10-30
    • 2014-07-11
    • 2020-02-14
    • 2016-04-07
    • 2018-09-30
    • 2014-07-10
    • 2015-07-20
    相关资源
    最近更新 更多