原数据有两列。第一列是打电话总时长,第二列是打电话占打接电话比。两列数据都已经标准化过了。一开始是逗号分割,每行两个数字。
拿到数据后,先使用R来看一下,毕竟只有两个维度,plot一下就好了。
1
2
3
4
5
6
7
8
9
10
11
|
x < - read.table( "D:\\R\\p04-17.csv" ,sep = "," ,col.names = c( "col1" , "col2" )) dataf < - data.frame( "col1" = x$col1, "col2" = x$col2) plot(col2~col1,data = dataf) #画出散点图 #使用R来做聚类,其实这里没必要scale了,因为数据本身就处理过的,不过还是习惯打上去了 model < - kmeans(scale(dataf[ 1 : 2 ]), 4 ) model library(ggplot2) #重新画一下图,把分类的结果用不同颜色标出来。 qplot(col1,col2,data = dataf,color = model$cluster) |
使用mahout进行实验。mahout要求数据是空格分隔的序列化文件。所以数据拿过去,先把逗号都换成了空格。然后使用InputDriver这个工具类对文件处理了一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#因为机子就一台笔记本,所以,在本地跑了 export MHOUT_LOCAL = true #把用户主目录下testdata文件夹下的空格分隔文件 处理一下, mahout org.apache.mahout.clustering.conversion.InputDriver - i testdata / p04 - 17.csv - o testoutput / vectorfiles - v org.apache.mahout.math.RandomAccessSparseVector #处理完, #因为mahout 还要求出入初始点 所以先建了个空文件夹表示以后这里要放初始点集,不过我这里指定k随机抽取k个点, #指定k之后 这个输入其实是被忽略了 mkdir testdata / initpoint #可以开始聚类了。聚类之后可以使用工具命令把结果导出来,也可以去mahout源码下运行clusterdumper类 #cd 表示收敛差值的阈值。x表示最大迭代次数, k初始点有多少个, k有了之后 忽略-c的内容。 mahout kmeans - i testdata / vectorfiles - o testoutput / kmeans - 10 - 4 - c testdata / initpoint \ - cd 0.5 - x 10 - cl - k 4 - ow mahout clusterdump - i testoutput / kmeans - 10 - 4 / clusters - 1 - final \ - o testoutput / kmeans - 10 - 4 / result.txt #生成的结果 c是点坐标 r是半径 前面的数字表示有多少点分过来了 #VL-642{n=74 c=[0.915, 0.437] r=[0.028, 0.152]} #VL-800{n=336 c=[0.796, 0.469] r=[0.067, 0.108]} #VL-1076{n=972 c=[0.397, 0.542] r=[0.127, 0.175]} #VL-1175{n=422 c=[0.684, 0.621] r=[0.062, 0.105]} mahout canopy - i testdata / vectorfiles - o testoutput / canopy - 0.2 - 0.1 - ow - t1 0.2 - t2 0.1 mahout clusterdump - i testoutput / canopy - 0.2 - 0.1 / clusters - 0 - final \ - o testoutput / canopy - 0.2 - 0.1 / result.txt #C-0{n=8 c=[0.495, 0.614] r=[0.181, 0.135]} #C-1{n=5 c=[0.615, 0.608] r=[0.100, 0.105]} #C-2{n=5 c=[0.443, 0.383] r=[0.170, 0.137]} #C-3{n=5 c=[0.599, 0.503] r=[0.079, 0.120]} mahout fkmeans - i testdata / vectorfiles - o testoutput / fuzzekmeans \ - c testdata / initpoint - cd 0.5 - x 10 - cl - k 4 - ow - m 2 mahout clusterdump - i testoutput / fuzzekmeans / clusters - 1 - final \ - o testoutput / fuzzekmeans / result.txt #SV-1476{n=629 c=[0.439, 0.621] r=[0.150, 0.147]} #SV-810{n=587 c=[0.585, 0.470] r=[0.191, 0.123]} #SV-1084{n=423 c=[0.627, 0.578] r=[0.202, 0.140]} #SV-1530{n=160 c=[0.763, 0.407] r=[0.223, 0.155]} |
因为cd 默认是0.5 ,我就都填了0.5,结果是顶多迭代一次就够了,效果非常不好,于是把这个值改的非常小就好了。距离默认都用了欧几里得距离。在输出目录里 data是原始数据,cluster-x是第几次迭代后得到的结果。cluster-x-final是最终结果。
得到了聚类的结果后,可以使用r来画个图,看看效果
比如:
1
2
3
4
5
6
7
8
9
|
mahout kmeans - i testdata / vectorfiles - o testoutput / kmeans - 10 - 4 - 0.001 \ - c testdata / initpoint - cd 0.001 - x 10 - cl - k 4 - ow mahout clusterdump - i testoutput / kmeans - 10 - 4 - 0.001 / clusters - 5 - final \ - o testoutput / kmeans - 10 - 4 - 0.001 / result.txt #VL-553{n=419 c=[0.808, 0.462] r=[0.076, 0.100]} #VL-56{n=282 c=[0.293, 0.708] r=[0.095, 0.090]} #VL-1184{n=539 c=[0.412, 0.416] r=[0.112, 0.132]} #VL-579{n=560 c=[0.650, 0.641] r=[0.094, 0.093]} |
1
2
3
4
5
6
7
8
|
x < - read.table( "D:\\R\\p04-17.csv" ,sep = "," ,col.names = c( "col1" , "col2" )) dataf < - data.frame( "col1" = x$col1, "col2" = x$col2) plot(col2~col1,data = dataf) #画出散点图 library(plotrix) ellipse( 0.808 , 0.462 , 0.076 , 0.100 ,border = "yellow" ,lwd = "3" ) ellipse( 0.293 , 0.708 , 0.095 , 0.090 ,border = "yellow" ,lwd = "3" ) ellipse( 0.412 , 0.416 , 0.112 , 0.132 ,border = "yellow" ,lwd = "3" ) ellipse( 0.650 , 0.641 , 0.094 , 0.093 ,border = "yellow" ,lwd = "3" ) |
得到下面的图:
这个还不是很好,但是看到我设置最多迭代10次,这才迭代了6次,所以可以把cd再调的更小,结果就应该很漂亮了。
怎么设置初始点集,这个遗留成了个问题,改天来看。
愿数据下载:http://pan.baidu.com/s/1kwQWu