您的位置:首页 > 其它

关于《深入推荐引擎相关算法 - 聚类》文章学习感悟

2014-07-09 16:54 423 查看
查找资料发现很多网站都引用了《深入推荐引擎相关算法 - 聚类》这篇文章,里面关于聚类相关算法的调用作了详细的介绍;但是这篇文章引用的Mahout 包是老版本的,所以对于新版 Mahout 包而言,改动非常大。

新版 与 旧版最大的区别:

1. 聚类算法的驱动类 Driver 不支持读取 Vector 集合数据 List<Vector> ;只提供读取文件的形式。

2. 引用的Hadoop 包不一样。

《深入推荐引擎相关算法 - 聚类》原文地址

http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy3/

自己根据文章改下相关算法实现,代码如下:

1. 数据构造类

public class SimpleDataSet {

// 创建一个二维点集的向量组

public static final double[][] points = { { 1, 1 }, { 2, 1 }, { 1, 2 },

{ 2, 2 }, { 3, 3 }, { 8, 8 }, { 9, 8 }, { 8, 9 }, { 9, 9 }, { 5, 5 },

{ 5, 6 }, { 6, 6 }};

//SimpleDataSet 的 writePointsToFile 方法,将测试点集写入文件里

// 首先我们将测试点集包装成 VectorWritable 形式,从而将它们写入文件

public static List<VectorWritable> getPoints(double[][] raw) {

List<VectorWritable> points = new ArrayList<VectorWritable>();

for (int i = 0; i < raw.length; i++) {

double[] fr = raw[i];

Vector vec = new RandomAccessSparseVector(fr.length);

vec.assign(fr);

// 只是在加入点集前,在 RandomAccessSparseVector 外加了一层 VectorWritable 的包装

points.add(new VectorWritable(vec));

}

return points;

}

// 将 VectorWritable 的点集写入文件,这里涉及一些基本的 Hadoop 编程元素,详细的请参阅参考资源里相关的内容

public static void writePointsToFile(Path output) throws IOException {

// 调用前面的方法生成点集

List<VectorWritable> pointVectors = getPoints(points);

// 设置 Hadoop 的基本配置

Configuration conf = new Configuration();

// 生成 Hadoop 文件系统对象 FileSystem

FileSystem fs = FileSystem.get(output.toUri(), conf);

// 生成一个 SequenceFile.Writer,它负责将 Vector 写入文件中

SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf, output, Text.class, VectorWritable.class);

// 这里将向量按照文本形式写入文件

try {

for (VectorWritable vw : pointVectors) {

writer.append(new Text(), vw);

}

} finally {

writer.close();

}

}

}

2. KMeans 算法调用

public class KMeansTest {

//输入输出路径

public static String testpointsPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/input/test.txt";

public static String outputPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/output";

/*

* 测试代码

*/

public static void main(String[] args) throws Exception {

// 声明一个计算距离的方法,这里选择了欧几里德距离

DistanceMeasure measure = new EuclideanDistanceMeasure();

// 指定输入路径,如前面介绍的一样,基于 Hadoop 的实现就是通过指定输入输出的文件路径来指定数据源的。

Path testpoints = new Path(testpointsPath);

Path output = new Path(outputPath);

Configuration conf = new Configuration();

// 清空输入输出路径下的数据

HadoopUtil.delete(conf, testpoints);

HadoopUtil.delete(conf, output);

// 在输入路径下生成点集,与内存的方法不同,这里需要把所有的向量写进文件,下面给出具体的例子

SimpleDataSet.writePointsToFile(testpoints);

// 指定需要聚类的个数,这里选择 2 类

int k = 2;

// 指定 K 均值聚类算法的最大迭代次数

int maxIter = 10;

// 指定 K 均值聚类算法的最大距离阈值

double distanceThreshold = 0.01;

// 随机K个聚类中心所在文件位置

Path clusters = new Path(output, "random-seeds");

RandomSeedGenerator.buildRandom(conf,testpoints,clusters, k, measure);

/*

* 调用KMeans方法进行聚类分析

* 参数:

* conf hadoop基本配置

* input 聚类输入源数据

* clusterIn K个初始化聚类中心点

* output 结果保存位置

* covergenceDelta 收敛系数

* maxIter 最大迭代次数

* runClustering 聚类点划分

* distanceThreshold 距离阈值

* runSequential 是否本地运行

*/

KMeansDriver.run(conf,testpoints, clusters, output,0.5,maxIter, true,distanceThreshold,false);

// 调用 ClusterDumper 的 printClusters 方法将聚类结果打印出来。

ClusterDumper clusterDumper = new ClusterDumper(new Path(output, "clusters-*-final"), new Path(output,"clusteredPoints"));

clusterDumper.printClusters(null);

}

}

3. Canopy算法调用

public class CanopyTest {

//输入输出路径

public static String testpointsPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/input/test.txt";

public static String outputPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/output";

/*

*

* 测试代码

*/

public static void main(String[] args) throws Exception {

// 设置距离阈值 T1,T2

double t1 = 4.0;

double t2 = 3.0;

// 声明距离计算的方法

DistanceMeasure measure = new EuclideanDistanceMeasure();

// 设置输入输出的文件路径

Path testpoints = new Path(testpointsPath);

Path output = new Path(outputPath);

Configuration conf = new Configuration();

// 清空输入输出路径下的数据

HadoopUtil.delete(conf, testpoints);

HadoopUtil.delete(conf, output);

// 将测试点集写入输入目录下

SimpleDataSet.writePointsToFile(testpoints);

// 调用 CanopyDriver.buildClusters 的方法执行 Canopy 聚类,参数是:

// 1. 输入路径,输出路径

// 2. 计算距离的方法

// 3. 距离阈值 T1 和 T2

CanopyDriver.run(conf, testpoints, output, measure, t1, t2, true, 0.01, false);

ClusterDumper clusterDumper = new ClusterDumper(new Path(output, "clusters-*-final"), new Path(output,"clusteredPoints"));

clusterDumper.printClusters(null);

}

}

4. FuzzyKmeans算法调用

public class FuzzyKMeansTest {

//输入输出路径

public static String testpointsPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/input/test.txt";

public static String outputPath = "hdfs://192.168.9.72:9000/test/cluster/kmeans/output";

public static void main(String[] args) throws Exception {

// 声明一个计算距离的方法,这里选择了欧几里德距离

DistanceMeasure measure = new EuclideanDistanceMeasure();

// 指定输入路径,如前面介绍的一样,基于 Hadoop 的实现就是通过指定输入输出的文件路径来指定数据源的。

Path testpoints = new Path(testpointsPath);

Path output = new Path(outputPath);

Configuration conf = new Configuration();

// 清空输入输出路径下的数据

HadoopUtil.delete(conf, testpoints);

HadoopUtil.delete(conf, output);

// 在输入路径下生成点集,与内存的方法不同,这里需要把所有的向量写进文件,下面给出具体的例子

SimpleDataSet.writePointsToFile(testpoints);

// 指定模糊 K 均值聚类算法的模糊参数

float fuzzificationFactor = 5.0f;

// 指定需要聚类的个数,这里选择 2 类

int k = 2;

// 指定 K 均值聚类算法的最大迭代次数

int maxIter = 10;

// 指定 K 均值聚类算法的最大距离阈值

double distanceThreshold = 0.01;

// 随机K个聚类中心所在文件位置

Path clusters = new Path(output, "random-seeds");

RandomSeedGenerator.buildRandom(conf,testpoints,clusters, k, measure);

/*

* conf,input, clustersIn, output,

* convergenceDelta 收敛系数,

* maxIterations,

* m 模糊参数,

* runClustering,

* emitMostLikely,

* threshold, runSequential

*/

FuzzyKMeansDriver.run(conf, testpoints, clusters, output, 0.5, maxIter,fuzzificationFactor, true, true, distanceThreshold, false);

// 调用 ClusterDumper 的 printClusters 方法将聚类结果打印出来。

ClusterDumper clusterDumper = new ClusterDumper(new Path(output, "clusters-*-final"), new Path(output,"clusteredPoints"));

clusterDumper.printClusters(null);

}

}

关于狄利克雷算法,新版Mahout已经摒弃该算法了;已经没有相关驱动类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐