K-means:如何选择K(cluster的数目)

目前决定cluster数目的常用方法是手动地决定cluster的数目

哪个K是正确的?

上图中的数据集,我们可以说它有4个clusters,也可以说它有2个clusters,但哪个是正确答案呢?其实这儿没有正确答案,数据集要划分的cluster的数目本来就是模拟两可的,可以是2个,3个,4个。这也是无监督学习的一部分,因为我们的数据集没有标签,所以没有清晰的答案。所以做一个能自动求出K值的算法是非常困难的

通过肘部法则(elbow method)来选择K值

通过画K与cost function的关系曲线图,如左图所示,肘部的值(cost function开始时下降很快,在肘部开始平缓了)做为K值,K=3。

并不是所有的问题都可以通过画肘部图来解决,有的问题如右边的那个图,肘点位置不明显(肘点可以是3,4,5),这时就无法确定K值了。

故肘部图是可以尝试的一种方法,但是并不是对所有的问题都能画出如左边那么好的图来确定K值。

另一种选择K值的方法—后续目的(市场等)

通过后续的一些目的,如市场方面的一些计算评估等。例如,T-shirt的例子,是将其设计为3种尺码还是5种尺码呢?要根据后续我们的一些目的来确定,是想T-shirt适应更多的顾客(5种)还是希望T-shirt更便宜(3种),来确定K的值。

总结

  1. 选择K值现在大多数还是通过你的理解与洞察手动来选择的
  2. 可以尝试通过elbow method来选择K值,但是它并不通用,因为很多情况下,肘部点并不明确
  3. 大多数情况下,我们根据后续的目的来选择K值,看后续要做些什么,来看我们的K值应该怎么选
时间: 2024-12-24 15:21:04

K-means:如何选择K(cluster的数目)的相关文章

从n个元素中选择k个的所有组合(包含重复元素)

LeetCode:Combinations这篇博客中给出了不包含重复元素求组合的5种解法.我们在这些解法的基础上修改以支持包含重复元素的情况.对于这种情况,首先肯定要对数组排序,以下不再强调 修改算法1:按照求包含重复元素集合子集的方法LeetCode:Subsets II算法1的解释,我们知道:若当前处理的元素如果在前面出现过m次,那么只有当前组合中包含m个该元素时,才把当前元素加入组合 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

9-n个人中选k个人的选择方法种类

用递归法计算从n个人中选择k个人组成一个委员会的不同组合数分析: 1.如果k>n,结果为0 2.k=n时,只有1组 3.k<n的时候,可以把解空间分为两部分:假设其中一个人叫X,那么选X的解和不选X的解加起来就是总的解.不选X的话,那么在剩下的n-1个人中选k个.选X的话,在剩下的n-1个人中再选k-1个.#include <iostream>using namespace std; int c(int n, int k){    if(k > n)        retur

【算法30】从数组中选择k组长度为m的子数组,要求其和最小

原题链接:codeforce 267 Div2 C 问题描述: 给定长度为n的数组a[],从中选择k个长度为m的子数组,要求和最大. 形式描述为:选择$k$个子数组[$l_1$, $r_1$], [$l_2$, $r_2$], ..., [$l_k$l1, $r_k$] (1 ≤ $l_1$ ≤$r_1$ ≤$l_2$ ≤ $r_2$ ≤... ≤$l_k$ ≤ $r_k$ ≤ n; $r_i-r_i+1$), 使得$\sum_{i=1}^{k}\sum_{j=l_i}^{r_i}p_j$ 问题

用递归法计算从n个人中选择k个人组成一个委员会的不同组合数

分析: 1.如果k>n,结果为0 2.k=n时,只有1组 3.k<n的时候,可以把解空间分为两部分:假设其中一个人叫X,那么选X的解和不选X的解加起来就是总的解.不选X的话,那么在剩下的n-1个人中选k个.选X的话,在剩下的n-1个人中再选k-1个. 代码: #include<iostream> using namespace std; int fun(int n, int k){ if (k == n||k==0){ return 1; } if (k > n){ retu

分治法题目整理分析 找第k小的数/求逆序对数目/派

设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数. 提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数.因此可以编制int find(int a[],int left,

关于组合 C(N, K) = C(N - 1, K) + C(N - 1, K - 1) 的理解

组合的递推公式 C(N, K) = C(N - 1, K) + C(N - 1, K - 1) 等价于 C(N + 1, K + 1) = C(N, K + 1) + C(N, K) ,即K和N分别加1. 通过观察 C(N + 1, K + 1) = C(N, K + 1) + C(N, K) 右边第二项C(N, K)为"在N件中取K件的组合数",左边一项C(N + 1, K + 1)为"在N+1件中取K+1件的组合数",这两项的差C(N, K + 1)为"

[Leetcode] Merge k sorted lists 合并k个已排序的链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:这题最容易想到的是,(假设有k个链表)链表1.2合并,然后其结果12和3合并,以此类推,最后是123--k-1和k合并.至于两链表合并的过程见merge two sorted lists的分析.复杂度的分析见JustDoIT的博客.算法复杂度:假设每个链表的平均长度是n,则1.2合并,遍历2n个

Leetcode23---&gt;Merge K sorted Lists(合并k个排序的单链表)

题目: 合并k个排序将k个已排序的链表合并为一个排好序的链表,并分析其时间复杂度 . 解题思路: 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后移动,尾向前移动,继续合并,直到头和尾相等,此时已经归并了一半, 然后以同样的方法又重新开始归并剩下的一半.时间复杂度是O(logn),合并两个链表的时间复杂度是O(n),则总的时间复杂度大概是O(nlogn):合并两个单链表算法可以参考Leetcode21中的解法:http://www.cnblo

leetCode 23. Merge k Sorted Lists (合并k个排序链表) 解题思路和方法

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:此题是由合并两个排序链表演化而来,刚开始,想法比较简单,像求最大公共前缀一样,逐一求解:但是最后超时,所以马上意识到出题方是为了使用归并和分治的方法,故重新写了代码. 代码一(超时未过): /** * Definition for singly-link