最近我遇到了这个面试问题(K-Means Clustering solution)。我想出的设计不符合面试官的期望(简单地说我没有得到这份工作,因为我在这个设计问题上输给了另一位候选人)。我想知道SO社区能提出多少不同/有效/简单的解决方案(通过这样做我希望磨练我的技能):
实施一种简单的算法,根据人的体重和身高对人群进行聚类。该 数据集包括具有权重和高度的人员列表,如下所示:
Person Weight Height
(kg) (inches)
Person 1 70 70
Person 2 75 80
Person 3 120 85
您可以将数据绘制为二维数据。重量是一维和高度 另一个方面。重量可以从最小50千克到150千克不等。高度可以是范围 从最少38英寸到90英寸
算法:
该算法(称为K-means聚类)将数据聚类为K组,如下所示:
从K群集开始。每个簇由其中心点定义,该中心点将从as开始 随机重量和随机高度。从中挑选随机数 上面定义的相应范围。
每个人 使用公式计算每个簇的中心距离 距离= sqrt(pow((wperson-wcenter),2)+(pow(hperson-hcenter),2)) wperson =人的重量, hperson =人的身高 wcenter =簇中心点的权重, hcenter =聚类中心点的高度
将人员分配到群集中心点距离最短的群集
在第2步结束后,您将最终得到K群集,每个群集都分配了一组人
对于每个群集,将中心点的重量和高度设置为平均值 群集中的人 wcenter =(群集中每个人的权重之和)/(群集中的人数) hcenter =(群集中每个人的身高总和)/群集中的人数)
重复步骤2到5进行1000次迭代,然后打印出每个迭代的以下信息 群集。
群集中心的重量和高度。 群集中的人员列表。
我不是在寻求实施/解决方案,而是寻求高水平的设计。你能列出接口/类等 我现在不想提出我的解决方案,但会在当天晚些时候发布?
答案 0 :(得分:2)
这是我对设计的尝试。我只展示静态图,因为算法已经基本上已经布局了。我计划有一个访问者来表示集群,可以允许不同类型的输出(xml,字符串,csv..etc)。也许访问者是矫枉过正的,如果是的话,那我就像ToString方法那样可以被覆盖。
注意:群集在SetCenter和FindNewCenter方法上创建CenterClusterItem。 CenterClusterItem不是PersonClusterItem,它只保存与PersonClusterItem相同数量的AClusterValues(因为平均值不是真正的人)。
另外,我忘了在KCluster上创建一个方法来开始这个过程,但这是隐含的。
Class Diagram http://img11.imageshack.us/img11/499/kcluster.png
答案 1 :(得分:1)
好吧,我会首先解决所有降低算法可重用性的常量/幻数:
而不是固定次数的迭代,使用停止标准(例如,如果群集不会改变太多,则终止)
不要将自己局限于2-dim数据,请使用向量
让用户定义要查找的群集数量
然后,您可以隐藏接口背后的某些细节,例如距离的计算方式可能不同(例如,它可能在某些时候必须处理除了double之外的值)。
另一方面,如果你真的有这个简单的问题,其中一些概括可能会有点过分 - 但这就是我要跟别人讨论实现这个算法的问题。
答案 2 :(得分:1)
您可以创建以下类:
答案 3 :(得分:0)
我不确定你的问题究竟是什么,你指出的步骤有效地定义了你所讨论的算法。
更好的想法可能是准确包含您所做的事情,然后人们可以为您提供一些提示/提示,说明您可能出错的地方或他们将采取的不同方式。
答案 4 :(得分:0)
听起来这是一个非常好的方法。 K-means通常会快速收敛(虽然不一定会达到全局最优),所以我的一个建议是运行算法直到不再发生变化,而不是固定数量的1000次迭代。然后,您可以使用不同的随机起点重复整个过程几次。
k-means的一个弱点是它确实需要你为k预先指定(即猜测)适当的值。我想你会得到积分,询问面试官k的适当值是什么,或者,如果没有办法知道,描述一些拟合优度度量,然后计算不同k值的度量来找到一个“只是足够低”的价值。