Java實(shí)現(xiàn)的KNN算法示例
本文實(shí)例講述了Java實(shí)現(xiàn)的KNN算法。分享給大家供大家參考,具體如下:
提起KNN算法大家應(yīng)該都不會(huì)陌生,對(duì)于數(shù)據(jù)挖掘來(lái)說(shuō)算是十大經(jīng)典算法之一。
算法的思想是:對(duì)于訓(xùn)練數(shù)據(jù)集中已經(jīng)歸類的分組,來(lái)對(duì)于未知的數(shù)據(jù)進(jìn)行分組歸類。其中是根據(jù)該未知點(diǎn)與其訓(xùn)練數(shù)據(jù)中的點(diǎn)計(jì)算距離,求出距離最短的點(diǎn),并將其歸入該點(diǎn)的那一類。
看看算法的工程吧:
1. 準(zhǔn)備數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行預(yù)處理
2. 選用合適的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)訓(xùn)練數(shù)據(jù)和測(cè)試元組
3. 設(shè)定參數(shù),如k
4.維護(hù)一個(gè)大小為k的的按距離由大到小的優(yōu)先級(jí)隊(duì)列,用于存儲(chǔ)最近鄰訓(xùn)練元組。隨機(jī)從訓(xùn)練元組中選取k個(gè)元組作為初始的最近鄰元組,分別計(jì)算測(cè)試元組到這k個(gè)元組的距離,將訓(xùn)練元組標(biāo)號(hào)和距離存入優(yōu)先級(jí)隊(duì)列
5. 遍歷訓(xùn)練元組集,計(jì)算當(dāng)前訓(xùn)練元組與測(cè)試元組的距離,將所得距離L 與優(yōu)先級(jí)隊(duì)列中的最大距離Lmax
6. 進(jìn)行比較。若L>=Lmax,則舍棄該元組,遍歷下一個(gè)元組。若L < Lmax,刪除優(yōu)先級(jí)隊(duì)列中最大距離的元組,將當(dāng)前訓(xùn)練元組存入優(yōu)先級(jí)隊(duì) 列。
7. 遍歷完畢,計(jì)算優(yōu)先級(jí)隊(duì)列中k 個(gè)元組的多數(shù)類,并將其作為測(cè)試元組的類別。
8. 測(cè)試元組集測(cè)試完畢后計(jì)算誤差率,繼續(xù)設(shè)定不同的k值重新進(jìn)行訓(xùn)練,最后取誤差率最小的k 值。
根據(jù)算法的過(guò)程我們進(jìn)行java語(yǔ)言實(shí)現(xiàn):
package KNN;
/**
* 點(diǎn)的坐標(biāo) x 、y
* @author Administrator
*
*/
public class PointBean {
int x;
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public PointBean(int x, int y) {
super();
this.x = x;
this.y = y;
}
public PointBean() {
super();
}
@Override
public String toString() {
return "PointBean [x=" + x + ", y=" + y + "]";
}
}
KNN算法
package KNN;
import java.util.ArrayList;
/**
* KNN實(shí)現(xiàn)的方法
* @author Administrator
*
*/
public class KnnMain {
public double getPointLength(ArrayList<PointBean> list,PointBean bb){
int b_x=bb.getX();
int b_y=bb.getY();
double temp=(b_x -list.get(0).getX())*(b_x -list.get(0).getX())+
(b_y -list.get(0).getY())*(b_y -list.get(0).getY());
// 找出最小的距離
for(int i=1;i<list.size();i++){
if(temp<((b_x -list.get(i).getX())*(b_x -list.get(i).getX())+
(b_y -list.get(i).getY())*(b_y -list.get(i).getY()))){
temp=(b_x -list.get(i).getX())*(b_x -list.get(i).getX())+
(b_y -list.get(i).getY())*(b_y -list.get(i).getY());
}
}
return Math.sqrt(temp);
}
/**
* 獲取長(zhǎng)度,找出最小的一個(gè)進(jìn)行歸類
* @param list1
* @param list2
* @param list3
* @param bb
*/
public void getContent(ArrayList<PointBean> list1,ArrayList<PointBean> list2,
ArrayList<PointBean> list3,PointBean bb){
double A=getPointLength(list1,bb);
double B=getPointLength(list2,bb);
double C=getPointLength(list3,bb);
//做出比較
if(A>B){
if(B>C){
System.out.println("這個(gè)點(diǎn):"+bb.getX()+" , "+bb.getY()+" " +"屬于C");
}else {
System.out.println("這個(gè)點(diǎn):"+bb.getX()+" , "+bb.getY()+" " +"屬于B");
}
}else {
if(A>C){
System.out.println("這個(gè)點(diǎn):"+bb.getX()+" , "+bb.getY()+" " +"屬于C");
}else {
System.out.println("這個(gè)點(diǎn):"+bb.getX()+" , "+bb.getY()+" " +"屬于A");
}
}
}
}
主函數(shù)
package KNN;
import java.util.ArrayList;
/*
* 主函數(shù) KNN
*/
public class TestJava {
static ArrayList< PointBean> listA;
static ArrayList< PointBean> listB;
static ArrayList< PointBean> listC;
static ArrayList< PointBean> listD;
public static void main(String[] args) {
//創(chuàng)佳Arraylist
listA=new ArrayList<PointBean>();
listB=new ArrayList<PointBean>();
listC=new ArrayList<PointBean>();
listD=new ArrayList<PointBean>();
//寫入數(shù)據(jù)
setDate();
getTestResult();
}
/**
* 得到結(jié)果
*/
private static void getTestResult() {
//創(chuàng)建對(duì)象
KnnMain km=new KnnMain();
for(int i=0;i<listD.size();i++){
km.getContent(listA, listB, listC, listD.get(i));
}
}
/**
* 寫入數(shù)據(jù)
*/
private static void setDate() {
//A的坐標(biāo)點(diǎn)
int A_x[]={1,1,2,2,1};
int A_y[]={0,1,1,0,2};
//B的坐標(biāo)點(diǎn)
int B_x[]={2,3,3,3,4};
int B_y[]={4,4,3,2,3};
//C的坐標(biāo)點(diǎn)
int C_x[]={4,5,5,6,6};
int C_y[]={1,2,0,2,1};
// 測(cè)試數(shù)據(jù)
//B的坐標(biāo)點(diǎn)
int D_x[]={3,3,3,0,5};
int D_y[]={0,1,5,0,1};
//
PointBean bA;
for(int i=0;i<5;i++){
bA=new PointBean(A_x[i], A_y[i]);
listA.add(bA);
}
//
PointBean bB ;
for(int i=0;i<5;i++){
bB=new PointBean(B_x[i], B_y[i]);
listB.add(bB);
}
//
PointBean bC ;
for(int i=0;i<5;i++){
bC=new PointBean(C_x[i], C_y[i]);
listC.add(bC);
}
//
PointBean bD ;
for(int i=0;i<5;i++){
bD=new PointBean(D_x[i], D_y[i]);
listD.add(bD);
}
}
}
測(cè)試的結(jié)果:
這個(gè)點(diǎn):3 , 1 屬于A
這個(gè)點(diǎn):3 , 5 屬于B
這個(gè)點(diǎn):0 , 0 屬于A
這個(gè)點(diǎn):5 , 1 屬于C
到此簡(jiǎn)單的KNN算法已經(jīng)實(shí)現(xiàn)對(duì)于未知點(diǎn)的劃分,有助于大家對(duì)于KNN算法的理解。對(duì)于改進(jìn)KNN的一些算法JAVA實(shí)現(xiàn)會(huì)在后面進(jìn)行貼出。共同學(xué)習(xí)共同進(jìn)步!
更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
- Python實(shí)現(xiàn)的knn算法示例
- python使用KNN算法手寫體識(shí)別
- 以Python代碼實(shí)例展示kNN算法的實(shí)際運(yùn)用
- kNN算法python實(shí)現(xiàn)和簡(jiǎn)單數(shù)字識(shí)別的方法
- Java實(shí)現(xiàn)的樸素貝葉斯算法示例
- Java實(shí)現(xiàn)的傅里葉變化算法示例
- Java實(shí)現(xiàn)五子棋AI算法
- 使用棧的迷宮算法java版代碼
- Java實(shí)現(xiàn)走迷宮回溯算法
- Java實(shí)現(xiàn)Floyd算法求最短路徑
- JAVA實(shí)現(xiàn)感知器算法
相關(guān)文章
Spring+MongoDB實(shí)現(xiàn)登錄注冊(cè)功能
這篇文章主要為大家詳細(xì)介紹了Spring+MongoDB實(shí)現(xiàn)登錄注冊(cè)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
MyBatis-Plus之邏輯刪除的實(shí)現(xiàn)
這篇文章主要介紹了MyBatis-Plus之邏輯刪除的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Mybatis的特點(diǎn)及優(yōu)點(diǎn)
Mybatis 本是apache的一個(gè)開(kāi)源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache software foundation 遷移到了google code,并且改名為MyBatis。mybatis有哪些特點(diǎn)和優(yōu)點(diǎn)呢?通過(guò)本文一起學(xué)習(xí)吧2016-12-12
Java為什么基本數(shù)據(jù)類型不需要進(jìn)行創(chuàng)建對(duì)象?
今天小編就為大家分享一篇關(guān)于Java為什么基本數(shù)據(jù)類型不需要進(jìn)行創(chuàng)建對(duì)象?,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04
JAVA對(duì)字符串進(jìn)行32位MD5加密的實(shí)踐
本文主要介紹了JAVA對(duì)字符串進(jìn)行32位MD5加密的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
Java優(yōu)化for循環(huán)嵌套的高效率方法
這篇文章主要介紹了Java優(yōu)化for循環(huán)嵌套的高效率方法,幫助大家更好的提升java程序性能,感興趣的朋友可以了解下2020-09-09
如何解決@PutMapping或@PostMapping接收String類型參數(shù)多兩個(gè)“引號(hào)問(wèn)題
這篇文章主要介紹了如何解決@PutMapping或@PostMapping接收String類型參數(shù)多兩個(gè)“引號(hào)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java中的線程池ThreadPoolExecutor細(xì)致講解
這篇文章主要介紹了Java中的線程池ThreadPoolExecutor細(xì)致講解,線程池是一種基于池化思想管理線程的工具,經(jīng)常出現(xiàn)在多線程服務(wù)器中,如MySQL,線程過(guò)多會(huì)帶來(lái)額外的開(kāi)銷,其中包括創(chuàng)建銷毀線程的開(kāi)銷、調(diào)度線程的開(kāi)銷等等,需要的朋友可以參考下2023-11-11

