k-fold交叉验证确定k-means中的k?
Posted
技术标签:
【中文标题】k-fold交叉验证确定k-means中的k?【英文标题】:k-fold Cross Validation for determining k in k-means? 【发布时间】:2011-10-01 12:45:49 【问题描述】:在文档聚类过程中,作为数据预处理步骤,我首先应用奇异向量分解得到U
、S
和Vt
,然后通过选择合适数量的特征值截断@987654326 @,现在从我读到的 here 中,这给了我一个很好的文档-文档相关性。现在我正在对矩阵Vt
的列进行聚类,以将相似的文档聚类在一起,为此我选择了 k-means,初始结果看起来对我来说是可以接受的(k = 10 个聚类),但我想更深入地挖掘关于选择 k 值本身。为了确定 k-means 中 k
的簇数,我是 suggested 来查看交叉验证。
在实现它之前,我想弄清楚是否有使用 numpy 或 scipy 的内置方法来实现它。目前,我执行kmeans
的方式是简单地使用scipy 中的函数。
import numpy, scipy
# Preprocess the data and compute svd
U, S, Vt = svd(A) # A is the TFIDF representation of the original term-document matrix
# Obtain the document-document correlations from Vt
# This 50 is the threshold obtained after examining a scree plot of S
docvectors = numpy.transpose(self.Vt[0:50, 0:])
# Prepare the data to run k-means
whitened = whiten(docvectors)
res, idx = kmeans2(whitened, 10, iter=20)
假设我的方法到目前为止是正确的(如果我遗漏了一些步骤,请纠正我),在这个阶段,使用输出执行交叉验证的标准方法是什么?任何关于如何将其应用于 k-means 的参考/实现/建议将不胜感激。
【问题讨论】:
【参考方案1】:要运行 k 折交叉验证,您需要一些质量度量来进行优化。这可以是准确度或F1 等分类度量,也可以是V-measure 等专门度量。
即使是我所知道的聚类质量度量也需要一个标记的数据集(“ground truth”)才能发挥作用;与分类的区别在于您只需要标记部分数据进行评估,而 k-means 算法可以利用所有数据来确定质心,从而确定聚类。
V-measure 和 several other scores 在 scikit-learn 中实现,以及通用的 cross validation 代码和“网格搜索”模块,该模块使用 k 折 CV 根据指定的评估度量进行优化。 免责声明:我参与了 scikit-learn 的开发,尽管我没有编写任何提到的代码。
【讨论】:
感谢您的回复。我很抱歉,但在这一点上我有点困惑。所以我的要点是我不能对k-means的输出使用k-fold交叉验证(因为k-means的输出正是我指定的,数据分类到我指定的集群中)并且我需要手动标记我的一些数据集?我想我的问题更多的是,我将如何利用这种技术来确定 k-means 中的 k,或者我是否应该遵循一些额外的步骤。 @Legend:嗯,交叉验证对于找到正确的参数非常有用,但是由于它需要标记一些数据并且更改 k 实际上会更改 标签的数量,它可能不是优化这个特定参数的最佳技术。我不能再帮你了;我不是每天都进行聚类。 太棒了!谢谢你澄清这一点。我的另一个问题向我建议了这种技术。我会寻找其他一些方法。再次感谢您的宝贵时间。【参考方案2】:确实要使用 F1-score 或 V-Measure 作为评分函数进行传统的交叉验证,您需要一些标记数据作为基本事实。但在这种情况下,您可以只计算地面实况数据集中的类数并将其用作 K 的最佳值,因此不需要交叉验证。
或者,您可以使用集群稳定性度量作为无监督的性能评估,并为此执行某种交叉验证程序。然而,这还没有在 scikit-learn 中实现,尽管它仍然在我的个人待办事项列表中。
您可以在以下answer on metaoptimize.com/qa 中找到有关此方法的更多信息。特别是你应该阅读Clustering Stability: An Overview by Ulrike von Luxburg。
【讨论】:
【参考方案3】:他们在这里使用 insidess 来找到最佳数量的集群。 “withinss”是返回的 kmeans 对象的一个属性。这可以用来找到最小的“错误”
https://www.statmethods.net/advstats/cluster.html
wss <- (nrow(mydata)-1)*sum(apply(mydata,2,var))
for (i in 2:15) wss[i] <- sum(kmeans(mydata,
centers=i)$withinss)
plot(1:15, wss, type="b", xlab="Number of Clusters",
ylab="Within groups sum of squares")
这个公式并不完全正确。但我自己也在做一个。模型每次都会改变,但它至少会是一堆迭代中最好的模型。
【讨论】:
以上是关于k-fold交叉验证确定k-means中的k?的主要内容,如果未能解决你的问题,请参考以下文章
交叉验证(cross validation)是什么?K折交叉验证(k-fold crossValidation)是什么?
R语言编写自定义K折交叉验证(k-fold crossValidation)函数使用使用bootstrap包中的crossval函数来交叉验证模型的R方指标验证模型的效能的可靠性和稳定性