KNN算法手写数字识别java实现
数据集:
资源链接 https://download.****.net/download/qq_39464369/11094319
数据格式
将手写数字像素点表示为32*32的0,1文本文件
例如 数字 0:
算法
将用到前面已经写好的knn算法,无需修改直接使用:
https://blog.****.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算法对于这类的处理算得上是得心应手的。
但由于对流有较多的使用以及对基本数据的包装大大降低了处理速率,所以任需要大力改进。