Commit d6fa1b3c authored by balanche's avatar balanche

Merge with current master branch

parents 07198dc3 274045dd
No preview for this file type
......@@ -22,7 +22,7 @@ import jcl.learning.LearningMethod;
import jcl.learning.methods.ClassifierUtils;
import jcl.utils.Progressable;
import jcl.utils.exceptions.JCLFormatException;
import jcl.utils.exceptions.MethodNotImplementedException;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
* <p>
......
......@@ -5,9 +5,10 @@ import java.io.Serializable;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.DistanceModel;
import jcl.data.distance.DistanceModel;
import jcl.data.distance.DistanceParameter;
import jcl.weights.Weights;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
* <p>
......@@ -21,7 +22,7 @@ abstract public class Cluster implements Serializable {
private static final long serialVersionUID = 1L;
/** Le resultat de la classification qui contient ce cluster */
protected final ClusteringResult result;
protected ClusteringResult result;
/** The cluster's gravity center */
protected DataObject clusterCenter = null;
......@@ -30,7 +31,10 @@ abstract public class Cluster implements Serializable {
protected Color color = new Color(0);
/** The cluster's father node color*/
protected Color couleur_pere = new Color(0);
protected Color couleur_pere = null;
/** L'index qui correspond a la place du cluster dans result */
protected int id = -1;
/**
* Indicate if the cluster is freezed or not. If it is, we
......@@ -73,6 +77,7 @@ abstract public class Cluster implements Serializable {
this.clusterCenter = new DataObject(cluster.clusterCenter);
}
this.weights = new Weights(cluster.weights);
this.id = cluster.id;
}
/** Renvoi le centroide du cluster et le calcul si il est vide */
......@@ -115,6 +120,16 @@ abstract public class Cluster implements Serializable {
public DataObject getClusterCenter() {
return this.clusterCenter;
}
/**
* <p>
* Return the id of the cluster in the ClusteringResult
* <p>
*
* @return the cluster id
*/
public int getId() {
return id;
}
/**
* <p>
......@@ -170,17 +185,21 @@ abstract public class Cluster implements Serializable {
*
* @param o
* l'index de l'objet
* @return le degre d'appartenance du o-ieme objet e la classe
* @return le degre d'appartenance du o-ieme objet e la classe *
* @throws MethodNotImplementedException
* si la methode n'implante pas cet operateur
*/
abstract public double getMembership(final int o);
abstract public double getMembership(final int o) throws MethodNotImplementedException;
/**
* <p>
* Probabilite de la classe.
* </p>
*
* @return la probabilite de la classe
* @return la probabilite de la classe *
* @throws MethodNotImplementedException
* si la methode n'implante pas cet operateur
*/
abstract public double getMembershipProbabilityEM();
abstract public double getMembershipProbabilityEM() throws MethodNotImplementedException;
/**
* <p>
......@@ -215,6 +234,17 @@ abstract public class Cluster implements Serializable {
return result;
}
/**
* <p>
* Set the clustering result to which the cluster should be attached
* <p>
*
* @param result the clustering result
*/
public void setResult(ClusteringResult result) {
this.result = result;
}
/**
* <p>
* Test si la classe est lockee.
......
......@@ -11,7 +11,7 @@ import javax.swing.tree.DefaultMutableTreeNode;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.DistanceModel;
import jcl.data.distance.DistanceModel;
import jcl.data.distance.DistanceParameter;
import jcl.evaluation.clustering.ClusteringQuality;
import jcl.learning.LearningResult;
......@@ -23,9 +23,9 @@ import jcl.learning.methods.monostrategy.evidence.AgglomerateEvidence;
import jcl.learning.methods.monostrategy.evidence.LearningResultEvidence;
import jcl.learning.methods.monostrategy.kmeans.LearningResultKmeans;
import jcl.utils.Matrix;
import jcl.utils.MemoryFlush;
import jcl.weights.ClassificationWeights;
import jcl.weights.Weights;
import multiCube.tools.util.MemoryFlush;
/**
* <p>
......
......@@ -7,14 +7,12 @@ import jcl.data.mask.IntArrayMask.IntMaskIterator;
import jcl.data.mask.Mask;
import jcl.weights.Weights;
import jj2000.j2k.NotImplementedError;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
public class LightCluster extends Cluster {
/** */
private static final long serialVersionUID = 1L;
/** L'index qui correspond a la place du cluster dans result */
private int id = -1;
/** the cluster cardinality */
private int cardinal = -1;
......@@ -144,13 +142,13 @@ public class LightCluster extends Cluster {
@Override
public double getMembership(int o) {
throw new NotImplementedError("method not Implemented for LighCluster class");
public double getMembership(int o) throws MethodNotImplementedException{
throw new MethodNotImplementedException("method not Implemented for LighCluster class");
}
@Override
public double getMembershipProbabilityEM() {
throw new NotImplementedError("method not Implemented for LighCluster class");
public double getMembershipProbabilityEM() throws MethodNotImplementedException{
throw new MethodNotImplementedException("method not Implemented for LighCluster class");
}
@Override
......@@ -172,17 +170,6 @@ public class LightCluster extends Cluster {
return indexIterator;
}
/**
* <p>
* Return the id of the cluster in the ClusteringResult
* <p>
*
* @return the cluster id
*/
public int getId() {
return id;
}
/**
* <p>
* Set the id of the cluster in the ClusteringResult
......
......@@ -6,6 +6,7 @@ import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.SimpleData;
import jcl.weights.Weights;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
* <p>
......@@ -41,7 +42,11 @@ public class SimpleCluster extends Cluster {
this.data = (Data) cluster.data.clone();
this.membershipDegree = new double[cluster.membershipDegree.length];
for (int i = 0; i < this.membershipDegree.length; i++) {
this.membershipDegree[i] = cluster.getMembership(i);
try {
this.membershipDegree[i] = cluster.getMembership(i);
} catch (MethodNotImplementedException e) {
e.printStackTrace();
}
}
this.membershipProbabilityEM = cluster.membershipProbabilityEM;
}
......@@ -124,6 +129,7 @@ public class SimpleCluster extends Cluster {
this.membershipProbabilityEM = proba;
this.locked = false;
this.name = "Cluster " + (k + 1);
this.id = k;
}
/**
......@@ -142,6 +148,7 @@ public class SimpleCluster extends Cluster {
this.name = name;
}
@Override
public Object clone() {
return new SimpleCluster(this);
......@@ -210,7 +217,7 @@ public class SimpleCluster extends Cluster {
* l'index de l'objet
* @return le degre d'appartenance du o-ieme objet e la classe
*/
public double getMembership(final int o) {
public double getMembership(final int o) throws MethodNotImplementedException {
double degree = 0;
if ((o >= 0) && (o < this.membershipDegree.length)) {
degree = this.membershipDegree[o];
......@@ -225,7 +232,7 @@ public class SimpleCluster extends Cluster {
*
* @return la probabilite de la classe
*/
public double getMembershipProbabilityEM() {
public double getMembershipProbabilityEM() throws MethodNotImplementedException {
return this.membershipProbabilityEM;
}
......
package jcl.clustering;
import java.util.Iterator;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.SimpleData;
import jcl.weights.Weights;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
* <p>
* Implementation simple de Cluster qui reprend les developpements avant abstraction
* </p>
*
* @author Baptiste Lafabregue
*/
public class SimpleCluster extends Cluster {
/** */
private static final long serialVersionUID = 1L;
/** Les donnees appartenant aéé& ce cluster */
private Data data = null;
/** Le degre d'appartenance de chaque objet a ce cluster */
private double membershipDegree[] = null;
/** Probabilite de la classe (pour EM) */
private double membershipProbabilityEM = 0;
/**
* <p>
* Constructeur de copie
* </p>
*
* @param cluster
* une classe
*/
public SimpleCluster(final SimpleCluster cluster) {
super(cluster);
this.data = (Data) cluster.data.clone();
this.membershipDegree = new double[cluster.membershipDegree.length];
for (int i = 0; i < this.membershipDegree.length; i++) {
try {
this.membershipDegree[i] = cluster.getMembership(i);
} catch (MethodNotImplementedException e) {
e.printStackTrace();
}
}
this.membershipProbabilityEM = cluster.membershipProbabilityEM;
}
<<<<<<< HEAD
=======
/**
* <p>
* Constructeur. (principal)
* </p>
*
* @param data
* l'ensemble de donnees d'o� est extraite la classe
* @param clusterMap
* la carte de classification
* @param k
* l'index de la classe
* @param weights
* le vecteur de poid associe a la classe
* @param membershipDegree
* le degre d'appartenance de tous les objets a la classe
* @param proba
* probabilite qu'un objet appartienne a cette classe
* @param result
* the parent result of the cluster
*/
public SimpleCluster(final Data data, final int clusterMap[], final int k,
final Weights weights, final double membershipDegree[],
final double proba, ClusteringResult result) {
super(result);
int c = 0;
this.weights = weights;
this.membershipDegree = new double[clusterMap.length];
if (membershipDegree != null) {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
}
this.membershipDegree[i] = membershipDegree[i];
}
} else {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
this.membershipDegree[i] = 1.;
} else {
this.membershipDegree[i] = 0.;
}
}
}
// TODO this.data = new Data(c, data.getStructure());
this.data = new SimpleData(c);
this.data.setComments(data.getComments());
this.data.setDataName(data.getDataName());
this.data.setAttributesNames(data.getAttributesNames());
c = 0;
Iterator<DataObject> iter = data.iterator();
int i = 0;
while(iter.hasNext()) {
DataObject current = iter.next();
if (clusterMap[i] == k) {
this.data.setDataObject(c, current);
c++;
}
i++;
}
if (this.data.getNbObjects() != 0) {
this.clusterCenter = this.computeCenter();
} else {
this.setVisible(false);
// System.out.println("attention, creation d'un cluster vide.");
}
this.membershipProbabilityEM = proba;
this.locked = false;
this.name = "Cluster " + (k + 1);
this.id = k;
}
>>>>>>> master
/**
* <p>
* Constructeur.
* </p>
*
* @param center
* centre de la classe
* @param data
* l'ensemble de donnees d'o est extraite la classe
* @param clusterMap
* la carte de classification
* @param k
* l'index de la classe
* @param weights
* le vecteur de poid associe a la classe
* @param membershipDegree
* le degre d'appartenance de tous les objets a la classe
* @param proba
* probabilite qu'un objet appartienne a cette classe
* @param result
* the parent result of the cluster
*/
public SimpleCluster(final DataObject center, final Data data,
final int clusterMap[], final int k, final Weights weights,
final double membershipDegree[], final double proba,
ClusteringResult result) {
super(result);
int c = 0;
this.weights = weights;
this.membershipDegree = new double[clusterMap.length];
if (membershipDegree != null) {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
}
this.membershipDegree[i] = membershipDegree[i];
}
} else {
for (int i = 0; i < clusterMap.length; i++) {
if (clusterMap[i] == k) {
c++;
this.membershipDegree[i] = 1.;
} else {
this.membershipDegree[i] = 0.;
}
}
}
this.data = new SimpleData(c, data.getDistanceModel(), data.getDistanceParameters());
this.data.setComments(data.getComments());
this.data.setDataName(data.getDataName());
this.data.setAttributesNames(data.getAttributesNames());
c = 0;
Iterator<DataObject> iter = data.iterator(0, clusterMap.length);
int i = 0;
while(iter.hasNext()) {
DataObject current = iter.next();
if (clusterMap[i] == k) {
this.data.setDataObject(c, current);
c++;
}
i++;
}
if (this.data.getNbObjects() != 0) {
this.clusterCenter = center;
} else {
this.setVisible(false);
// System.out.println("attention, creation d'un cluster vide.");
}
this.membershipProbabilityEM = proba;
this.locked = false;
this.name = "Cluster " + (k + 1);
this.id = k;
}
/**
* <p>
* Constructeur a partir d'un nom. ( utilisé pour construire une hiérarchie
* avec la méthodre arbreCobWeb() )
* </p>
*
* @param name
* le nom du cluster
* @param result
* the parent result of the cluster
*/
public SimpleCluster(final String name, ClusteringResult result) {
super(result);
this.name = name;
}
<<<<<<< HEAD
=======
public SimpleCluster(Cluster cluster, boolean fromSample) {
super(cluster);
if (cluster.getData(fromSample) != null) {
this.data = (Data) cluster.getData(fromSample).clone();
}
try {
if(cluster instanceof SimpleCluster) {
this.membershipDegree = new double[((SimpleCluster)cluster).membershipDegree.length];
for (int i = 0; i < this.membershipDegree.length; i++) {
this.membershipDegree[i] = cluster.getMembership(i);
}
this.membershipProbabilityEM = ((SimpleCluster)cluster).membershipProbabilityEM;
} else {
this.membershipDegree = new double[cluster.getCard()];
for (int i = 0; i < this.membershipDegree.length; i++) {
this.membershipDegree[i] = cluster.getMembership(i);
}
}
} catch (MethodNotImplementedException e) {
e.printStackTrace();
}
if (this.clusterCenter == null)
this.clusterCenter = this.computeCenter();
}
>>>>>>> master
@Override
public Object clone() {
return new SimpleCluster(this);
}
@Override
public int getCard() {
if (this.data == null) {
return 0;
}
return this.data.getNbObjects();
}
/**
* <p>
* Centre de la classe.
* </p>
*
* @return le centre de la classe
*/
public DataObject getClusterCenter() {
return this.clusterCenter;
}
/**
* <p>
* Les objets de la classe.
* </p>
*
* @parma fromSample
* tells if we want the Data based on object from the sample or the whole data
*
* @return les objets de la classe
*/
@Override
public Data getData(boolean fromSample) {
return this.data;
}
/**
* <p>
* Objet de la classe.
* </p>
*
* @param objIndex
* l'index de l'objet dans la classe
* @return le l'objet à l'indice objIndex
*/
public DataObject getObject(final int objIndex) {
// check if objIndex is ok
if (objIndex >= this.data.getNbObjects()) {
System.out.println("error: class Cluster, method getObject");
return null;
}
// returns requested object
return this.data.getDataObject(objIndex);
}
/**
* <p>
* Degre d'appartenance d'un objet e la classe.
* </p>
*
* @param o
* l'index de l'objet
* @return le degre d'appartenance du o-ieme objet e la classe
*/
public double getMembership(final int o) throws MethodNotImplementedException {
double degree = 0;
if ((o >= 0) && (o < this.membershipDegree.length)) {
degree = this.membershipDegree[o];
}
return degree;
}
/**
* <p>
* Probabilite de la classe.
* </p>
*
* @return la probabilite de la classe
*/
public double getMembershipProbabilityEM() throws MethodNotImplementedException {
return this.membershipProbabilityEM;
}
/**
* <p>
* Locke la classe.
* </p>
*/
public void lock() {
this.locked = true;
this.data.lock();
}
/**
* <p>
* Delocke la classe.
* </p>
*/
public void unlock() {
this.locked = false;
this.data.unlock();
}
@Override
public DataObject getCenter() {
return this.clusterCenter;
}
}
......@@ -9,14 +9,14 @@ import java.util.Vector;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.DistanceModel;
import jcl.data.SimpleData;
import jcl.data.distance.DistanceModel;
import jcl.data.distance.average.AverageParameter;
import jcl.learning.LearningResult;
import jcl.learning.methods.monostrategy.kmeans.LearningResultKmeans;
import jcl.utils.exceptions.MethodNotImplementedException;
import jcl.weights.ClassificationWeights;
import jcl.weights.LocalWeights;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
* <p>
......@@ -65,6 +65,7 @@ public class SimpleClusteringResult extends ClusteringResult {
this.clusters = new Cluster[result.clusters.length];
for (int i = 0; i < result.clusters.length; i++) {
this.clusters[i] = (Cluster) result.clusters[i].clone();
this.clusters[i].setResult(this);
}
this.weights = (ClassificationWeights) result.weights.clone();
......
package jcl.clustering.constraints;
import jcl.clustering.ClusteringResult;
import jcl.data.DataObject;
import jcl.data.distance.DistanceModel;
import jcl.data.distance.DistanceParameter;
/**
* Class that represent a generic constraint.
......@@ -57,4 +60,95 @@ public abstract class Constraint {
return true;
}
/**
* Compute the marginal silhouette score of the i-th object from a Data.
* A value close to 1 indicates is similar to other object from his class,
* a value close to 0 indicates that the object is close to another class.
*
* @param index
* the object to evaluate index
* @param result
* the result to evaluate the object to
* @param metricToUse
* the metric to use for the evaluation
* @param parameters
* the parameters used by the metric if needed
* @return the marginal silhouette score
*/
public static double marginalSilhouetteScore(int index, ClusteringResult result, DistanceModel metricToUse,
DistanceParameter[] parameters) {
double msc = 0.0;
int closerCluster = -1;
double minDist = 0;
DataObject obj = result.getData().getDataObject(index);
if (result.getClusterCenter(0) != null) {
minDist = metricToUse.getMetaDistance().compute(obj, result.getClusterCenter(0),
metricToUse.getDistances(), parameters);
closerCluster = 0;
for (int i = 1 ; i < result.getNbClusters() ; i++) {
if (result.getClusterCenter(i) != null) {
double tmpDist = metricToUse.getMetaDistance().compute(result.getData().getDataObject(index),
result.getClusterCenter(i), metricToUse.getDistances(), parameters);
if (tmpDist < minDist) {
minDist = tmpDist;
closerCluster = i;
}
}
}
msc = computeAvgDissimilarity(obj, closerCluster, result, metricToUse, parameters);
} else {
msc = computeAvgDissimilarity(obj, 0, result, metricToUse, parameters);