KNN并行化
一、实验目的
使用hadoop集群完成基本的词频统计实验的拓展,理解map reduce的运行机制,并掌握自定义执行过程中的函数的方法。
二、实验环境
虚拟机系统:
Ubuntu 20
运行环境:
完全分布式hadoop集群
软件:
Hadoop 2.7.1
Jdk1.8
Eclipse
硬件配置:
Master节点:2GB内存,1核心,20GB硬盘
Slave1 节点:1GB内存,1核心,20GB硬盘
Slave2 节点:1GB内存,1核心,20GB硬盘
三、问题描述
KNN算法描述
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。
传统KNN算法性能的瓶颈
- 如果训练样本数据有n个,则KNN算法需要计算n次相似度,时间复杂度为O(n)
- 单机内存有限
- 单机计算资源也有限
指导思想:分而治之
如果能够将测试样本和每一训练样本的相似度的计算工作分摊到不同的机器上并行地计算,则能够减少计算时间。
面对问题:
测试集数量相对较少,而训练集数据较大,无法在单一节点进行存储运算
基本思路:
1、数据文件:将测试集以全局文件的方式发送到各个节点上,而训练集依靠hadoop自带的分片机制发送到不同的map节点上。
2、mapper阶段,计算分片后的训练集和测试集每个点的距离,并将其以发出。
3、sort过程将相同id按距离升序排列。
4、combiner限制同一个测试数据只发出与其最近的k个节点。
5、reduce读取同一个测试数据对应的前k项并进行投票。
四、实验步骤
1、map过程
计算当前节点上训练集与测试集各节点之间的距离
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, paris, Text>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
String train_data=value.toString();
String[] rc1=train_data.split(",");//文件是csv格式的,使用','分割开
String type=rc1[rc1.length-1];
for(String i : testData){
String[] rc2=i.split(",");
double[] rrc2 = new double[100];
double[] rrc1 = new double[100];
//double rrc1[] = null;
for(int j=0;j<(rc1.length-1);j++){
if (rc1[j] != null){
rrc1[j] = Double.parseDouble(rc1[j]);
}
}
for(int j=0;j<rc2.length;j++){
rrc2[j] = Double.parseDouble(rc2[j]);
}
int c;
c = rc2.length;
Double dis=Distance.Distance1(rrc1, rrc2,c);//计算距离
context.write(new paris(t_id,dis), ne