用Scipy实现Kmeans聚类算法

用Scipy实现K-means聚类算法 | 沙湖王

用Scipy实现K-means聚类算法

   这是我之前写过的一篇文章,使用k-均值聚类算法给明星的身材分分类,由于技艺不精,写得着实不好。今天在stackoverflow上发现,原来scipy有聚类的相关包,还挺方便的。不过,貌似网上似乎都没有它的使用介绍。我忙了一下午,终于搞好了,我的数据如下:

 

 身高体重胸围腰围臀围
金巧巧164112.534.025.034.0
杨幂16899.032.024.032.0
钟丽缇168108.036.024.035.0
朱茵16095.033.022.033.0
赵薇166105.033.023.033.0
李珊珊175115.036.024.036.0
佘诗曼16496.033.022.034.0
郭羡妮166103.033.023.034.0
郑秀文165100.031.022.032.0
林嘉欣163108.033.024.034.0
韩君婷168108.034.024.035.0
安雅163104.034.524.035.0
林志玲174117.034.024.036.0
萧蔷170108.034.023.035.0
林嘉绮180126.034.025.035.0
姚乐怡163101.034.024.034.0
关之琳170117.035.024.035.0
巩俐168126.038.030.036.0
彭丹169125.036.024.036.0
张柏芝165101.033.025.034.0
章子怡164108.032.024.034.0
何洁157104.032.020.045.0
蔡依林15892.032.024.032.0
阿娇160101.032.024.033.0
阿Sa165100.032.023.033.5
高圆圆167108.033.024.034.0
奥黛丽赫本170103.532.020.035.0
温碧霞164106.033.023.033.0
安吉利娜-朱丽173130.036.027.036.0
巩新亮168101.034.022.033.0
舒淇168115.034.024.035.0
范冰冰168112.033.022.032.0
阿朵166115.038.030.038.0
白歆惠175112.033.023.035.0
韩艺瑟166101.033.024.033.0
幸田来未15692.033.022.033.0
饭岛爱161100.033.522.033.5
苍井空155101.035.022.432.7
衫本彩168124.033.922.633.6
宋慧乔161101.033.024.032.0
李慧珍16092.033.024.032.0
陈怡蓉160101.032.025.034.0
张梓林182128.034.725.034.8
斯嘉丽·约翰逊160108.035.524.635.5
霍莉·威洛比170123.829.323.430.1
碧昂斯170126.035.223.834.4
蕾哈娜173108.030.024.032.0
玛丽莲166120.435.022.035.0
黛塔·范·提思168107.034.022.034.0
凯蒂·派瑞173130.034.027.033.0
碧姬·芭铎170128.035.023.035.0
金·卡戴珊175128.035.525.036.0
拉拉·斯通173112.534.024.035.0
洪欣167124.033.025.035.0
王祖贤172128.033.025.033.0
林心如167103.533.022.034.0
孟广美178129.034.026.036.0
应采儿175112.533.024.534.0
张韶涵15890.032.023.532.0
徐若瑄161114.033.025.033.0
桂纶镁164103.532.023.034.5
陈乔恩16590.033.022.033.3
杨丞琳16199.032.023.033.0
廖碧儿171117.035.024.034.0
李玟162105.035.022.535.0
Maggie170106.034.024.034.0
张曼玉168115.032.423.034.0

上述数据用csv格式存储,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
from scipy.cluster.vq import vq, kmeans, whiten,kmeans2
data = pd.read_csv('/home/rickey/文档/学习/数据挖掘与数据仓库/数据挖掘作业/三围数据',sep='t',index_col=0)
matData = data.as_matrix()
whitened = whiten(matData)
center = kmeans(whitened,12)[0]
result = vq(whitened,center)[0]
dicResult = {}
resultList = result.tolist()
i = 0
for i in range(len(resultList)):
    #print i
    if dicResult.has_key(resultList[i]):
        dicResult[result[i]].append(i)
    else:
        dicResult[result[i]] = [i]
for i in dicResult:
    for j in dicResult[i]:
        print data.index[j],
    print 'nnn'

现在的代码量相对于之前的,真的是少了很多很多呀。下面我介绍一下一些主要函数的说明:

我这里使用了scipy,pandas两个包,read_csv读取csv文件的效果我觉得比numpy和scipy都要好。data里面包含了人名,列名,所以用matData获取纯数据部分。whiten函数比较坑爹,它的文档的例子是错误的,我是看了它的源代码才知道什么意思的,实际上,它是先算出matData各列的标准差,形成一个新的数组,比如上面的数据有四列,该新的数组就有四个元素,每个元素分别是对应列的标准差。然后,用matData处于该标准差数据,就得出了whitened这个结果了。

center获得的是聚类中心所形成的数组。,这里,可以用kmeans,也可以用kmeans2。他们两个的区别我还没有去细致区分。kmeans返回的结果是一个有两个元素的元组,第一个元素是聚类中心数组,第二个元素是单个数字,我不太明白它的意思。

result则是聚类的结果。这里,vq需要两个参数,分别是whitened,center,通过vq,可以获取每个人所属的类,返回的也是如kmeans一样的元组结果,第一个元素如下:

array([ 6, 11,  7,  3, 11,  7,  3, 11, 11,  6,  7,  8,  7,  7, 10,  6,  7,
        0,  2,  6,  6,  1,  5,  5, 11,  6, 11, 11, 10, 11,  7, 11,  0,  7,
        6,  5,  3,  9,  2,  5,  5,  6, 10,  8,  4,  2,  4,  2, 11, 10,  2,
       10,  7,  2,  2, 11, 10,  7,  5,  6, 11,  3,  5,  7,  8,  7, 11])

这个数组的意思是说,第一个人属于聚类中心6,第二个人属于聚类中心11。后面的那些代码,主要是用来输出人名的,与聚类算法已经无关了,获得的结果会变,貌似即使是同样的k值,结果还是会有点不一样的,k值也比较难以确定,我分的是12个,结果如下:

巩俐 阿朵 



何洁 



彭丹 衫本彩 碧昂斯 玛丽莲 碧姬·芭铎 洪欣 王祖贤 



朱茵 佘诗曼 饭岛爱 陈乔恩 



霍莉·威洛比 蕾哈娜 



蔡依林 阿娇 幸田来未 宋慧乔 李慧珍 张韶涵 杨丞琳 



金巧巧 林嘉欣 姚乐怡 张柏芝 章子怡 高圆圆 韩艺瑟 陈怡蓉 徐若瑄 



钟丽缇 李珊珊 韩君婷 林志玲 萧蔷 关之琳 舒淇 白歆惠 拉拉·斯通 应采儿 廖碧儿 Maggie 



安雅 斯嘉丽·约翰逊 李玟 



苍井空 



林嘉绮 安吉利娜-朱丽 张梓林 凯蒂·派瑞 金·卡戴珊 孟广美 



杨幂 赵薇 郭羡妮 郑秀文 阿Sa 奥黛丽赫本 温碧霞 巩新亮 范冰冰 黛塔·范·提思 林心如 桂纶镁 张曼玉 
 
总体来讲,感觉不然我之前的那个算法分得准确。
原文地址:https://www.cnblogs.com/lexus/p/2815792.html