基于Hadoop的Knn算法实现

2023-10-29

    Knn算法的核心思想是如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。Knn方法在类别决策时,只与极少量的相邻样本有关。由于Knn方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,Knn方法较其他方法更为合适。

    Knn算法流程如下:

    1. 计算当前测试数据与训练数据中的每条数据的距离

    2. 圈定距离最近的K个训练对象,作为测试对象的近邻

    3. 计算这K个训练对象中出现最多的那个类别,并将这个类别作为当前测试数据的类别


    以上流程是Knn的大致流程,按照这个流程实现的MR效率并不高,可以在这之上进行优化。在这里只写,跟着这个流程走的MR实现过程。

    Mapper的设计

    由于测试数据相比于训练数据来说,会小很多,因此将测试数据用Java API读取,放到内存中。所以,在setup中需要对测试数据进行初始化。在map中,计算当前测试数据与每条训练数据的距离,Mapper的值类型为:<Object, Text, IntWritable,MyWritable>。map输出键类型为IntWritable,存放当前测试数据的下标,输出值类型为MyWritable,这是自定义值类型,其中存放的是距离以及与测试数据比较的训练数据的类别。

public class KnnMapper extends Mapper<Object, Text, IntWritable,MyWritable> {
	Logger log = LoggerFactory.getLogger(KnnMapper.class);
	private List<float[]> testData;
	@Override
	protected void setup(Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		Configuration conf= context.getConfiguration();
		conf.set("fs.defaultFS", "master:8020");
		String testPath= conf.get("TestFilePath");
		Path testDataPath= new Path(testPath);
		FileSystem fs = FileSystem.get(conf);
		this.testData = readTestData(fs,testDataPath);
	}
	
	@Override
	protected void map(Object key, Text value, Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		String[] line = value.toString().split(",");
		float[] trainData = new float[line.length-1];
		for(int i=0;i<trainData.length;i++){
			trainData[i] = Float.valueOf(line[i]);
			log.info("训练数据:"+line[i]+"类别:"+line[line.length-1]);
		}
		for(int i=0; i< this.testData.size();i++){
			float[] testI = this.testData.get(i);
			float distance = Outh(testI, trainData);
			log.info("距离:"+distance);
			context.write(new IntWritable(i), new MyWritable(distance, line[line.length-1]));
		}
	}
	
	
	private List<float[]> readTestData(FileSystem fs,Path Path) throws IOException {
		//补充代码完整
		FSDataInputStream data = fs.open(Path);
		BufferedReader bf = new BufferedReader(new InputStreamReader(data));
		String line = "";
		List<float[]> list = new ArrayList<>();
		while ((line = bf.readLine()) != null) {
			String[] items = line.split(",");
			float[] item = new float[items.length];
			for(int i=0;i<items.length;i++){
				item[i] = Float.valueOf(items[i]);
			}
			list.add(item);
		}
		return list;
	}
	// 计算欧式距离
	private static float Outh(float[] testData, float[] inData) {
		float distance =0.0f;
		for(int i=0;i<testData.length;i++){
			distance += (testData[i]-inData[i])*(testData[i]-inData[i]);
		}
		distance = (float)Math.sqrt(distance);
		return distance;
	}
}
    自定义值类型MyWritable如下:
public class MyWritable implements Writable{
	private float distance;
	private String label;
	public MyWritable() {
		// TODO Auto-generated constructor stub
	}
	public MyWritable(float distance, String label){
		this.distance = distance;
		this.label = label;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return this.distance+","+this.label;
	}
	@Override
	public void write(DataOutput out) throws IOException {
		// TODO Auto-generated method stub
		out.writeFloat(distance);
		out.writeUTF(label);
	}
	@Override
	public void readFields(DataInput in) throws IOException {
		// TODO Auto-generated method stub
		this.distance = in.readFloat();
		this.label = in.readUTF();
		
	}
	public float getDistance() {
		return distance;
	}

	public void setDistance(float distance) {
		this.distance = distance;
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

}
    在Reducer端中,需要初始化参数K,也就是圈定距离最近的K个对象的K值。在reduce中需要对距离按照从小到大的距离排序,然后选取前K条数据,再计算这K条数据中,出现次数最多的那个类别并将这个类别与测试数据的下标相对应并以K,V的形式输出到HDFS上。
public class KnnReducer extends Reducer<IntWritable, MyWritable, IntWritable, Text> {
	private int K;
	@Override
	protected void setup(Context context)
			throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		this.K = context.getConfiguration().getInt("K", 5);
	}
	@Override
	/***
	 * key => 0
	 * values =>([1,lable1],[2,lable2],[3,label2],[2.5,lable2])
	 */
	protected void reduce(IntWritable key, Iterable<MyWritable> values,
			Context context) throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		MyWritable[] mywrit = new MyWritable[K];
		for(int i=0;i<K;i++){
			mywrit[i] = new MyWritable(Float.MAX_VALUE, "-1");
		}
		// 找出距离最小的前k个
		for (MyWritable m : values) {
			float distance = m.getDistance();
			String label = m.getLabel();
			for(MyWritable m1: mywrit){
				if (distance < m1.getDistance()){
					m1.setDistance(distance);
					m1.setLabel(label);
				}
			}
		}
		// 找出前k个中,出现次数最多的类别
		String[] testClass = new String[K];
		for(int i=0;i<K;i++){
			testClass[i] = mywrit[i].getLabel();
		}
		String countMost = mostEle(testClass);
		context.write(key, new Text(countMost));
	}
	public static String mostEle(String[] strArray) {  
        HashMap<String, Integer> map = new HashMap<>();  
        for (int i = 0; i < strArray.length; i++) {
			String str = strArray[i];
        	if (map.containsKey(str)) {
				int tmp = map.get(str);
				map.put(str, tmp+1);
			}else{
				map.put(str, 1);
			}
		}
        // 得到hashmap中值最大的键,也就是出现次数最多的类别
        Collection<Integer> count = map.values();
        int maxCount = Collections.max(count);
        String maxString = "";
        for(Map.Entry<String, Integer> entry: map.entrySet()){
        	if (maxCount == entry.getValue()) {
				maxString = entry.getKey();
			}
        }
        return maxString;   
	}
}

    最后输出结果如下:


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Hadoop的Knn算法实现 的相关文章

  • 无法验证 serde:org.openx.data.jsonserde.jsonserde

    我编写了这个查询来在配置单元上创建一个表 我的数据最初是 json 格式 所以我已经下载并构建了 serde 并添加了它运行所需的所有 jar 但我收到以下错误 FAILED Execution Error return code 1 fr
  • 运行 Sqoop 导入和导出时如何找到最佳映射器数量?

    我正在使用 Sqoop 版本 1 4 2 和 Oracle 数据库 运行 Sqoop 命令时 例如这样 sqoop import fs
  • 在 Hadoop MapReduce 中为二进制文件创建自定义 InputFormat 和 RecordReader

    我正在编写一个 M R 作业 该作业处理以二进制格式编写的大型时间序列数据文件 如下所示 此处换行以提高可读性 显然 实际数据是连续的 TIMESTAMP 1 TIMESTAMP 1 TIMESTAMP 2 TIMESTAMP 2 TIME
  • 将 Spark 添加到 Oozie 共享库

    默认情况下 Oozie 共享 lib 目录提供 Hive Pig 和 Map Reduce 的库 如果我想在 Oozie 上运行 Spark 作业 最好将 Spark lib jar 添加到 Oozie 的共享库 而不是将它们复制到应用程序
  • Java8:使用 Stream / Map-Reduce / Collector 将 HashMap 转换为 HashMap

    我知道如何 改造 一个简单的JavaList from Y gt Z i e List
  • 更改 Hadoop 中的数据节点数量

    如何改变数据节点的数量 即禁用和启用某些数据节点来测试可扩展性 说得更清楚一点 我有4个数据节点 我想一一实验1 2 3 4个数据节点的性能 是否可以只更新名称节点中的从属文件 临时停用节点的正确方法 创建一个 排除文件 这列出了您想要删除
  • 适用于 Python 3.x 的 Hive 客户端

    是否可以使用 Python 3 x 连接到 hadoop 并运行 hive 查询 我正在使用Python 3 4 1 我发现可以按照这里写的方式完成 https cwiki apache org confluence display Hiv
  • 与文件名中的冒号“:”作斗争

    我有以下代码 用于加载大量 csv gz 并将它们转储到其他文件夹中 并将源文件名作为一列 object DailyMerger extends App def allFiles path File List File val parts
  • 全部配对图表上的所有路径

    这可能是一个没有最佳解决方案的问题 假设我有一个有向图 不知道它是否有循环 循环检测将是这个问题的方面之一 给定一组顶点 可能是数百万个顶点 我需要计算给定图的所有唯一对之间的所有不同路径 没有重复顶点的路径 我该如何应对这种情况 让我们看
  • 更改spark_temporary目录路径

    是否可以更改 temporarySpark在写入之前保存临时文件的目录 特别是 由于我正在编写表的单个分区 因此我希望临时文件夹位于分区文件夹内 是否可以 由于其实现原因 无法使用默认的 FileOutputCommiter FileOut
  • 在 Apache Spark 上下文中,内存数据存储意味着什么?

    我读到 Apache Spark 将数据存储在内存中 然而 Apache Spark 旨在分析大量数据 又称大数据分析 在这种情况下 内存数据存储的真正含义是什么 它可以存储的数据是否受到可用 RAM 的限制 它的数据存储与使用HDFS的A
  • 在 Google Cloud Dataproc 环境中使用 Hadoop 流式处理运行 python map reduce 作业时出错

    我想使用 hadoop 流方法在 Google Cloud Dataproc 中运行 python map reduce 作业 我的map reduce python脚本 输入文件和作业结果输出位于Google Cloud Storage中
  • sqoop 通过 oozie 导出失败

    我正在尝试将数据导出到mysql from hdfs通过sqoop 我可以通过 shell 运行 sqoop 并且它工作正常 但是当我通过调用oozie 它出现以下错误并失败 我还包括了罐子 没有描述性日志 sqoop脚本 export c
  • 以编程方式读取 Hadoop Mapreduce 程序的输出

    这可能是一个基本问题 但我在谷歌上找不到答案 我有一个映射缩减作业 它在其输出目录中创建多个输出文件 我的 Java 应用程序在远程 hadoop 集群上执行此作业 作业完成后 需要使用以下命令以编程方式读取输出org apache had
  • 使用mongodb聚合框架按数组长度分组

    我有一个看起来像这样的集合 id id0 name saved things id id1 name saved things id id2 name saved things etc 我想使用 mongodb 的聚合框架来得出一个直方图结
  • Hadoop 超立方体

    嘿 我正在启动一个基于 hadoop 的超立方体 具有灵活的维度数 有人知道这方面现有的方法吗 我刚刚发现PigOLAP草图 http wiki apache org pig PigOLAPSketch 但没有代码可以使用它 另一种方法是Z
  • 如何修复“任务尝试_201104251139_0295_r_000006_0 未能报告状态 600 秒”。

    我编写了一个 MapReduce 作业来从数据集中提取一些信息 该数据集是用户对电影的评分 用户数量约25万 电影数量约30万 地图的输出是
  • 通过Oozie命令行指定多个过滤条件

    我正在尝试通过命令行搜索一些特定的 oozie 作业 我使用以下语法进行相同的操作 oozie jobs filter status RUNNING status KILLED 但是 该命令仅返回正在运行的作业 而不是已杀死的作业 需要帮助
  • Hadoop fs 查找块大小?

    在 Hadoop fs 中如何查找特定文件的块大小 我主要对命令行感兴趣 例如 hadoop fs hdfs fs1 data 但看起来这并不存在 有Java解决方案吗 The fsck其他答案中的命令列出了块并允许您查看块的数量 但是 要
  • Mongodb MapReduce 选择最新日期

    我似乎无法让我的 MapReduce 缩减功能正常工作 这是我的地图功能 function Map day Date UTC this TimeStamp getFullYear this TimeStamp getMonth this T

随机推荐

  • 小程序跳转样式布局错乱_小程序webview无法自适应问题?跳转页面出现样式错乱问题。...

    小程序webview无法自适应问题 跳转页面出现样式错乱问题 The problem that the applet webview cannot be adapted The style of the jump page appears
  • map和set的概念及使用

    1 什么是关联式容器 关联式容器也是用来存储数据的 与序列式容器不同的是 其里面存储的是
  • 新天龙官网服务器更新消息,《新天龙八部》1月20日全服更新维护公告

    亲爱的玩家 大家好 为保证游戏运行的稳定性 提升整体服务质量 新天龙八部 游戏全部服务器 除测试服务器外 将于2020年1月20日7 00 9 00进行更新维护 维护后版本号升级为3 66 5201 如果在预定时间内无法完成维护内容 开机时
  • AcWing 420. 火星人

    人类终于登上了火星的土地并且见到了神秘的火星人 人类和火星人都无法理解对方的语言 但是我们的科学家发明了一种用数字交流的方法 这种交流方法是这样的 首先 火星人把一个非常大的数字告诉人类科学家 科学家破解这个数字的含义后 再把一个很小的数字
  • 多源迁移学习网络补充知识用于具有不可见故障的机器智能诊断

    摘要 当前基于深度迁移学习的故障诊断的大多数成功需要两个假设 1 源机器的健康状态集合应当与目标机器的健康状态集合重叠 2 目标机器样本的数量跨健康状态平衡 然而 这样的假设在工程场景中是不现实的 其中目标机器遭受在源机器中看不到的故障类型
  • 华硕主板已经开启VT-D虚拟化,但是进了win10还是CPU显示Hyper-V显示已禁用

    最近X宝看i5 8400的便宜好几百大洋 就入手一台当家里照片文档FTP服务器 系统win10装好 常用软件安装完成 准备来安装Hyper V了 在 程序和功能 里面的 Hyper V的虚拟机监控程序 是灰色的 老司机了 这难不倒我 一般都
  • CmakeList--gflags

    set GFLAGS LIBRARIES usr lib x86 64 linux gnu libgflags so
  • vue-cli3+electron出现白屏现象

    近期使用electron vue cli3 0开发了一个跨平台项目 进行登录后路由跳转出现白屏现象 原因在于路由使用了history模式 history模式在electron环境中会出现 路由跳转的白屏现象 因此 需要将histroy模式修
  • deepin自带wine使用方法_忘记Windows!国产深度v20正式版来袭,永久免费使用!

    最近win10系统更新出现各种bug 真是让人头痛 但是 就在我们在win10漩涡中晕头转向的时候 很多朋友都没有留意到 我们的国产操作系统 deepin 20正式版 在9月份已经正式发布 而直至10月份 距离deepin 20正式版发布一
  • Python实现邮箱自动发送代码(包含正文图片、附件文件)

    以下为源码 仅供大家学习 抄送实现是同一封邮件发送2次 如想实现发送人和抄送人显示中文名字 在list集合中添加中文名字即可 旭旭同学测试 lt 12341324 qq com gt 测试 lt 1341 qq com gt 不足之处请大家
  • Qt 多线程/多窗口 参数传递

    文章目录 注意 传递 Qt 支持的数据类型 主线程 gt 子线程 子线程 gt 主线程 主窗口 gt 子窗口 子窗口 gt 主窗口 传递自己定义的数据类型 第一步 定义数据类型 第二步 在 main 函数中注册该数据类型 第三步 开始传参数
  • 博客同时部署Github和Coding page

    前期 注册账号不讲了 现在都是以团队注册 注册完后 记得到团队设置里面 找到实名认证 在初次使用静态网站服务前 需要团队拥有者完成实名认证 然后需要在个人设置里绑定邮箱和设置密码 顺便把公钥添加下 创建一个项目 然后点进这个项目中 部署静态
  • phpstorm 配置apache路径

    初学php 如何自动将phpstorm中的文件部署到设定好的目录中 用了 我的路径是apache里面配置的路径ServerRoot
  • CentOS 7二进制文件安装nodejs

    根据自己的经验编写在linux系统CentOS下安装nodejs的过程 本篇介绍二进制文件直接解压安装的过程 方法 步骤 1 如图所示 在nodejs官网下载压缩包 根据自己的系统是32位还是64位选择压缩包 别选错类型哦 2 安装前要先安
  • sklearn——加载数据集

    1 通用数据集 API 根据所需数据集的类型 有三种主要类型的数据集API接口可用于获取数据集 方法一 loaders 可用来加载小的标准数据集 在玩具数据集中有介绍 方法二 fetchers 可用来下载并加载大的真实数据集 在真实世界中的
  • 无法生成“F:\system voiume information”下的常规文件夹列表拒绝访问

    1 产生问题 将桌面从属性 位置直接改到了F盘 F盘上的东西全显示在桌面上 2 解决问题 1 点击还原默认值后显示要下图 选择否 win10可以用 然后再次移动到你需要的位置即可 2 win7可以用 win10并没有用成 1 按win r
  • 图的创建和遍历

    图的定义 由顶点的有穷非空集合和顶点之间边的集合组成的数据类型 图的表示 G V E G表示一个图 V是图G的顶点集合 E为图G的边的集合 图的逻辑结构 多对多 图的存储结构 邻接矩阵 邻接表 十字链表 邻接多重表 图的一些无聊术语 顶点i
  • 多源bfs

    这是 LeetCode 上的 1162 地图分析 难度为 中等 与 单源最短路 不同 多源最短路 问题是求从 多个源点 到达 一个 多个汇点 的最短路径 在实现上 最核心的搜索部分 多源 BFS 与 单源 BFS 并无区别 并且通过建立 虚
  • 日常管理的五条小建议

    原文作者 Johanna Rothman著作 门后的秘密 卓越管理的故事 有时候 你需要为工作理一理头绪 你需要给自己一些喘息的机会 停下来 思考一会儿 这里有一些小建议 可以帮助你处理好日常管理工作 计划并安排一对一会谈 做管理意味着你要
  • 基于Hadoop的Knn算法实现

    Knn算法的核心思想是如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别 则该样本也属于这个类别 并具有这个类别上样本的特性 该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别 Knn方法在类