mahout实现的模糊K-Means聚类算法原理和源码分析
来源:互联网 发布:微信对域名市场的影响 编辑:程序博客网 时间:2024/05/20 14:19
首先介绍一下,FuzzyKMeans算法的主要思想。
模糊 C 均值聚类(FCM),即众所周知的模糊 ISODATA,是用隶属度确定每个数据点属于某个聚类的程度的一种聚类算法。1973 年,Bezdek 提出了该算法,作为早期硬 C 均值聚类(HCM)方法的一种改进。FCM 把 n 个向量 xi(i=1,2,...,n)分为 c 个模糊组,并求每组的聚类中心,使得非相似性指标的价值函数达到最小。FCM 使得每个给定数据点用值在 0,1 间的隶属度来确定其属于各个组的程度。与引入模糊划分相适应,隶属矩阵 U 允许有取值在 0,1 间的元素。不过,加上归一化规定,一个数据集的隶属度的和总等于 1:
那么,FCM 的价值函数(或目标函数)就是下式一般化形式:
这里 uij 介于 0,1 间;ci 为模糊组 i 的聚类中心,dij=||ci-xj||为第 i 个聚类中心与第 j 个数据点间的欧几里德距离;且 m (属于1到无穷) 是一个加权指数。
构造如下新的目标函数,可求得使下式达到最小值的必要条件:其实就是拉格朗日乘子法
对上式所有输入参量求导,使上式达到最小的必要条件为:
和
由上述两个必要条件,模糊 C 均值聚类算法是一个简单的迭代过程。在批处理方式运行时,
FCM 用下列步骤确定聚类中心 ci 和隶属矩阵 U[1]:
步骤 1:用值在 0,1 间的随机数初始化隶属矩阵 U
步骤 2:用式(3)计算 c 个聚类中心 ci,i=1,...,c。
步骤 3:根据式(1)计算价值函数。如果它小于某个确定的阀值,或它相对上次价
值函数值的改变量小于某个阀值,则算法停止。
步骤 4:用(4)计算新的 U 矩阵和。返回步骤 2。
上述算法也可以先初始化聚类中心,然后再执行迭代过程。由于不能确保 FCM 收敛于一个最优解。算法的性能依赖于初始聚类中心。因此,我们要么用另外的快速算法确定初始
聚类中心,要么每次用不同的初始聚类中心启动该算法,多次运行 FCM。
notes: 上面讨论不难看出二个参数比较重要:1.聚类的数目,2.控制算法的柔软参数m,如果m过大,则聚类的效果很差,如果m过小,则算法接近Kmeans算法。
mahout实现:
在mahout中,控制参数m=2;定义如下:private double m = 2.0; // default value
其整个代码如下:
1 public class FuzzyKMeans{ 2 3 public static void main(String args[]) throws Exception { 4 int k = 3; 5 List<Vector> sampleData = new ArrayList<Vector>(); 6 RandomPointsUtil.generateSamples(sampleData, 400, 1, 1, 3); 7 RandomPointsUtil.generateSamples(sampleData, 300, 1, 0, 0.5); 8 RandomPointsUtil.generateSamples(sampleData, 300, 0, 2, 0.1); 9 List<Vector> randomPoints = RandomPointsUtil.chooseRandomPoints(10 sampleData, k);11 List<SoftCluster> clusters = new ArrayList<SoftCluster>();12 int clusterId = 0;13 for (Vector v : randomPoints) {14 clusters.add(new SoftCluster(v, clusterId++,15 new EuclideanDistanceMeasure()));16 }17 List<List<SoftCluster>> finalClusters = FuzzyKMeansClusterer18 .clusterPoints(sampleData, clusters,19 new EuclideanDistanceMeasure(), 0.01, 3, 10);20 for (SoftCluster cluster : finalClusters.get(finalClusters.size() - 1)) {21 System.out.println("Fuzzy Cluster id: " + cluster.getId()22 + " center: " + cluster.getCenter().asFormatString());23 }24 }25 }
对上面几行代码进行说明:
类RandomPointsUtil中静态方法generateSamples是产生随机样本,并存在sampleData中。
类RandomPointsUtil中静态方法chooseRandomPoints是随机选择k个样本作为初始点。
其类RandomPointsUtil代码如下:
1 public class RandomPointsUtil { 2 public static List<Vector> chooseRandomPoints(List<Vector> srcVector, int k) { 3 List<Vector> destVector = new ArrayList<Vector>(); 4 for (int i = 0; i < k; i++) { 5 int index = (int) (Math.random() * srcVector.size()); 6 destVector.add(srcVector.get(index)); 7 } 8 return destVector; 9 }10 11 private static void generateSamples(List<Vector> sampleData, int num, double mx,12 double my, double sd, int card) {13 for (int i = 0; i < num; i++) {14 DenseVector v = new DenseVector(card);15 for (int j = 0; j < card; j++) {16 v.set(j, UncommonDistributions.rNorm(mx, sd));17 }18 sampleData.add(v);19 }20 }21 22 /**23 * Generate 2-d samples for backwards compatibility with existing tests25 * @param numint number of samples to generate27 * @param mx double x-value of the sample mean29 * @param mydouble y-value of the sample mean31 * @param sddouble standard deviation of the samples33 */34 public static void generateSamples(List<Vector> sampleData, int num, double mx,35 double my, double sd) {36 37 generateSamples(sampleData, num, mx, my, sd, 2);38 }39 }
- mahout实现的模糊K-Means聚类算法原理和源码分析
- Mahout之k-means算法源码分析
- mahout下的K-Means聚类实现与源码分析
- K-means算法的实现原理和分析
- Mahout实现k-means算法
- mahout测试k-Means聚类算法
- mahout的k-means聚类算法的内存实现(大于mahout0.6以上不支持)
- K-means均值聚类算法的原理与实现
- K-Means聚类算法的原理及实现
- K-Means聚类算法的原理及实现【转】
- K-Means聚类算法的原理及实现
- Mahout clustering Canopy+K-means 源码分析
- 基于模糊K-Means算法的新闻聚类
- 一个K-means聚类算法的实现代码和分析
- k-means聚类算法的详解和实现
- 用java实现K-means算法,k-means聚类算法原理
- mahout 源码解析之聚类--K-Means,FuzzyKMeans
- K-Means聚类算法的实现
- 用nohup命令让Linux下程序永远在后台执行
- HTML5应用开发功耗调优化小结
- shutdown
- FileNameFilter接口应用: 指定多个扩展名过滤规则
- 将排名提升至首页的方法
- mahout实现的模糊K-Means聚类算法原理和源码分析
- 做一个有胆识的有为青年
- 查找绝对值等差数列
- 一个启动Java程序的shell脚本
- UtilDate(一):获取当前日期的年月日时分秒星期
- android 中禁止RatingBar选择 或 改变
- 《高效程序员的45个习惯》
- JAVA系列-设计模式-工厂模式
- 杭电ACM2043密码在linux下C++编译