Commit 7c38e5b9 authored by lafabregue's avatar lafabregue

fix in mask ietration and samarah

parent a2c981db
......@@ -18,7 +18,7 @@ public class LightCluster extends Cluster {
private int cardinal = -1;
/** indexes used to read object in the cluster */
private int clusterIndex = 0;
private int clusterIndex = -1;
/** iterator used to read object in the cluster */
private IntMaskIterator indexIterator = null;
......@@ -122,22 +122,25 @@ public class LightCluster extends Cluster {
}
@Override
public DataObject getObject(int objIndex) {
public DataObject getObject(int objIndex) {
boolean fromSample = result.getClusterMap().length == result.data.getNbObjects();
if(objIndex > clusterIndex) {
while(clusterIndex != objIndex && getIndexIterator(false).hasNext()) {
while(clusterIndex != objIndex && getIndexIterator(fromSample).hasNext()) {
clusterIndex++;
getIndexIterator(false).next();
getIndexIterator(fromSample).next();
}
return result.getData().getWholeDataDataObject(getIndexIterator(false).current());
} else if (objIndex < clusterIndex){
while(clusterIndex != objIndex && clusterIndex > 0) {
clusterIndex--;
getIndexIterator(false).previous();
}
return result.getData().getWholeDataDataObject(getIndexIterator(false).current());
getIndexIterator(fromSample).previous();
}
}
if (fromSample) {
return result.getData().getDataObject(getIndexIterator(fromSample).current());
} else {
return result.getData().getWholeDataDataObject(getIndexIterator(fromSample).current());
}
return result.getData().getWholeDataDataObject(getIndexIterator(false).current());
}
......
......@@ -568,7 +568,7 @@ public class SimpleData extends Data {
return this.currentView.get(i);
}
@Override
@Override
public DataObject getDataObject(int[] coordonneDataObject) {
int aux = 1;
int index = coordonneDataObject[coordonneDataObject.length - 1];
......
......@@ -160,12 +160,13 @@ public class IntArrayMask implements Mask {
private final int[] mask;
private final int id;
private final boolean ignore;
private boolean first = true;
public IntMaskIterator(final int[] mask, final int id, final boolean ignore) {
this.id = id;
this.mask = mask;
this.ignore = ignore;
this.cursor = 0;
this.cursor = -1;
this.end = getLastIndex(0, mask.length-1);
}
......@@ -174,7 +175,7 @@ public class IntArrayMask implements Mask {
this.id = id;
this.mask = mask;
this.ignore = ignore;
this.cursor = start;
this.cursor = start-1;
this.end = getLastIndex(start, end);
}
......@@ -206,16 +207,16 @@ public class IntArrayMask implements Mask {
}
public boolean hasNext() {
return this.cursor <= end;
return this.cursor < end;
}
public Integer next() {
int next = -1;
cursor++;
if (ignore) {
while(cursor <= end) {
if(mask[cursor] != id) {
next = cursor;
cursor++;
break;
} else {
cursor++;
......@@ -225,7 +226,6 @@ public class IntArrayMask implements Mask {
while(cursor <= end) {
if(mask[cursor] == id) {
next = cursor;
cursor++;
break;
} else {
cursor++;
......@@ -255,6 +255,12 @@ public class IntArrayMask implements Mask {
}
/**
* Return the last index called by next() method
* Warning : if no next() have been called it returns -1
*
* @return the last index returned by next() method
*/
public Integer current() {
return new Integer(cursor);
}
......
......@@ -944,9 +944,9 @@ public class LearningResultKmeans extends LearningResult {
}
// create Weights section
model = JCLModelExchange.addSection(model,
JCLModelExchange.MODEL_WEIGHT_SECTION,
JCLModelExchange.weightsToString(this.weights.getGlobalWeights()));
// model = JCLModelExchange.addSection(model,
// JCLModelExchange.MODEL_WEIGHT_SECTION,
// JCLModelExchange.weightsToString(this.weights.getGlobalWeights()));
// create dataObject section
List<DataObject> dataObjects = new ArrayList<DataObject>();
......
package jcl.learning.methods.monostrategy.kmeans;
import java.awt.Color;
import java.io.StringReader;
import java.rmi.server.RMIFailureHandler;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;
import jcl.Classification;
import jcl.clustering.ClusteringResult;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.DistanceModel;
import jcl.data.attribute.Attribute;
import jcl.data.distance.Distance;
import jcl.data.distance.DistanceParameter;
import jcl.data.distance.EmptyDistanceParameter;
import jcl.data.distance.MetaDistance;
import jcl.data.distance.sequential.ParameterDTW;
import jcl.data.mask.DummyMask;
import jcl.data.mask.Mask;
import jcl.data.mask.MultiIDIntArrayMask;
import jcl.evaluation.clustering.ClusteringEvaluation;
import jcl.learning.LearningParameters;
import jcl.learning.LearningResult;
import jcl.utils.exceptions.JCLFormatException;
import jcl.utils.io.JCLModelExchange;
import jcl.weights.ClassificationWeights;
import jcl.weights.GlobalWeights;
import jcl.weights.LocalWeights;
import jcl.weights.Weights;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
*
* @author Cedric WEMMERT / Alexandre BLANSCHe
*/
public class LearningResultKmeans extends LearningResult {
/** */
private static final long serialVersionUID = 1L;
/** L'ensemble des centres des classes */
protected Vector<KmeansSeed> seeds = null;
protected boolean[] redefined;
static int incement = 0;
/**
* Represente la somme des distances au carre de chaque objet à son centre
*/
protected double distanceGlobale;
/** the clustermap from the learning part
* it is based on the sampling */
protected int[] learningClusterMap;
/**
* <p>
* Constructor
* </p>
*
* @param data Les donnees e classifier
* @param params Les parametres de l'algorithme
* @param samples Les exemples pour l'initialisation des centres
*/
public LearningResultKmeans(Data data, ParametersKmeans params, Vector samples) {
super(params, params.weights, data);
if (((ParametersKmeans) this.params).featureWeighting != ParametersKmeans.NO_FEATURE_WEIGHTING) {
double poidsTotal = params.weights.getGlobalWeights().getTotalWeights();
if (poidsTotal == 0) {
// System.out.println(" Tous les attributs ont un poids NUL ==> on les initialise a 1/nbre d'attributs");
for (int i = 0; i < data.getOneDataObject().getNbAttributes(); i++)
params.weights.getGlobalWeights().setWeight(i, data.getOneDataObject().getNbAttributes());
params.weights.getGlobalWeights().totalWeights = 1;
}
double weightsArray[] = new double[data.getOneDataObject().getNbAttributes()];
for (int i = 0; i < weightsArray.length; i++)
weightsArray[i] = Math.pow(1. / weightsArray.length, ((ParametersKmeans) this.params).beta);
// weightsArray[i] = params.weights.getGlobalWeights ().getWeight
// (i) / poidsTotal;
if (((ParametersKmeans) this.params).featureWeighting == ParametersKmeans.GLOBAL_FEATURE_WEIGHTING)
this.weights = new GlobalWeights(new Weights(weightsArray));
else {
Weights localWeights[] = new Weights[params.nbClusters];
for (int k = 0; k < params.nbClusters; k++)
localWeights[k] = new Weights(weightsArray);
this.weights = new LocalWeights(localWeights);
}
}
this.initSeeds(data, samples, params.nbClusters);
}
/**
* <p>
* Constructeur de copie.
* </p>
*
* @param learningResult L'objet e copier
*/
public LearningResultKmeans(LearningResultKmeans learningResult) {
super(learningResult.params, learningResult.params.weights, learningResult.data);
this.seeds = new Vector<KmeansSeed>();
for (int k = 0; k < learningResult.seeds.size(); k++)
this.seeds.add((KmeansSeed) (learningResult.seeds.get(k)).clone());
}
/**
* <p>
* Constructeur.
* </p>
*
* @param local_seeds Les centres des classes
* @param params Les parametres de l'algorithme
*/
public LearningResultKmeans(Vector<KmeansSeed> local_seeds, ParametersKmeans params) {
super(params, params.weights, local_seeds.get(0).getData());
this.seeds = local_seeds;
}
public LearningResultKmeans() {
super("dummy");
}
/**
* <p>
* Ajout d'un objet e l'une des classes avec un certain degre d'appartenance.
* </p>
*
* @param obj L'index de l'objet dans les donnees
* @param seed L'index de la classe
* @param membershipDegree Le degre d'appartenance de l'objet e la classe
*/
public void addObject(int obj, int seed, double membershipDegree) {
((FuzzySeed) this.seeds.get(seed)).addObject(obj, membershipDegree);
}
@Override
public ClusteringResult classify(Data data, boolean fromSample) {
// System.out.println("début classify: " + new SimpleDateFormat("HH:mm:ss.SSS").format(new Date()));
for (int i = 0 ; i < this.seeds.size() ; i++) {
if (this.seeds.get(i) instanceof LightHardSeed) {
((LightHardSeed) this.seeds.get(i)).setId(i);
}
}
// long startT = System.nanoTime();
// System.out.println("start at "+startT);
int clusterMap[] = this.clusterAffectation(data,fromSample);
// long endT = System.nanoTime();
// System.out.println("endat "+ endT + " total of "+ (endT - startT)/1000000000l);
ClusteringResult result = null;
if (((ParametersKmeans) this.params).fuzzy) {
double membershipDegree[][] = new double[this.seeds.size()][];
for (int i = 0; i < this.seeds.size(); i++)
membershipDegree[i] = ((FuzzySeed) this.seeds.get(i)).membership;
result = ClusteringResult.generateDefaultClusteringResult(this, clusterMap, membershipDegree, this.weights,
this.seeds.size(), null, data, this.qualityIndices, getColors());
} else {
result = ClusteringResult.generateDefaultClusteringResult(this, clusterMap, null, this.weights,
this.seeds.size(), null, data, this.qualityIndices, getColors());
}
<<<<<<< HEAD
// System.out.println("fin classify: " + new SimpleDateFormat("HH:mm:ss.SSS").format(new Date()));
=======
if (this.data == null) {
this.data = data;
for (KmeansSeed s : seeds) {
((LightHardSeed)s).setData(data);
}
}
>>>>>>> master
return result;
}
@Override
public void clean() {
for (int i = 0; i < this.seeds.size(); i++)
(this.seeds.get(i)).initialize();
}
@Override
public Object clone() {
return new LearningResultKmeans(this);
}
private int closestSeed(DataObject c) {
double distTemp;
double distMin = seeds.get(0).distance(c, params.getModel(), params.getDistanceParameters());
int closestSeed = 0;
for (int i = 1; i < seeds.size(); i++) {
distTemp = seeds.get(i).distance(c, params.getModel(), params.getDistanceParameters());
if (distTemp < distMin) {
distMin = distTemp;
closestSeed = i;
}
}
synchronized (this) {
distanceGlobale += distMin * distMin;
}
return closestSeed;
}
private int closestSeed(DataObject c, DistanceModel model, DistanceParameter[] param, DataObject[] seeds) {
MetaDistance metaDistance = model.getMetaDistance();
Distance<Attribute, DistanceParameter>[] distances = model.getDistances();
double distTemp;
double distMin = metaDistance.compute(seeds[0], c, distances, param);
int closestSeed = 0;
for (int i = 1; i < seeds.length; i++) {
distTemp = metaDistance.compute(seeds[i], c, distances, param);
if (distTemp < distMin) {
distMin = distTemp;
closestSeed = i;
}
}
distanceGlobale += distMin;
return closestSeed;
}
private int closestSeed(DataObject c, ClassificationWeights weights, Vector<KmeansSeed> seeds) {
double distTemp;
double distMin = seeds.get(0).distance(c, params.getModel(), params.getDistanceParameters());
int closestSeed = 0;
for (int i = 1; i < seeds.size(); i++) {
distTemp = seeds.get(i).distance(c, params.getModel(), params.getDistanceParameters());
if (distTemp < distMin) {
distMin = distTemp;
closestSeed = i;
}
}
distanceGlobale += distMin * distMin;
return closestSeed;
}
/**
* <p>
* Assign each object of a Data to a class
* </p>
*
* @param data
* Data to classify
* @param onSample
* if it is on the sample or the whole data
* @return the index of the assigned class for each object
*/
public int[] clusterAffectation(Data data, boolean onSample) {
this.resetProgress();
distanceGlobale = 0.0;
int nbObjects = 0;
if (onSample) {
nbObjects = data.getNbObjects();
this.clean();
} else {
nbObjects = data.getWholeDataNbObjects();
}
this.progressM=nbObjects;
int clusterMap[] = new int[nbObjects];
int nbThreads = ((ParametersKmeans) this.params).nbThreads;
if (((ParametersKmeans) this.params).fuzzy) {
// pour chaque objet...
int i =0;
Iterator<DataObject> iter = null;
if (onSample) {
iter = data.iterator();
} else {
iter = data.getWholeSourceDataObjects();
}
while(iter.hasNext()) {
DataObject obj = iter.next();
double distance[] = new double[((ParametersKmeans) this.params).nbClusters];
boolean zero[] = new boolean[((ParametersKmeans) this.params).nbClusters];
int count = 0;
double max = -1;
for (int j = 0; j < ((ParametersKmeans) this.params).nbClusters; j++) {
distance[j] = this.getDistance(obj, j);
zero[j] = (distance[j] == 0.0);
if (zero[j]) count++;
}
// System.out.println("end of first loop!");
if (count > 0) {
//System.out.println("entrée1!");
double membershipDegree = Math.pow(1. / count, ((ParametersKmeans) this.params).m);
for (int j = 0; j < ((ParametersKmeans) this.params).nbClusters; j++)
if (zero[j]) {
this.addObject(i, j, membershipDegree);
clusterMap[i] = j;
} else
this.addObject(i, j, 0);
} else
for (int j = 0; j < ((ParametersKmeans) this.params).nbClusters; j++) {
double sum = 0.0;
for (int k = 0; k < ((ParametersKmeans) this.params).nbClusters; k++)
sum += Math.pow(distance[j] / distance[k], ((ParametersKmeans) this.params).expM);
double membershipDegree = Math.pow(1. / sum, ((ParametersKmeans) this.params).m);
this.addObject(i, j, membershipDegree);
if (membershipDegree > max) {
max = membershipDegree;
clusterMap[i] = j;
}
}
i++;
}
} else {
/*
* for (int i = 0; i < data.getNbObjects(); i++) { DataObject obj =
* data.getDataObject(i); clusterMap[i] = this.closestSeed(obj);
*
* ((HardSeed) this.seeds.get(clusterMap[i])).addObject(obj); }
*/
LearningParameters params = this.params;
if (params == null) {
System.err.println("Parameters should not be null");
} else {
ThreadedAffectation[] tabThreads = new ThreadedAffectation[nbThreads];
int nbObjectsPerThread = (int) Math.ceil((double)nbObjects / nbThreads);
for (int th = 0; th < nbThreads - 1; th++) {
if (onSample) {
tabThreads[th] = new ThreadedAffectation(clusterMap,
data.iterator(th * nbObjectsPerThread, (th + 1) * nbObjectsPerThread ),
params.getModel(), params.getDistanceParameters()[th],
th * nbObjectsPerThread);
} else {
tabThreads[th] = new ThreadedAffectation(clusterMap,
data.getWholeSourceDataObjects(th * nbObjectsPerThread, (th + 1) * nbObjectsPerThread ),
params.getModel(), params.getDistanceParameters()[th],
th * nbObjectsPerThread);
}
tabThreads[th].start();
}
if (onSample) {
tabThreads[nbThreads - 1] = new ThreadedAffectation(clusterMap,
data.iterator((nbThreads - 1) * nbObjectsPerThread, nbObjects ),
params.getModel(), params.getDistanceParameters()[nbThreads - 1],
(nbThreads - 1) * nbObjectsPerThread);
} else {
tabThreads[nbThreads - 1] = new ThreadedAffectation(clusterMap,
data.getWholeSourceDataObjects((nbThreads - 1) * nbObjectsPerThread, nbObjects),
params.getModel(), params.getDistanceParameters()[nbThreads - 1],
(nbThreads - 1) * nbObjectsPerThread);
}
tabThreads[nbThreads - 1].start();
for (int th = 0; th < nbThreads; th++) {
try {
tabThreads[th].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int th = 0; th < nbThreads; th++) {
distanceGlobale += tabThreads[th].getThreadGlobalDistance();
}
}
distanceGlobale = Math.sqrt(distanceGlobale);
if (onSample) {
for(KmeansSeed s : this.seeds) {
((LightHardSeed) s).setClusterMap(clusterMap);
}
learningClusterMap = clusterMap;
}
}
//this.endProgress();
return clusterMap;
}
/**
* <p>
* Calcul de la distance entre un objet et un centre.
* </p>
*
* @param obj Un objet
* @param seed L'index d'un centre
* @return La distance entre l'objet et le centre
*/
public double getDistance(DataObject obj, int seed) {
return (this.seeds.get(seed)).distance(obj, params.getModel(), params.getDistanceParameters());
}
/**
* <p>
* Methode renvoyant le nombre de clusters.
* </p>
*
* @return le nombre de clusters demandes
*/
public int getNbClusters() {
return ((ParametersKmeans) this.params).nbClusters;
}
/**
* <p>
* Methode renvoyant un noyau.
* </p>
*
* @param k le numero du noyau e renvoyer
* @return le noyau numero k
*/
public KmeansSeed getSeed(int k) {
return this.seeds.get(k);
}
/**
* <p>
* Methode renvoyant l'ensemble des noyaux courants.
* </p>
*
* @return le vecteur des noyaux
*/
public Vector<KmeansSeed> getSeeds() {
return this.seeds;
}
/**
* Return the global distance from the data to the clusters
* @return the distance
*/
public double getDistanceGlobale() {
return distanceGlobale;
}
public int[] getLearningClustermap() {
if (learningClusterMap == null) {
learningClusterMap = clusterAffectation(data, true);
}
return learningClusterMap;
}
/**
* <p>
* Methode d'initialisation des noyaux
* </p>
*
* @param data les donnees e classer
* @param samples les exemples e utiliser pour l'initialisation
* @param nbClusters le nombre de noyaux e initialiser
*/
private void initSeeds(Data data, Vector samples, int nbClusters) {
DataObject[] seeds = new DataObject[nbClusters];
int nbClustersLeft = nbClusters;
int remaining = data.getNbObjects();
int index = 0;
if (samples == null || samples.contains(new Integer(-1))) {
for (int i = 0; i < data.getNbObjects(); i++) {
if (Math.random() < ((double) nbClustersLeft / (double) remaining)) {
seeds[index] = data.getDataObject(i);
index++;
nbClustersLeft--;
}
remaining--;
}
} else {// Dans le cas ou les centre initiaux sont donnes
// if centers are given by index
if (samples.size() > 0 && samples.get(0) instanceof Integer) {
for (int i = 0; i < seeds.length; i++) {
seeds[i] = data.getDataObject((Integer) samples.get(i));
}