读代码-RandomSeedGenerator

package org.apache.mahout.clustering.kmeans;
public final class RandomSeedGenerator
完成中心点随机取样的过程

hdfs操作,比较普遍,先删除再新建

FileSystem fs = FileSystem.get(output.toUri(), conf);
HadoopUtil.delete(conf, output);
Path outFile = new Path(output, "part-randomSeed");
boolean newFile = fs.createNewFile(outFile);


遍历hdfs路径框架
fs.globStatus(inputPathPattern, PathFilters.logsCRCFilter());
globStatus返回了匹配pattern的所有路径
logsCRCFilter过滤掉了以_开头的日志,点开头的隐藏及.crc文件
循环时滤掉文件夹,只处理文件

if (newFile) {
Path inputPathPattern;

if (fs.getFileStatus(input).isDir()) {
inputPathPattern = new Path(input, "*");
} else {
inputPathPattern = input;
}

FileStatus[] inputFiles = fs.globStatus(inputPathPattern, PathFilters.logsCRCFilter());
for (FileStatus fileStatus : inputFiles) {
if (fileStatus.isDir()) {
continue;
}
//process file
}

}



初始化writer
准备k个容量的list存储选出的值

SequenceFile.Writer writer = SequenceFile.createWriter(fs, conf, outFile, Text.class, Cluster.class);
Random random = RandomUtils.getRandom();
List<Text> chosenTexts = new ArrayList<Text>(k);
List<Cluster> chosenClusters = new ArrayList<Cluster>(k);
int nextClusterId = 0;



随机的核心--蓄水池算法

for (Pair<Writable,VectorWritable> record
: new SequenceFileIterable<Writable,VectorWritable>(fileStatus.getPath(), true, conf)) {
Writable key = record.getFirst();
VectorWritable value = record.getSecond();
Cluster newCluster = new Cluster(value.get(), nextClusterId++, measure);
newCluster.observe(value.get(), 1);
Text newText = new Text(key.toString());
int currentSize = chosenTexts.size();
if (currentSize < k) {
chosenTexts.add(newText);
chosenClusters.add(newCluster);
} else if (random.nextInt(currentSize + 1) == 0) { // with chance 1/(currentSize+1) pick new element
int indexToRemove = random.nextInt(currentSize); // evict one chosen randomly
chosenTexts.remove(indexToRemove);
chosenClusters.remove(indexToRemove);
chosenTexts.add(newText);
chosenClusters.add(newCluster);
}
}
<think>我们正在处理用户关于在Hadoop上使用Mahout运行KMeans聚类算法的问题。根据提供的引用,我们可以整理出以下步骤:1.环境准备:安装和配置Hadoop、Mahout以及Java环境。2.数据准备:将输入数据转换成MahoutKMeans算法要求的格式(通常是SequenceFile格式)。3.生成初始聚类中心:可以使用Mahout提供的kmeans聚类算法生成初始中心点,或者随机生成。4.运行KMeans算法:通过命令行调用Mahout的kmeans命令。5.查看结果:Mahout输出的聚类结果需要转换回可格式。具体步骤:**1.环境配置**根据引用[4],需要配置Java、Hadoop和Mahout的环境变量。确保在/etc/profile中设置JAVA_HOME、HADOOP_HOME、MAHOUT_HOME等,并将它们的bin目录加入PATH。**2.数据准备**Mahout的KMeans算法要求输入数据为SequenceFile格式,其中键为文本(通常可以忽略),值为向量(VectorWritable)。用户需要将原始数据转换成这种格式。例如,如果原始数据是文本文件,每行是一个用空格分隔的数值向量,可以使用Mahout提供的`seqdirectory`和`seq2sparse`工具进行转换,或者自己编写程序转换。**3.生成初始聚类中心**可以使用Mahout的`kmeans`命令的`-c`参数指定初始聚类中心路径。如果该路径不存在,Mahout会随机选择输入数据中的点作为初始中心。也可以使用`org.apache.mahout.clustering.kmeans.RandomSeedGenerator`生成随机中心点。**4.运行KMeans算法**命令行示例(引用[2]):```mahoutkmeans-i<inputvectors>-c<initialclusters>-o<outputdirectory>-k<numberofclusters>-x<maxiterations>-ow--clustering```参数说明:-`-i`:输入向量路径(HDFS路径)-`-c`:初始聚类中心路径-`-o`:输出目录-`-k`:聚类数目-`-x`:最大迭代次数-`-ow`:如果输出目录存在则覆盖-`--clustering`:在迭代结束后运行聚类分配步骤,将每个点分配到最终的聚类中**5.结果转换**Mahout的输出结果也是SequenceFile格式,可以使用`clusterdump`工具转换成可文本:```mahoutclusterdump-i<clusters-*-final>-o<outputtextfile>-p<clusteredPointsdirectory>-d<dictionaryfile>-dtsequencefile-b100-n20--evaluate-dmorg.apache.mahout.common.distance.EuclideanDistanceMeasure-sp0```其中:-`-i`:聚类中心路径(如输出目录下的`clusters-*-final`)-`-p`:包含聚类点的路径(通常为输出目录下的`clusteredPoints`)-`-o`:输出的文本文件-`-d`:字典文件(如果数据是文本形式的向量,可能需要字典来映射特征索引到实际词)-`-dt`:字典文件格式(如`sequencefile`或`text`)注意:在运行Mahout命令前,确保Hadoop集群已经启动。**常见错误**:-输入路径不存在(如引用[3]中的错误):确保输入路径在HDFS上存在,并且路径正确。-环境变量配置错误:确保Mahout、Hadoop等环境变量配置正确,并且可以在命令行中调用。根据上述步骤,我们可以为用户提供一个详细的教程。由于用户要求生成相关问题,我们在回答后添加相关问题。现在,我们按照用户要求的结构化方式回答。</think>### 在Hadoop上使用Mahout实现KMeans聚类算法的步骤 #### 1. **环境准备** - **安装配置**: - 安装Java(JDK 1.7+)、Hadoop(1.x或2.x)、Mahout(0.6+)[^4] - 配置环境变量(示例配置): ```bash export JAVA_HOME=/usr/java/jdk1.8.0_301 export HADOOP_HOME=/usr/lib/hadoop export MAHOUT_HOME=/opt/mahout export PATH=$PATH:$HADOOP_HOME/bin:$MAHOUT_HOME/bin ``` - **验证安装**: ```bash hadoop version # 验证Hadoop mahout --help # 验证Mahout ``` #### 2. **数据预处理** - **格式转换**:将原始数据转换为Mahout支持的SequenceFile格式(键值对存储) ```bash mahout seqdirectory -i /input/raw_data -o /output/seq_data -c UTF-8 ``` - **向量化**:将文本数据转换为数值向量(TF-IDF等) ```bash mahout seq2sparse -i /output/seq_data -o /output/tfidf-vectors ``` #### 3. **运行KMeans算法** - **命令行执行**(关键参数说明)[^2]: ```bash mahout kmeans \ -i /output/tfidf-vectors \ # 输入向量路径 -c /output/initial-clusters \ # 初始聚类中心路径 -o /output/kmeans-result \ # 输出目录 -k 10 \ # 聚类数量 -x 100 \ # 最大迭代次数 -ow \ # 覆盖输出目录 --clustering # 执行聚类分配 ``` - **参数细节**: - 若未提供初始中心点(`-c`),Mahout会随机选择$k$个点作为初始中心 - 使用`-dm`指定距离度量(默认为欧氏距离) #### 4. **结果解析** - **转换可格式**: ```bash mahout clusterdump \ -i /output/kmeans-result/clusters-*-final \ # 最终聚类中心 -o ./clusters.txt \ # 文本输出路径 -d /output/tfidf-vectors/dictionary.file-0 \ # 字典文件 -dt sequencefile # 字典格式 ``` #### 5. **常见问题解决** - **路径错误**:确保所有路径在HDFS中存在(避免`Input path does not exist`错误)[^3] - **内存不足**:在`mahout-env.sh`中调整JVM堆大小: ```bash export MAHOUT_HEAPSIZE=4096 ``` - **版本兼容**:Mahout 0.9+需显式调用Spark/H2O后端: ```bash mahout spark-kmeans -i ... # Spark模式 ``` > **关键提示**:完整流程依赖HDFS数据存储,所有输入/输出路径需为HDFS路径(如`hdfs://namenode:8020/path`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值