相比于有监督的分类器,聚类的目标是从一组未打标签的数据中识别相似对象组。它可
以用于识别同类群体的代表性样本,找到有用与合适的分组;或者找到不寻常的样本,比如
异常值。
下面通过分析银行数据集演示如何实现聚类。数据集包含600个实例,每个实例用11个属性
进行描述,这些属性包括年龄、性别、地区、收入、婚姻状况、是否有子女、汽车拥有情况、存
款活动、当前活动、房地产抵押、PEP。分析中,我们将尝试使用EM(Expectation Maximization,
期望最大化)聚类算法识别常见的客户组。
EM工作过程如下:给定一组簇(clusters),EM首先为每个实例指派一个属于某个特定簇的
概率分布。比如,起初有3个簇A、B、C,一个实例分别属于簇A、B、C的概率分布依次为0.7、
0.10、0.20。第二步中,EM重新评估每个类的概率分布的参数向量。算法不断对这两步做迭代,
直到参数收敛或者达到迭代的最大值。
对于EM中使用的簇数,可以手动设置,也可以通过交叉验证进行自动设置。另外一个确
定数据集中簇数的方法是肘部法则(elbow-method),这个方法会查看特定簇数所解释的偏差
百分比。使用该方法会不断增加簇数,直到新加的簇不会带来很多信息,即只能解释很少的额外
差异。
创建工程
依然使用上一篇文章的工程
加载数据
// 从文件中读取数据集Instances data = new Instances(new BufferedReader(new FileReader(PATH)));
聚类算法
创建聚类模型的过程与创建分类模型的过程很类似,即加载数据与创建模型。Weka中,使
用weka.clusterers包实现聚类算法
// 创建一个新的聚类器实例EM model = new EM();// 构建聚类模型model.buildClusterer(data);// 打印聚类模型的详细信息System.out.println(model);
EM
==Number of clusters selected by cross validation: 6
Number of iterations performed: 100Cluster
Attribute 0 1 2 3 4 5(0.1) (0.13) (0.26) (0.25) (0.12) (0.14)
======================================================================
age0_34 10.0535 51.8472 122.2815 12.6207 3.1023 1.094835_51 38.6282 24.4056 29.6252 89.4447 34.5208 3.375552_max 13.4293 6.693 6.3459 50.8984 37.861 81.7724[total] 62.1111 82.9457 158.2526 152.9638 75.4841 86.2428
sexFEMALE 27.1812 32.2338 77.9304 83.5129 40.3199 44.8218MALE 33.9299 49.7119 79.3222 68.4509 34.1642 40.421[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
regionINNER_CITY 26.1651 46.7431 73.874 60.1973 33.3759 34.6445TOWN 24.6991 13.0716 48.4446 53.1731 21.617 17.9946RURAL 8.4113 12.7871 21.7634 25.7529 11.1622 22.1231SUBURBAN 3.8356 11.344 15.1706 14.8404 10.3289 12.4805[total] 63.1111 83.9457 159.2526 153.9638 76.4841 87.2428
income0_24386 22.5301 77.3981 150.8728 35.3652 3.0947 1.739124387_43758 38.0636 4.5119 6.2909 113.3875 70.4654 8.280843759_max 1.5174 1.0357 1.0889 4.2111 1.924 76.2228[total] 62.1111 82.9457 158.2526 152.9638 75.4841 86.2428
marriedNO 15.0163 34.8213 48.6021 32.7954 49.5126 29.2523YES 46.0948 47.1244 108.6506 119.1684 24.9715 55.9904[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
children0 2.1776 53.2782 55.6363 92.5938 32.663 32.65111 51.5497 26.7841 22.0968 1.9302 18.9418 19.69732 6.4264 2.3777 56.5523 25.7573 23.3335 25.55293 2.9574 1.5057 24.9671 33.6825 1.5458 9.3415[total] 63.1111 83.9457 159.2526 153.9638 76.4841 87.2428
carNO 29.7462 47.4075 89.7372 69.5918 34.7847 38.7326YES 31.3649 34.5382 67.5154 82.372 39.6993 46.5101[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
save_actNO 6.7118 58.9844 49.6095 39.7853 35.7784 1.1306YES 54.3993 22.9613 107.6431 112.1785 38.7056 84.1121[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
current_actNO 12.8656 21.8946 35.3337 46.1845 15.9243 18.7973YES 48.2455 60.0511 121.9189 105.7792 58.5598 66.4455[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
mortgageNO 34.2814 47.6791 108.1248 95.3628 54.1015 57.4504YES 26.8297 34.2666 49.1278 56.601 20.3826 27.7924[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428
pepYES 59.0226 72.2592 18.5799 3.8416 68.4764 57.8202NO 2.0885 9.6865 138.6727 148.1222 6.0076 27.4226[total] 61.1111 81.9457 157.2526 151.9638 74.4841 85.2428-8.773422954298614
第一行表明有6个簇,第一列指出属性及相应范围。比如,属性age划分为3
个区段:0~34、35~51、52~max。左侧列表示有多少个实例归入每个簇的特定范围,比如0~34
年龄组的客户大部分位于簇#2(122个实例)。
评估
可以使用对数似然度量(log likelihood measure)评估聚类算法的质量,即测量被识别的簇的
一致程度。数据集划分为多个折(folds),针对每个折运行聚类。这么做的动机是,如果聚类算
法为相似数据(该数据不用于拟合参数)给出高概率,那么它在捕获数据结构方面可能做得很好。
// 使用 10 折交叉验证评估模型的对数似然值double logLikelihood = ClusterEvaluation.crossValidateModel(model, data, 10, new Random(1));// 打印对数似然值System.out.println(logLikelihood);
评估结果:-8.773422954298614
完整代码
private static String PATH = ClassUtils.getDefaultClassLoader().getResource("bank-data.arff").getPath();public static void main(String[] args) throws Exception {// 从文件中读取数据集Instances data = new Instances(new BufferedReader(new FileReader(PATH)));// 创建一个新的聚类器实例EM model = new EM();// 构建聚类模型model.buildClusterer(data);// 打印聚类模型的详细信息System.out.println(model);// 使用 10 折交叉验证评估模型的对数似然值double logLikelihood = ClusterEvaluation.crossValidateModel(model, data, 10, new Random(1));// 打印对数似然值System.out.println(logLikelihood);}
结论
1. 聚类数量: 交叉验证选择的最佳聚类数量为 6 个。
2. 迭代次数: 模型进行了 100 次迭代。
3. 聚类特征分布:
- **年龄(age)**:
- 年龄在 52 岁以上的个体在聚类 5 中有较高的比例。
- 年龄在 35-51 岁的个体在聚类 3 中有较高的比例。
- **性别(sex)**:
- 女性的比例在聚类 2、3 和 6 中较高。
- 男性的比例在聚类 1 和 4 中较高。
- **地区(region)**:
- 内城(INNER_CITY)和郊区(SUBURBAN)的个体在聚类 0 和 5 中较高。
- 农村和城镇的个体在聚类 2 和 3 中较高。
- **收入(income)**:
- 高收入个体(43759_max)在聚类 5 中比例较高。
- 中等收入个体(24387_43758)在聚类 3 中比例较高。
- **婚姻状况(married)**:
- 未婚个体在聚类 4 中比例较高。
- 已婚个体在聚类 3 和 6 中比例较高。
- **子女数量(children)**:
- 无子女的个体在聚类 3 中比例较高。
- 有多个子女的个体在聚类 0 和 5 中比例较高。
- **是否有车(car)**:
- 无车的个体在聚类 2 中比例较高。
- 有车的个体在聚类 3 和 4 中比例较高。
- **是否有储蓄账户(save_act)**:
- 有储蓄账户的个体在聚类 6 中比例较高。
- 无储蓄账户的个体在聚类 5 中比例较低。
- **是否有当前账户(current_act)**:
- 无当前账户的个体在聚类 0 和 5 中比例较低。
- 有当前账户的个体在聚类 3 和 4 中比例较高。
- **是否有抵押贷款(mortgage)**:
- 无抵押贷款的个体在聚类 3 和 4 中比例较高。
- 有抵押贷款的个体在聚类 6 中比例较低。
- **是否有个人养老计划(pep)**:
- 有个人养老计划的个体在聚类 1 和 4 中比例较高。
- 无个人养老计划的个体在聚类 2 和 3 中比例较高。
4. 目标变量:结果显示目标变量的得分(-8.773422954298614),这可能是一个对数似然值或某种损失函数的值,表示模型在训练数据上的拟合程度。