关于《深入推荐引擎相关算法 - 聚类》文章学习感悟
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已经摒弃该算法了;已经没有相关驱动类。
新版 与 旧版最大的区别:
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已经摒弃该算法了;已经没有相关驱动类。
相关文章推荐
- [学习]探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 3. 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 深入相关算法,聚类:探索推荐引擎内部的秘密(3)
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密:深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密:深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密-第 3 部分: 深入推荐引擎相关算法 - 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类
- 深入推荐引擎相关算法 ---- 聚类
- 探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类