博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kmeans聚类源代码
阅读量:6259 次
发布时间:2019-06-22

本文共 4331 字,大约阅读时间需要 14 分钟。

代码是在weka上二次开发的,但没有使用原来的kmeans代码,只是用了它的数据类Intances,先说下与它相关的几点东西。

一、KMeans算法简介

输入:聚类个数k,以及包含 n个数据对象的数据库。

输出:满足方差最小标准的k个聚类。

处理流程:       

1)从 n个数据对象任意选择 k 个对象作为初始聚类中心.

2)根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;

3)重新计算每个(有变化)的聚类的均值。

4)重复(2)(3),直到聚类不发生改变。

划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个中心对象(引力中心)来进行计算的。

    k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

 

二、weka相关介绍

1、Instances

Instances是数据集类,是样本或实例的集合。

Instances有个数据头header,包含除了样本Instance之外的信息,比如attributes的信息。

//data是Instances类型Instances ins = new Instances(data, 0);//用data的数据集信息创建一个新的Instances类,但不包含data的样本

2、Instance

Instance是一个接口,对应的是一个样本或实例。

因为不同项目中数据集是不一样的,也就不能固定Instance的具体属性,所以写成接口。在自己的项目中,应该实现这个Instance

3、Attribute

属性类,对应Instance的一列。

每个Attribute保存的是Instance这一列可取的值。

a、如果是属性是数值类型,这个Attribute就用Numeric类型表示

b、如果是String类型,这个Attribute保存了一个向量,向量的每个值是属性可以取到的String值。

所以,Attribute不保存某个Instance的某个属性状态,而是数据集Instances的某个属性的可取范围,也就是这个属性的值域。

所以,虽然Instance能get到某个Attribute,当不能直接从这个Attribute获取这个属性值。属性值可以直接从Instance获取。

//获取第i个属性的值,用String表示instance.toString(i)

如果属性值是数值类型,可以直接获取,不用toString(i)

//获取第3个属性的值,从0开始计数。返回doubleinstance.value(3)

4、InstanceQuery

我的数据是在数据库中,所以我就用InstanceQuery这个类,而且可以避免我自己去实现Instance类。

可以参考下官方文档:

首先要修改文档,在weka.experiment包下面。

在Eclipse IDE下没法直接修改,我用2345好压找到文件,修改了保存回去,就ok了。我连的是oracle。

主要是修改DatabaseUtils.props的这两行:

# JDBC driver (comma-separated list)jdbcDriver=oracle.jdbc.driver.OracleDriver# database URLjdbcURL=jdbc:oracle:thin:@192.168.2.67:1521:orcl

然后就是在代码中写了:

public static Instances getData() throws Exception {        InstanceQuery query = getQuery();                String sql = "..............................................................";        Instances data = query.retrieveInstances(sql);        if (data.numInstances() <= 0)            throw new Exception("data size is 0;");        clusterCentroids = new Instances(data, numClusters);        return data;    }        public static InstanceQuery getQuery() {        InstanceQuery query = null;        try {            query = new InstanceQuery();        } catch (Exception e) {
e.printStackTrace(); } query.setDatabaseURL("jdbc:oracle:thin:@192.168.2.67:1521:orcl"); query.setUsername("..."); query.setPassword("..."); return query; }

 

三、代码

import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.Enumeration;import java.util.Random;import weka.core.Instance;import weka.core.Instances;import weka.core.Utils;import weka.experiment.InstanceQuery;public class DisKmeans {        private static int numClusters = 20;    private static int maxInteration = 600;    private static Instances clusterCentroids;    private static Instances[] kmeansResult;        public static void main(String[] args) throws Exception {        Instances data = getData();        System.out.println("start");        System.out.println(data.size());        System.out.println(data.instance(1));        Instance instance = data.instance(1);        for (int i=0; i
=0 ; i--) { insIndex = random.nextInt(i);//保证i不会超过数组上线 clusterCentroids.add(data.instance(insIndex)); if (clusterCentroids.numInstances() == numClusters) { break; } }// System.out.println(clusterCentroids); printInstances(clusterCentroids); System.out.println("-----------聚类中心结束-------------"); return clusterCentroids; } /** * 根据初始中心点,对数据进行第一次聚类,结果为初始聚类结果 * @param data * @param centroids * @return */ public static Instances[] createCluster(Instances data, Instances centroids) { Instances[] newData = new Instances[centroids.numInstances()]; for (int i=0; i
= 0.0001) { flag = false; break; } } return flag; } public static void printInstances(Instances instances) { for (int i=0; i

 

四、其他

1、离散变量:数据中有个有用的离散变量,不方便直接放到kmeans算法中。但一定要用,也是可以的。

2、DatabaseUtils.props文件,在jar包中不方便直接修改,而我用解压工具修改在压缩回去,虽然可行,总觉得不太好。不知道有什么更好的方法?

转载于:https://www.cnblogs.com/549294286/p/3461994.html

你可能感兴趣的文章
生活就是好好经历,无问西东----三月份总结
查看>>
《SQL 进阶教程》 case:练习题1-1-3 用 ORDER BY 指定顺序进行排序
查看>>
Linux Core Dump【转】
查看>>
NBIoT三种部署方式【转】
查看>>
Linux 内核驱动--多点触摸接口【转】
查看>>
vim快捷键笔记【原创】
查看>>
算法(Algorithms)第4版 练习 2.3.17
查看>>
详解JSOUP的Select选择器语法
查看>>
条款12:复制对象的时候不要忘了其每一个部分
查看>>
一统江湖的大前端(3) DOClever——你的postman有点low
查看>>
解决浏览器Adobe Flash Player不是最新版本问题
查看>>
KMP
查看>>
5.基于优化的攻击——CW
查看>>
cocos2d-x的CallFunc
查看>>
customTextbox
查看>>
oracle11g安装完成后修改字符集
查看>>
Laravel 的HTTP控制器
查看>>
结构型 之 适配器模式
查看>>
CAD导板框方法
查看>>
[CF1039D]You Are Given a Tree
查看>>