基于Mahout实现K-Means聚类

需求分析

需要对数据集进行预处理,选择合适的特征进行聚类分析,确定聚类的数量和初始中心点,调用Mahout提供的K-Means算法进行聚类计算,评估聚类结果的准确性和稳定性。同时,需要对Mahout的使用和参数调优进行深入学习和实践,以保证聚类结果的有效性和可靠性。

系统实现

    1.对实验整体的理解:

    本次实验,我们的目的是理解聚类的原理,并且掌握常见聚类的算法,以及掌握使用Mahout实现K-Means聚类分析算法的过程。

     2.实验整体流程分析:

  • 创建项目,导入开发依赖包
  • 编写工具类
  • 编写聚类分析的代码
  • 将聚类结果输出
  • 评估聚类的效果

     3.准备工作:

  • 使用IDEA创建一个Maven项目:mahout_kmeans_demo

 

  • 修改pom.xml文件,导入开发MapReduce所需的Jar包
 <dependencies><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-common</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-core</artifactId><version>2.6.0</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-mr</artifactId><version>0.13.0</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-math</artifactId><version>0.13.0</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-hdfs</artifactId><version>0.13.0</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-integration</artifactId><version>0.13.0</version></dependency><dependency><groupId>org.apache.mahout</groupId><artifactId>mahout-examples</artifactId><version>0.13.0</version></dependency>
</dependencies>

下载相关依赖包

等待pom.xml文件不再出现错误即可 

  • 准备实验数据并下载

  • 启动Hadoop集群。

终端输入start-all.sh

可以使用jps命令查看集群启动情况。

     4.执行聚类过程:

  • 编写工具类HdfsUtil,对HDFS的基本操作进行封装
package com;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.mapred.JobConf;import java.io.IOException;
import java.net.URI;public class HdfsUtil {private static final String HDFS = "hdfs://master:9000/";private String hdfsPath;private Configuration conf;public HdfsUtil(Configuration conf) {this(HDFS, conf);}public HdfsUtil(String hdfs, Configuration conf) {this.hdfsPath = hdfs;this.conf = conf;}public static JobConf config() {JobConf conf = new JobConf(HdfsUtil.class);conf.setJobName("HdfsDAO");return conf;}public void mkdirs(String folder) throws IOException {Path path = new Path(folder);FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);if (!fs.exists(path)) {fs.mkdirs(path);System.out.println("Create: " + folder);}fs.close();}public void rmr(String folder) throws IOException {Path path = new Path(folder);FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);fs.deleteOnExit(path);System.out.println("Delete: " + folder);fs.close();}public void ls(String folder) throws IOException {Path path = new Path(folder);FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);FileStatus[] list = fs.listStatus(path);System.out.println("ls: " + folder);System.out.println("==========================================================");for (FileStatus f : list) {System.out.printf("name: %s, folder: %s, size: %d\n", f.getPath(), f.isDir(), f.getLen());}System.out.println("==========================================================");fs.close();}public void createFile(String file, String content) throws IOException {FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);byte[] buff = content.getBytes();FSDataOutputStream os = null;try {os = fs.create(new Path(file));os.write(buff, 0, buff.length);System.out.println("Create: " + file);} finally {if (os != null)os.close();}fs.close();}public void copyFile(String local, String remote) throws IOException {FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);fs.copyFromLocalFile(new Path(local), new Path(remote));System.out.println("copy from: " + local + " to " + remote);fs.close();}public void download(String remote, String local) throws IOException {Path path = new Path(remote);FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);fs.copyToLocalFile(path, new Path(local));System.out.println("download: from" + remote + " to " + local);fs.close();}public void cat(String remoteFile) throws IOException {Path path = new Path(remoteFile);FileSystem fs = FileSystem.get(URI.create(hdfsPath), conf);FSDataInputStream fsdis = null;System.out.println("cat: " + remoteFile);try {fsdis = fs.open(path);IOUtils.copyBytes(fsdis, System.out, 4096, false);} finally {IOUtils.closeStream(fsdis);fs.close();}}
}
  • 编写KMeansMahout类,执行聚类过程
package com;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.mahout.clustering.Cluster;
import org.apache.mahout.clustering.canopy.CanopyDriver;
import org.apache.mahout.clustering.conversion.InputDriver;
import org.apache.mahout.clustering.kmeans.KMeansDriver;
import org.apache.mahout.common.HadoopUtil;
import org.apache.mahout.common.distance.EuclideanDistanceMeasure;
import org.apache.mahout.utils.clustering.ClusterDumper;public class KMeansMahout {private static final String HDFS = "hdfs://master:9000";public static void main(String[] args) throws Exception {String localFile = "/home/data/iris.dat";//  mahout输出至HDFS的目录String outputPath = HDFS + "/user/hdfs/kmeans/output";//  mahout的输入目录String inputPath = HDFS + "/user/hdfs/kmeans/input/";//  canopy算法的t1和t2double t1 = 2;double t2 = 1;//  收敛阀值double convergenceDelta = 0.5;//  最大迭代次数int maxIterations = 10;Path output = new Path(outputPath);Path input = new Path(inputPath);Configuration conf = new Configuration();HdfsUtil hdfs = new HdfsUtil(HDFS, conf);hdfs.rmr(inputPath);hdfs.mkdirs(inputPath);hdfs.copyFile(localFile, inputPath);hdfs.ls(inputPath);//  每次执行聚类前,删除掉上一次的输出目录HadoopUtil.delete(conf, output);//  执行聚类run(conf, input, output, new EuclideanDistanceMeasure(), t1, t2, convergenceDelta, maxIterations);}private static void run(Configuration conf, Path input, Path output,EuclideanDistanceMeasure euclideanDistanceMeasure, double t1, double t2,double convergenceDelta, int maxIterations) throws Exception {Path directoryContainingConvertedInput = new Path(output, "data");System.out.println("Preparing  Input");//  将输入文件序列化,并选取RandomAccessSparseVector作为保存向量的数据结构InputDriver.runJob(input, directoryContainingConvertedInput,"org.apache.mahout.math.RandomAccessSparseVector");System.out.println("Running  Canopy  to  get  initial  clusters");//  保存canopy的目录Path canopyOutput = new Path(output, "canopies");//  执行Canopy聚类CanopyDriver.run(conf, directoryContainingConvertedInput, canopyOutput,euclideanDistanceMeasure, t1, t2, false, 0.0, false);System.out.println("Running  KMeans");//  执行k-means聚类,并使用canopy目录KMeansDriver.run(conf, directoryContainingConvertedInput,new Path(canopyOutput, Cluster.INITIAL_CLUSTERS_DIR + "-final"),output, convergenceDelta, maxIterations, true, 0.0, false);System.out.println("run  clusterdumper");//  将聚类的结果输出至HDFSClusterDumper clusterDumper = new ClusterDumper(new Path(output, "clusters-*-final"),new Path(output, "clusteredPoints"));clusterDumper.printClusters(null);}
}

在KmeansMahout类上点击右键并执行程序

 执行结果在HDFS目录中

     5.解析聚类结果:

  • 从Mahout的输出目录下提取出所要的信息

  • 编写ClusterOutput类,解析聚类后结果
package com;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.mahout.clustering.classify.WeightedPropertyVectorWritable;
import org.apache.mahout.math.Vector;import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;public class ClusterOutput {private static final String HDFS = "hdfs://master:9000";public static void main(String[] args) {try {//   需要被解析的mahout的输出文件String clusterOutputPath = "/user/hdfs/kmeans/output";//   解析后的聚类结果,将输出至本地磁盘String resultPath = "/home/data/result.txt";BufferedWriter bw;Configuration conf = new Configuration();conf.set("fs.default.name", HDFS);FileSystem fs = FileSystem.get(conf);SequenceFile.Reader reader = null;reader = new SequenceFile.Reader(fs, new Path(clusterOutputPath + "/clusteredPoints/part-m-00000"), conf);bw = new BufferedWriter(new FileWriter(new File(resultPath)));//   key为聚簇中心IDIntWritable key = new IntWritable();WeightedPropertyVectorWritable value = new WeightedPropertyVectorWritable();while (reader.next(key, value)) {//   得到向量Vector vector = value.getVector();String vectorValue = "";//   将向量各个维度拼接成一行,用\t分隔for (int i = 0; i < vector.size(); i++) {if (i == vector.size() - 1) {vectorValue += vector.get(i);} else {vectorValue += vector.get(i) + "\t";}}bw.write(key.toString() + "\t" + vectorValue + "\n\n");}bw.flush();reader.close();} catch (Exception e) {e.printStackTrace();}}
}

在ClusterOutput类上右键执行程序

 执行结果被保存在/home/data/result.txt文件中,打开终端执行以下命令

     6.评估聚类效果:

  • 编写InterClusterDistances类,计算平均簇间距离
package com;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Writable;
import org.apache.mahout.clustering.Cluster;
import org.apache.mahout.clustering.iterator.ClusterWritable;
import org.apache.mahout.common.distance.DistanceMeasure;
import org.apache.mahout.common.distance.EuclideanDistanceMeasure;import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class InterClusterDistances {private static final String HDFS = "hdfs://master:9000";public static void main(String[] args) throws Exception {String inputFile = HDFS + "/user/hdfs/kmeans/output";System.out.println("聚类结果文件地址:" + inputFile);Configuration conf = new Configuration();Path path = new Path(inputFile + "/clusters-2-final/part-r-00000");System.out.println("Input Path:" + path);FileSystem fs = FileSystem.get(path.toUri(), conf);List<Cluster> clusters = new ArrayList<Cluster>();SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf);Writable key = (Writable) reader.getKeyClass().newInstance();ClusterWritable value = (ClusterWritable) reader.getValueClass().newInstance();while (reader.next(key, value)) {Cluster cluster = value.getValue();clusters.add(cluster);value = (ClusterWritable) reader.getValueClass().newInstance();}System.out.println("Cluster In Total:" + clusters.size());DistanceMeasure measure = new EuclideanDistanceMeasure();double max = 0;double min = Double.MAX_VALUE;double sum = 0;int count = 0;Set<Double> total = new HashSet<Double>();// 如果聚类的个数大于1才开始计算if (clusters.size() != 1 && clusters.size() != 0) {for (int i = 0; i < clusters.size(); i++) {for (int j = 0; j < clusters.size(); j++) {double d = measure.distance(clusters.get(i).getCenter(), clusters.get(j).getCenter());min = Math.min(d, min);max = Math.max(d, max);total.add(d);sum += d;count++;}}System.out.println("Maximum Intercluster Distance:" + max);System.out.println("Minimum Intercluster Distance:" + min);System.out.println("Average Intercluster Distance:" + sum / count);for (double d : total) {System.out.print("[" + d + "] ");}} else if (clusters.size() == 1) {System.out.println("只有一个类,无法判断聚类质量");} else if (clusters.size() == 0) {System.out.println("聚类失败");}}
}

同样右键执行程序,得到下图结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/716143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

顶会ICLR2024论文Time-LLM:基于大语言模型的时间序列预测

文青松 松鼠AI首席科学家、AI研究院负责人 美国佐治亚理工学院(Georgia Tech)电子与计算机工程博士&#xff0c;人工智能、决策智能和信号处理方向专家&#xff0c;在松鼠AI、阿里、Marvell等公司超10年的技术和管理经验&#xff0c;近100篇文章发表在人工智能相关的顶会与顶刊…

Cloud整合Zookeeper代替Eureka

微服务间通信重构与服务治理笔记-CSDN博客 Zookeeper是一个分布式协调工具,可以实现注册中心功能 安装Zookeeper 随便 就用最新版本吧 进入Zookeeper 包目录 cd /usr/local/develop/ 解压 tar -zxvf apache-zookeeper-3.9.1-bin.tar.gz -C /usr/local/develop 进入配置文件…

StarRocks实战——首汽约车实时数仓实践

目录 前言 一、引入背景 二、OLAP引擎选型 三、架构演进 四、实时数仓构建 五、业务实践价值未来规划 原文大佬的这篇首汽约车实时数仓实践有借鉴意义&#xff0c;这里摘抄下来用作学习和知识沉淀。 前言 首汽约车&#xff08;以下简称“首约”&#xff09;是首汽集团打造…

Vue+SpringBoot打造大学计算机课程管理平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 实验课程档案模块2.2 实验资源模块2.3 学生实验模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 实验课程档案表3.2.2 实验资源表3.2.3 学生实验表 四、系统展示五、核心代码5.1 一键生成实验5.2 提交实验5.3 批阅实…

131. 分割回文串(力扣LeetCode)

文章目录 131. 分割回文串题目描述回溯代码 131. 分割回文串 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xff1a; 输入&#xf…

Android 架构MVI、MVVM、MVC、MVP

目录 一、MVC&#xff08;Model-View-Controller&#xff09; 二、 MVP&#xff08;Model-View-Presenter&#xff09; 三. MVVM&#xff08;Model-View-ViewModel&#xff09; 四. MVI&#xff08;Model-View-Intent&#xff09; 五.MVI简单实现 先简单了解一下MVC、MVP和…

索引使用规则6——单列索引联合索引

1、单列索引 单列索引&#xff1a;即一个索引只包含单个列 举个例子 1.1、给phone和那么建立索引 create index index_name on tb_qianzhui(name); create index index_phone on tb_qianzhui(phone);1.2、查询发现可能的索引有好几个&#xff0c;但是最终选择了phone的索引…

萝卜大杂烩 | 提高数据科学工作效率的 8 个 Python 库

本文来源公众号“萝卜大杂烩”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;提高数据科学工作效率的 8 个 Python 库 在进行数据科学时&#xff0c;可能会浪费大量时间编码并等待计算机运行某些东西。所以我选择了一些 Python 库…

贪吃蛇(C语言)步骤讲解

一&#xff1a;文章大概 使用C语言在windows环境的控制台中模拟实现经典小游戏 实现基本功能&#xff1a; 1.贪吃蛇地图绘制 2.蛇吃食物的功能&#xff08;上&#xff0c;下&#xff0c;左&#xff0c;右方向控制蛇的动作&#xff09; 3.蛇撞墙死亡 4.计算得分 5.蛇身加…

[C语言]——C语言常见概念(1)

目录 一.C语言是什么、 二.C语言的历史和辉煌 三.编译器的选择&#xff08;VS2022为例&#xff09; 1.编译和链接 2.编译器的对比 3.VS2022 的优缺点 四.VS项目和源文件、头文件介绍 五.第⼀个C语言程序 ​​​​​​​ 一.C语言是什么、 ⼈和⼈交流使⽤的是⾃然语⾔&…

【python】爬取链家二手房数据做数据分析【附源码】

一、前言、 在数据分析和挖掘领域中&#xff0c;网络爬虫是一种常见的工具&#xff0c;用于从网页上收集数据。本文将介绍如何使用 Python 编写简单的网络爬虫程序&#xff0c;从链家网上海二手房页面获取房屋信息&#xff0c;并将数据保存到 Excel 文件中。 二、效果图&#…

【JS】解构赋值注意点,解构赋值报错

报错代码 const 小明 { email: 6, pwd: 66 } const 小刚 { email: 9, pwd: 99 }const { email } 小明 const { email } 小刚 报错图 原因 2个常量重复&#xff0c;重复在同一个作用域内是不能重复的&#xff0c;例如大括号内{const a 1; const a 2} 小伙伴A提问 问&…

Redis-基础篇

Redis是一个开源、高性能、内存键值存储数据库&#xff0c;由 Salvatore Sanfilippo&#xff08;网名antirez&#xff09;创建&#xff0c;并在BSD许可下发布。它不仅可以用作缓存系统来加速数据访问&#xff0c;还可以作为持久化的主数据存储系统或消息中间件使用。Redis因其数…

leetcode:37.解数独

题目理解&#xff1a;本题中棋盘的每一个位置都要放一个数字&#xff08;而N皇后是一行只放一个皇后&#xff09;&#xff0c;并检查数字是否合法&#xff0c;解数独的树形结构要比N皇后更宽更深。 代码实现&#xff1a;

SpringBoot+Redis 解决海量重复提交问题,yyds!

在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求&#xff0c;我们来解释一下幂等的概念&#xff1a;任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义&#xff0c;最终的含义就是 对数据库的影响只能是一次性的&#xff0c;不能重复处理。如何保证其…

JetBrains Gateway Github Copilot 客户端插件和主机插件

JetBrains Gateway可以通过插件支持Github Copilot&#xff08;需另行注册&#xff09;。 需要安装插件 客户端&#xff0c;而非插件 主机&#xff0c;如图所示&#xff1a; 大概是因为代码显示在客户端&#xff08;运行在本地的IDE&#xff09;&#xff1f;

NOC2023软件创意编程(学而思赛道)python初中组复赛真题

目录 下载打印原文档做题: 软件创意编程 一、参赛范围 1.参赛组别:小学低年级组(1-3 年级)、小学高年级组(4-6 年级)、初中组。 2.参赛人数:1 人。 3.指导教师:1 人(可空缺)。 4.每人限参加 1 个赛项。 组别确定:以地方教育行政主管部门(教委、教育厅、教育局) 认…

Python 潮流周刊#40:白宫建议使用 Python 等内存安全的语言

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。本周刊开源&#xff0c;欢迎投稿[1]。另有电报频道[2]作为副刊&#xff0c;补充发布更加丰富的资讯&#xff0c;…

三层靶机靶场之环境搭建

下载&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;f4as 简介 2019某CTF线下赛真题内网结合WEB攻防题库&#xff0c;涉 及WEB攻击&#xff0c;内网代理路由等技术&#xff0c;每台服务器存在一个 Flag&#xff0c;获取每一 个Flag对应一个积分&…

在docker中搭建selenium 爬虫环境(3分钟快速搭建)

1、安装docker 省略 2、拉取镜像 docker pull selenium/standalone-chrome-debug 3、运行容器 docker run -d -p 4444:4444 -p 5900:5900 -v C:\Users\Public\VNC_Donwnloads:/home/seluser/Downloads --memory6g --name selenium_chrome selenium/standalone-chrome-debu…