knn算法---java简单实现

knn算法又叫k邻近算法

在一个坐标系中标记已经有标签的几个点,然后定下一个未知的点,通过选取最近的k个点。查看这k个点的标签。然后给新未知点定义标签。

机器学习实战中提到通过接吻次数与打架次数立坐标系,然后通过距离判断该片属于爱情片还是动作片。

但是上面用的是Python的代码,我这里用java的代码写一次。

package Study.Number.Util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Test;

public class KnnUtil {
    @Test
    public void test(){
        float[][] in={{7,1},{8,2},{1,6},{1,9},{9,4},{7,3},{2,2}};
        float[] b={3,1};
        System.out.println(    basePnn(in,3,b));
    }
    
    public List<Map> basePnn(float[][] input,int k,float[] base){
        /*float[][] output=new float[k][];*/
        List<Map> list=new ArrayList();
        Map map=new HashMap();
        float maxX=0;
        float maxY=0;
        float x;
        float y;
        int xlen;
        int ylen;
        for(int i=0;i<input.length;i++){
            if(maxX<input[i][0]){
                maxX=input[i][0];
            }
        }
        for(int i=0;i<input.length;i++){
            if(maxY<input[i][1]){
                maxY=input[i][1];
            }
        }
        int bx=(int) ((base[0]/maxX)*100);
        int by=(int) ((base[1]/maxX)*100);
        for(int i=0;i<input.length;i++){
            Map maps=new HashMap();
            x=input[i][0];
            y=input[i][1];
            xlen=(int) ((x/maxX)*100);
            ylen=(int) ((y/maxX)*100);
            xlen=xlen-bx;
            ylen=ylen-by;
            maps.put("index", i);
            maps.put("len", Math.sqrt(xlen*xlen+ylen*ylen));
            list.add(maps);
        }
        List link=new LinkedList();
        double now;
        double old;
        for(int i=0;i<list.size();i++){
            for(int j=0;j<(list.size()-i);j++){
                if(j>0){
                    now=(Double) list.get(j).get("len");
                    old=(Double) list.get(j-1).get("len");
                    if(now<old){
                        Map m=list.get(j-1);
                        list.set(j-1, list.get(j));
                        list.set(j, m);
                    }
                }
            }
            
        }
        return list.subList(0, k);
    }
    

}

这个方法有时候可以很好的区分爱情片跟动作片。

但是也有一些疑惑,比如接吻的次数明显会远远少于打架的次数,两者距离的控制衡量不太好掌握,,容易动作片接吻两次就判断成了爱情片的情况。

再则是相亲问题。女子把帅,跟多金作为坐标系,很难区分帅又多金的人与丑又穷的人。

第一个算法。玩玩,仅此而已

posted @ 2017-07-27 16:48  酒皇  阅读(1956)  评论(0编辑  收藏  举报