/*----------------------------------------------------------*/ /* K-Nearest Neighbor Algorithm */ /*----------------------------------------------------------*/ /* (C) 2001 Zdravko Markov */ /*----------------------------------------------------------*/ /* knn: K-nearest neighbor */ /* knnw: Distance-weighted nearest neighbor */ /*----------------------------------------------------------*/ knn(Instance,K,Class) :- neighbors(Instance,K,Neighbors), sum(Neighbors,Sum), max(Sum,_-Class). knnw(Instance,K,Class) :- neighbors(Instance,K,Neighbors), sumw(Neighbors,Sum), max(Sum,_-Class). neighbors(Instance,K,Neighbors) :- findall(D-C,(example(_,C,E),dist(Instance,E,D)),Ds), keysort(Ds,L), first(K,L,Neighbors). dist([],[],0). dist([X|T],[X|V],N) :- !, dist(T,V,N). dist([_|T],[_|V],N) :- dist(T,V,M), N is M+1. first(0,_,[]). first(N,[X|T],[X|V]) :- M is N-1, first(M,T,V). sum([],[]). sum([_-C|T],[N-C|R]) :- delc(C,T,V,N), sum(V,R). delc(_,[],[],1). delc(X,[_-X|T],V,N) :- !, delc(X,T,V,M), N is M+1. delc(X,[Y|T],[Y|V],N) :- delc(X,T,V,N). sumw([],[]). sumw([D-C|T],[S-C|R]) :- delcw(C,T,V,S1), (D>0, S is S1+1/(D*D); S is S1+1), !, sumw(V,R). delcw(_,[],[],0). delcw(X,[D-X|T],V,S) :- !, delcw(X,T,V,S1), (D>0, S is S1+1/(D*D); S is S1+1). delcw(X,[Y|T],[Y|V],N) :- delcw(X,T,V,N). max([X],X) :- !. max([M-X|T],N-Y) :- max(T,K-Z), (M>K,N-Y=M-X; N-Y=K-Z), !.