链接:https://zhuanlan.zhihu.com/p/40431290
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(1)KNN分类算法
KNN是通过测量不同特征值之间的距离进行分类。如果取样本的特征空间里K个相似对象向里占最多的类别,并把样本归入此类。
理解:通过计算样本与待计算对象之间的差距 dn(距离) 让样本以对象为中心开始排队,取以个最大半径K,在这个范围里,那一类的类占的比重大,就把待测对象标记为该类。
*有一点像soul交友软件,通过你的信息,在数据库里计算和你相似距离最小的用户,并且还会给你表明你们的相似度,然后把你也归入这一类星球里*
(2)KNN使用
将数据转化为可计算数据,并且储存到相应文件里。
(0)录入样本
(1) 录入带识别对象
(2) 计算样本数据和识别对象的距离;
(3)按照距离大小把对象存储到队列里
(4)取得K值计算K值内类别所占的最多类为最相似类别;
(5)将待识别样本标记为最相似类别
二--思路二
1.首先录取样本的数据,得到0-9这10个数字对应的数据类,着10个数字对应着你输入的数据,输入的数据越多越好
*1这里我用一个数组存“0-9”着是10个数字,想让数组对应的值为样本的个数,最开始都初始化为0,当你准备录入“0”的时候,就在文件夹里建立0的第1个样本,并且a[0]++;这样号访问到底有多少个“0”数据,也好到后期算距离;
2.读取样本数据----a[10]++;"待测量数据增多"
3. 用样本数据分别和 "0-9”着10个类里面存的样本算距离,取得平均距,并且当作样本与“0”到“9”着9个数字之间的差距,取最小距离mind ,以及对应最相似数字
4.将待测对象的类别修改为最相似类
我会调用一个方法,直接把待测对像的数据放到,相似数字的会便利的下一个数据,并且a[相似数字]++
public class MyUI extends JFrame {
public Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
private int width = 400;
private int height = 550;
MyCanvas canvas = null;
private Graphics g;
public JTextField number=null;
public static void main(String[] args) throws AWTException {
MyUI myui=new MyUI();
}
public MyUI()
{
super();
this.setTitle("handwirting");
this.setSize(width, height);
this.setResizable(false);
this.setLocation(400, 180);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.canvas = new MyCanvas(this);
this.add(canvas);
JPanel jp=new JPanel();
jp.setBackground(Color.BLACK);
jp.setSize(new Dimension(400,40 ));
this.add(BorderLayout.EAST,jp);
jp.setLayout(new FlowLayout());
JButton b1=new JButton("练习");
b1.addActionListener(canvas);
JButton b2=new JButton("识别");
b2.addActionListener(canvas);
jp.add(b1);
jp.add(b2);
number=new JTextField(1);
jp.add(number);
this.setVisible(true);
canvas.setG();
}
}
首先会有这么一个界面,在输入框里写入要学习的数字(存储相应对象的数据1),这时候我会将这个黑色区域存下来,并且获取它的每一个点rgb因为是黑白的,所以就将白色设为1,黑色设为0,这几样就可以得到一串子,把他存到名字为“0-1”文件里代表“0”数字的第一组数据。
我会配合着输出存储情况
第一行代表计算机要学习“存储”的类别
第二行是当前对10个数组存储数据的情况,目前只学习了1所以[1]的长度就是1啦;
这里[10]用来代表待识别的对象。
这时候点击识别按钮,进行识别
这里就是输出
我这个版本就是有bug的
进行改进
(1)需要如果计算出来的差距特别大的时候,就直接选择废除这个数据,并且输出不能识别
(2)每一次启动程序都需要重新输入学习样本的数据,应该调用一个方法来实践设置数组的长度,在计算knn时候直接读取以前存取的数据。。。。。
//图片存储
public void wirte2jpg(int key) throws IOException {
// TODO Auto-generated method stub
Dimension imagesize = this.getSize();
// 创建一个图形
BufferedImage image = new BufferedImage(imagesize.width, imagesize.height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.createGraphics();
this.paint(graphics);
// 创建图片
File f = new File("D:手写图片\" + key + "-" + (keylength[key]) + ".jpg");
try {
if (!f.exists()) {
f.createNewFile();
System.out.println(123);
}
// 存储一张手写图片
ImageIO.write(image, "jpg", f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
savepage(image, key);
this.setBackground(Color.BLACK);
}
//存储数据
public void savepage(BufferedImage image, int key) throws IOException {
int k = 0;
// 存起来图像
for (int i = image.getMinY(); i < image.getMinY() + height; i++) {
for (int j = image.getMinX(); j < image.getMinX() + width; j++) {
// 数组颜色
int mycolor = image.getRGB(j, i);
if (mycolor == -1) {
Mydata[k] = 1;
k++;
} else {
Mydata[k] = 0;
k++;
}
}
}
// 创建文本本舰存数组
File f = new File("D:数字\" + key + "-" + (keylength[key]) + ".txt");
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 存入数据
for (int q = 0; q < SIZE; q++) {
try {
out.write((byte) Mydata[q]);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
总结一下-这个项目我耗费最久的在IO流,以及数据存储上面,以及方法之间的调用布局,
方法与方法之间的调用关系,存储数据的读取上面。下一篇总结IO流以及异常。