KNN算法手写数字识别java实现

数据集:

资源链接 https://download.csdn.net/download/qq_39464369/11094319

数据格式

将手写数字像素点表示为32*32的0,1文本文件
在这里插入图片描述

例如 数字 0:
在这里插入图片描述

算法

将用到前面已经写好的knn算法,无需修改直接使用:
https://blog.csdn.net/qq_39464369/article/details/88953522

测试代码

package knn;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Hand {

	public static void main(String[] args) throws IOException {
		Hand hand=new Hand();
		ArrayList<VisibleData> training = hand.getDataList("E:\\机器学习实战\\机器学习实战代码\\MLiA_SourceCode\\Ch02\\trainingDigits");
		ArrayList<VisibleData> test = hand.getDataList("E:\\机器学习实战\\机器学习实战代码\\MLiA_SourceCode\\Ch02\\testDigits");
		KNN knn=new KNN();
		knn.setTraining(training);
		knn.setDistance((a,b)->{
			List<Double> dis=new ArrayList<Double>();
			for(int i=0;i<a.getData().size();i++) {
				dis.add(a.getData().get(i).doubleValue()-
						b.getData().get(i).doubleValue());
			}
			return Math.sqrt(dis.stream().map(m->m*m).reduce(0.0,(x,y)->x+y).doubleValue());
		});
		//预测分类
		for(VisibleData item:test) {
			System.out.print("真实值 :\t"+item.getLabel());
			System.out.println("\t预测值 :\t"+knn.test(item,3));
		}
	}
	//读取目录 并将数据包装
    public   ArrayList<VisibleData> getDataList(String path) throws IOException {
        File file = new File(path);
        File[] fileList = file.listFiles();
        ArrayList<VisibleData> dataList=new ArrayList<VisibleData>();
        for (int i = 0; i < fileList.length; i++) {
        	 InputStreamReader reader=new InputStreamReader(new FileInputStream(fileList[i]),"GBK");
             BufferedReader bfreader=new BufferedReader(reader);
             String line;
             String txt="";
             while((line=bfreader.readLine())!=null) {//包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
            	 txt+=line;
             }
             dataList.add(new FileData(stringToList(txt),fileList[i].getName().substring(0,1)));
             reader.close();
             bfreader.close();
        }
		return dataList;
    }
    //将字符串转为列表
    public static ArrayList<Number> stringToList(String string) {
    	ArrayList<Number> list=new ArrayList<Number>(); 
    	for(int i=0;i<string.length();i++) {
    		int tmp=string.charAt(i)-48;
    		list.add(tmp);
    	}
		return list;
    }
    
}
//数据类 包含数据和标签
class FileData implements VisibleData{
	private ArrayList<Number> list;
	private String label;
	public FileData(ArrayList<Number> list,String label) {
		this.list=list;
		this.label=label;
	}
	public List<Number> getData() {
		return list;
	}
	public String getLabel() {
		return label;
	}
}

输出

在这里插入图片描述
结果比较符合预期,knn算法对于这类的处理算得上是得心应手的。
但由于对流有较多的使用以及对基本数据的包装大大降低了处理速率,所以任需要大力改进。

猜你喜欢

转载自blog.csdn.net/qq_39464369/article/details/89066479