在这里将使用Weka自带的K-means以及EM算法对同一份数据进行聚类。
目前使用的是自带的数据集。我也不太清楚这样聚类的效果如何 sigh...
Weka Version: 3.7.10
K-Means K-均值算法
import java.io.File;
import weka.clusterers.SimpleKMeans;
import weka.core.DistanceFunction;
import weka.core.Instances;
import weka.core.converters.ArffLoader;
public class TestKMeans {
public static void main(String[] args) {
Instances ins = null;
SimpleKMeans KM = null;
// 目前没有使用到,但是在3.7.10的版本之中可以指定距离算法
// 默认是欧几里得距离
DistanceFunction disFun = null;
try {
// 读入样本数据
File file = new File("D:\\Program Files\\Weka-3-7\\data\\contact-lenses.arff");
ArffLoader loader = new ArffLoader();
loader.setFile(file);
ins = loader.getDataSet();
// 初始化聚类器 (加载算法)
KM = new SimpleKMeans();
KM.setNumClusters(2); //设置聚类要得到的类别数量
KM.buildClusterer(ins); //开始进行聚类
// 打印聚类结果
System.out.println(KM.toString());
// for(String option : KM.getOptions()) {
// System.out.println(option);
// }
// System.out.println("CentroIds:" + tempIns);
} catch(Exception e) {
e.printStackTrace();
}
}
}
在上面的算法之中,使用的是SimpleKMeans这个类。
使用EM算法的方法几乎一样,唯一的不同就是在设置类数目的时候可以设置成-1. 如下:
EM em = null;
em = new EM();
// 使用交叉验证自动选择聚类数目
em.setNumClusters(-1);
em.setMaxIterations(100);
em.buildClusterer(ins);
具体可以看源码:
/**
* Set the number of clusters (-1 to select by CV).
*
* @param n the number of clusters
* @throws Exception if n is 0
*/
@Override
public void setNumClusters(int n) throws Exception {
if (n == 0) {
throw new Exception("Number of clusters must be > 0. (or -1 to "
+ "select by cross validation).");
}
if (n < 0) {
m_num_clusters = -1;
m_initialNumClusters = -1;
} else {
m_num_clusters = n;
m_initialNumClusters = n;
}
}
关于EM 以及K-Means的具体描述,请自行百度吧~