/***********************************************************************
This file is part of KEEL-software, the Data Mining tool for regression,
classification, clustering, pattern mining and so on.
Copyright (C) 2004-2010
F. Herrera (herrera@decsai.ugr.es)
L. Sánchez (luciano@uniovi.es)
J. Alcalá-Fdez (jalcala@decsai.ugr.es)
S. García (sglopez@ujaen.es)
A. Fernández (alberto.fernandez@ujaen.es)
J. Luengo (julianlm@decsai.ugr.es)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/
**********************************************************************/
//
// KNN.java
//
// Salvador Garc�a L�pez
//
// Created by Salvador Garc�a L�pez 11-7-2004.
// Copyright (c) 2004 __MyCompanyName__. All rights reserved.
//
package keel.Algorithms.ImbalancedClassification.Ensembles.Basic;
import keel.Dataset.Attribute;
import keel.Dataset.Attributes;
public class KNN {
public static int evaluacionKNN (int nvec, double conj[][], int clases[], double ejemplo[], int nClases) {
return evaluacionKNN2 (nvec,conj, clases, ejemplo, nClases);
}
public static int evaluacionKNN2 (int nvec, double conj[][], int clases[], double ejemplo[], int nClases) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], ejemplo);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
return votada;
}
/**
* To implement Depur Algorithm, we need the neighboor's vector, to decide what we must make
*
* @param nvec
* @param conj
* @param clases
* @param ejemplo
* @param nClases
* @return The neighboors' classes.
*
*/
public static int[] evaluacionKNN3 (int nvec, double conj[][], int clases[], double ejemplo[], int nClases) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
int clasesVecinosCercanos[];
double minDistancias[];
double dist;
if (nvec > conj.length)
nvec = conj.length;
vecinosCercanos = new int[nvec];
clasesVecinosCercanos= new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
clasesVecinosCercanos[i]=-1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], ejemplo);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<vecinosCercanos.length; j++) {
if(vecinosCercanos[j]!=-1)
clasesVecinosCercanos[j] =clases[vecinosCercanos[j]];
}
return clasesVecinosCercanos;
}
public static int evaluacionKNN2 (int nvec, double conj[][], int clases[], double ejemplo[], int nClases, Referencia nVotos) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], ejemplo);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
nVotos.entero = votaciones;
return votada;
}
public static int evaluacionKNN2 (int nvec, double conj[][], int clases[], double ejemplo[], int nClases, int vecinos[]) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], ejemplo);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
for (i=0; i<vecinosCercanos.length; i++)
vecinos[i] = vecinosCercanos[i];
return votada;
}
public static double distancia (double ej1[], double ej2[]) {
int i;
double suma = 0;
for (i=0; i<ej1.length; i++) {
suma += (ej1[i]-ej2[i])*(ej1[i]-ej2[i]);
}
suma = Math.sqrt(suma);
return suma;
}
public static double distancia2 (double ej1[], double ej2[]) {
int i;
double suma = 0;
for (i=0; i<ej1.length; i++) {
suma += (ej1[i]-ej2[i])*(ej1[i]-ej2[i]);
}
return suma;
}
/*****************************************************************************/
/*Adapted Methods for HVDM distance*/
public static int evaluacionKNN (int nvec, double conj[][], double real[][], int nominal[][], boolean nulos[][], int clases[], double ejemplo[], double ejReal[], int ejNominal[], boolean ejNulos[], int nClases, boolean distance) {
return evaluacionKNN2 (nvec, conj, real, nominal, nulos, clases, ejemplo, ejReal, ejNominal, ejNulos, nClases, distance);
}
public static int evaluacionKNN2 (int nvec, double conj[][], double real[][], int nominal[][], boolean nulos[][], int clases[], double ejemplo[], double ejReal[], int ejNominal[], boolean ejNulos[], int nClases, boolean distance) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], real[i], nominal[i], nulos[i], ejemplo, ejReal, ejNominal, ejNulos, distance);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
return votada;
}
public static int evaluacionKNN2 (int nvec, double conj[][], double real[][], int nominal[][], boolean nulos[][], int clases[], double ejemplo[], double ejReal[], int ejNominal[], boolean ejNulos[], int nClases, boolean distance, Referencia nVotos) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], real[i], nominal[i], nulos[i], ejemplo, ejReal, ejNominal, ejNulos, distance);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
nVotos.entero = votaciones;
return votada;
}
/**
* To implement Depur Algorithm, we need the neighboor's vector, to decide what we must make
*
* @param nvec
* @param conj
* @param clases
* @param ejemplo
* @param nClases
* @return The neighboors' classes.
* Isaac Triguero.
*/
public static int[] evaluacionKNN3 (int nvec, double conj[][], double real[][], int nominal[][], boolean nulos[][], int clases[], double ejemplo[], double ejReal[], int ejNominal[], boolean ejNulos[], int nClases, boolean distance) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
int clasesVecinosCercanos[];
double minDistancias[];
double dist;
if (nvec > conj.length)
nvec = conj.length;
vecinosCercanos = new int[nvec];
clasesVecinosCercanos= new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
clasesVecinosCercanos[i]=-1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], real[i], nominal[i], nulos[i], ejemplo, ejReal, ejNominal, ejNulos, distance);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<vecinosCercanos.length; j++) {
if(vecinosCercanos[j]!=-1)
clasesVecinosCercanos[j] =clases[vecinosCercanos[j]];
}
return clasesVecinosCercanos;
}
public static int evaluacionKNN2 (int nvec, double conj[][], double real[][], int nominal[][], boolean nulos[][], int clases[], double ejemplo[], double ejReal[], int ejNominal[], boolean ejNulos[], int nClases, boolean distance, int vecinos[]) {
int i, j, l;
boolean parar = false;
int vecinosCercanos[];
double minDistancias[];
int votos[];
double dist;
int votada, votaciones;
if (nvec > conj.length)
nvec = conj.length;
votos = new int[nClases];
vecinosCercanos = new int[nvec];
minDistancias = new double[nvec];
for (i=0; i<nvec; i++) {
vecinosCercanos[i] = -1;
minDistancias[i] = Double.POSITIVE_INFINITY;
}
for (i=0; i<conj.length; i++) {
dist = distancia(conj[i], real[i], nominal[i], nulos[i], ejemplo, ejReal, ejNominal, ejNulos, distance);
if (dist > 0) {
parar = false;
for (j = 0; j < nvec && !parar; j++) {
if (dist < minDistancias[j]) {
parar = true;
for (l = nvec - 1; l >= j+1; l--) {
minDistancias[l] = minDistancias[l - 1];
vecinosCercanos[l] = vecinosCercanos[l - 1];
}
minDistancias[j] = dist;
vecinosCercanos[j] = i;
}
}
}
}
for (j=0; j<nClases; j++) {
votos[j] = 0;
}
for (j=0; j<nvec; j++) {
if (vecinosCercanos[j] >= 0)
votos[clases[vecinosCercanos[j]]] ++;
}
votada = 0;
votaciones = votos[0];
for (j=1; j<nClases; j++) {
if (votaciones < votos[j]) {
votaciones = votos[j];
votada = j;
}
}
for (i=0; i<vecinosCercanos.length; i++)
vecinos[i] = vecinosCercanos[i];
return votada;
}
public static double distancia (double ej1[], double ej1Real[], int ej1Nom[], boolean ej1Nul[], double ej2[], double ej2Real[], int ej2Nom[], boolean ej2Nul[], boolean Euc) {
int i;
double suma = 0;
if (Euc == true) {
for (i=0; i<ej1.length; i++) {
suma += (ej1[i]-ej2[i])*(ej1[i]-ej2[i]);
}
suma = Math.sqrt(suma);
} else {
for (i=0; i<ej1.length; i++) {
if (ej1Nul[i] == true || ej2Nul[i] == true) {
suma += 1;
} else if (Attributes.getInputAttribute(i).getType() == Attribute.NOMINAL) {
suma += Metodo.nominalDistance[i][ej1Nom[i]][ej2Nom[i]];
} else {
if (Metodo.stdDev[i] != 0)
suma += Math.abs(ej1Real[i]-ej2Real[i]) / (4*Metodo.stdDev[i]);
}
}
suma = Math.sqrt(suma);
}
return suma;
}
public static double distancia2 (double ej1[], double ej1Real[], int ej1Nom[], boolean ej1Nul[], double ej2[], double ej2Real[], int ej2Nom[], boolean ej2Nul[], boolean Euc) {
int i;
double suma = 0;
if (Euc == true) {
for (i=0; i<ej1.length; i++) {
suma += (ej1[i]-ej2[i])*(ej1[i]-ej2[i]);
}
} else {
for (i=0; i<ej1.length; i++) {
if (ej1Nul[i] == true || ej2Nul[i] == true) {
suma += 1;
} else if (Attributes.getInputAttribute(i).getType() == Attribute.NOMINAL) {
suma += Metodo.nominalDistance[i][ej1Nom[i]][ej2Nom[i]];
} else {
if (Metodo.stdDev[i] != 0)
suma += Math.abs(ej1Real[i]-ej2Real[i]) / (4*Metodo.stdDev[i]);
}
}
}
return suma;
}
}