Commit 7cdd1364 authored by gbequet's avatar gbequet
Browse files

operations S/M/R pour AHC

parent 4a9bf7dd
......@@ -165,7 +165,9 @@ public class TestSamarah {
classification.addAgent(parametersDbscan, simpleData);
classification.addAgent(parametersAHC, simpleData);
// classification.addAgent(parametersAHC2, simpleData);
classification.addAgent(parametersEm, simpleData);
// classification.addAgent(parametersEm, simpleData);
// System.out.println("ID de AHC : " + classification.getAgents().get(5).getId());
classification.classify();
System.out.println("\n End of classify");
......@@ -202,7 +204,7 @@ public class TestSamarah {
System.out.println("Nombre de clusters pour DBSCAN : " + agents.get(4).getNbClusters());
System.out.println("Nombre de clusters pour AHC : " + agents.get(5).getNbClusters());
// System.out.println("Nombre de clusters du 2eme AHC : " + agents.get(6).getNbClusters());
System.out.println("Nombre de clusters pour EM : " + agents.get(6).getNbClusters());
// System.out.println("Nombre de clusters pour EM : " + agents.get(6).getNbClusters());
}
......
......@@ -17,6 +17,7 @@ import jcl.learning.methods.monostrategy.dbscan.ClassifierDbscan;
import jcl.learning.methods.monostrategy.dbscan.LearningResultDbscan;
import jcl.learning.methods.monostrategy.dbscan.ParametersDbscan;
import jcl.learning.methods.monostrategy.em.LearningResultEM;
import jcl.learning.methods.monostrategy.kmeans.LearningResultKmeans;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
......@@ -98,53 +99,37 @@ public class ClassifierAHC extends LearningMethod {
}
@Override
public ClusteringResult merge(final LearningResult learningResult,
final ClusteringResult _result, final Data data, final Vector cr) {
if ((LearningResultAHC) learningResult != null) {
Collections.sort(cr);
int[] prevClusterMap = _result.getClusterMap();
int newC = (int) cr.get(0);
int[] newClusterMap = new int[_result.getNbObjects()];
for (int i=0; i<newClusterMap.length; i++) {
if (cr.contains(prevClusterMap[i])) {
newClusterMap[i] = newC;
}
else {
int k = 0;
boolean remp = false;
for (int j=0; j<cr.size() && !remp; j++) {
if (((int) cr.get(j) > prevClusterMap[i]) || (j == cr.size()-1)) {
if (k>=2) {
newClusterMap[i] = prevClusterMap[i] - k;
}
remp = true;
}
k++;
}
}
}
LearningResultAHC lr = (LearningResultAHC) _result.getLearningResult();
System.out.println("AHC Merge " + cr);
if (((LearningResultAHC) learningResult) != null) {
System.out.println("AHC merge " + cr);
return ClusteringResult.gerenerateDefaultClusteringResult(lr, newClusterMap, lr.getWeights(),
_result.getNbClusters() - cr.size() + 1, data, lr.getQualityIndices(), lr.getColors());
ClusteringResult res = ((LearningResultAHC) learningResult).mergeAgglomerates(data, _result, cr);
res.setMethode(this.getType());
return res;
}
return null;
}
@Override
public ClusteringResult reclass(final LearningResult learningResult,
final ClusteringResult _result, final Data data, final int c) {
return _result;
if (((LearningResultAHC) learningResult) != null) {
System.out.println("AHC reclass le cluster " + c);
ClusteringResult res = ((LearningResultAHC) learningResult).reclassAgglomerate(data, c, _result);
res.setMethode(this.getType());
return res;
}
return null;
}
@Override
public ClusteringResult split(final LearningResult learningResult,
final ClusteringResult _result, final Data data, final int c,
......@@ -153,23 +138,29 @@ public class ClassifierAHC extends LearningMethod {
// recup les objets du cluster à split
Data clusterData = _result.getData(c, true);
ParametersAHC params = (ParametersAHC) this.getParameters();
int nb = n;
// si pas assez d'objets on ajuste le nb de cluster
if (clusterData.getNbObjects() < n) {
nb = clusterData.getNbObjects();
}
System.out.println("AHC split le cluster " + c + " en " + nb);
// nouveau AHC sur les objets du cluster à split
ParametersAHC splitParams = new ParametersAHC(n, params.getModel(), params.getDistanceParameters());
ParametersAHC params = (ParametersAHC) this.getParameters();
ParametersAHC splitParams = new ParametersAHC(nb, params.getModel(), params.getDistanceParameters());
ClassifierAHC splitAHC = new ClassifierAHC(splitParams, null);
LearningResultAHC splitLearnResult = (LearningResultAHC) splitAHC.learn(clusterData);
ClusteringResult clusResSplit = splitLearnResult.classify(clusterData);
System.out.println("AHC a split le cluster " + c + " en " + clusResSplit.getNbClusters());
return ((LearningResultAHC) learningResult).reArrange(data, c, n, _result.getNbClusters(), clusResSplit, _result.getClusterMap());
ClusteringResult res = ((LearningResultAHC) learningResult).replaceAgglomerate(data, c, nb, _result, splitLearnResult);
res.setMethode(this.getType());
return res;
}
return null;
}
@Override
public ClusteringResult injectConstraints(LearningResult learningResult, ClusteringResult result, Data data,
Vector<Constraint> constraints) throws MethodNotImplementedException {
......
......@@ -114,6 +114,32 @@ public class DistanceMatrix
onlyEvaluate(offa,offb, model, distanceParameters);
}
public int findClosePairOfAgglo(int c, DistanceModel model, DistanceParameter[][] distanceParameters)
{
double tmpmin = Double.MAX_VALUE;
int res = -1;
int cSize = this.matrix[c].length;
for (int j=0; j<cSize; j++) {
if (this.matrix[c][j]<tmpmin && c!=j)
{
tmpmin = this.matrix[c][j];
res = j;
}
}
for (int i=cSize; i<this.matrix.length; i++) {
if (this.matrix[i][c]<tmpmin && i!=c)
{
tmpmin = this.matrix[i][c];
res = i;
}
}
return res;
}
/**
* trouve le couple d'agglomerats le plus proche et le fusionne en un
* seul agglomerat. cette methode met à jour la matrice de distance.
......
......@@ -8,9 +8,15 @@ import jcl.Classification;
import jcl.clustering.ClusteringResult;
import jcl.data.Data;
import jcl.data.DataObject;
import jcl.data.mask.DummyMask;
import jcl.data.mask.Mask;
import jcl.data.mask.MultiIDIntArrayMask;
import jcl.learning.LearningParameters;
import jcl.learning.LearningResult;
import jcl.learning.methods.monostrategy.dbscan.LearningResultDbscan;
import jcl.learning.methods.monostrategy.kmeans.KmeansSeed;
import jcl.learning.methods.monostrategy.kmeans.LightHardSeed;
import jcl.learning.methods.monostrategy.kmeans.ParametersKmeans;
import multiCube.tools.util.exceptions.MethodNotImplementedException;
/**
......@@ -21,11 +27,13 @@ import multiCube.tools.util.exceptions.MethodNotImplementedException;
*/
public class LearningResultAHC extends LearningResult {
int nbClusters;
public int nbClusters;
final static long serialVersionUID = 1L;
private final DistanceMatrix m;
private Vector<Agglomerate> matchingSet;
public int[] clusterMap = null;
......@@ -38,18 +46,50 @@ public class LearningResultAHC extends LearningResult {
super(params, params.weights, null);
this.nbClusters = ((ParametersAHC) params).nbClusters;
this.m = m;
this.matchingSet = this.cutDendogram(this.nbClusters);
}
public LearningResultAHC(LearningResultAHC learningResult) {
super(learningResult.params, learningResult.params.weights, learningResult.data);
this.nbClusters = learningResult.nbClusters;
this.m = learningResult.m;
// this.matchingSet = learningResult.matchingSet;
this.matchingSet = new Vector(learningResult.matchingSet);
}
public DistanceMatrix getDistanceMatrix() {
return this.m;
}
public Vector<Agglomerate> getMatchingSet() {
return this.matchingSet;
}
public void setMatchingSet(Vector<Agglomerate> newMatchingSet) {
this.matchingSet = newMatchingSet;
}
/**
* @return retourne la racine de l'abre hierarchique.
*/
public Agglomerate getHierarchy() {
if (!this.m.reduced()) {
System.out.println("warning, bad usage of getHierarchy()");
}
return this.m.getLastAgglomerate();
}
@Override
public Object clone() {
return new LearningResultAHC(this);
}
@Override
protected void setQualityIndices() {
// TODO Auto-generated method stub
}
private void cutDendogramRec(final Vector<Agglomerate> v, final int nbClustersToEnd, final int mod) {
......@@ -96,7 +136,7 @@ public class LearningResultAHC extends LearningResult {
return null;
}
final Vector<Agglomerate> matchingSet = this.cutDendogram(this.nbClusters);
// final Vector<Agglomerate> matchingSet = this.cutDendogram(this.nbClusters);
int nbObjects = -1;
Iterator<DataObject> dataToClassify = null;
......@@ -114,7 +154,7 @@ public class LearningResultAHC extends LearningResult {
for (int i = 0; i < resClusterMap.length; i++) {
DataObject tmp = dataToClassify.next();
int offset = -1;
for (final Iterator<Agglomerate> iter = matchingSet.iterator(); iter.hasNext();) {
for (final Iterator<Agglomerate> iter = this.matchingSet.iterator(); iter.hasNext();) {
final Agglomerate tmpAgglomerate = (Agglomerate) iter.next();
offset++;
if (tmpAgglomerate.getContent().contains(tmp)) {
......@@ -134,80 +174,91 @@ public class LearningResultAHC extends LearningResult {
this.nbClusters, data, this.qualityIndices, getColors());
}
public ClusteringResult mergeAgglomerates(final Data data, ClusteringResult clusRes, final Vector cr) {
Collections.sort(cr);
Vector<Agglomerate> agglomeratesToMerge = new Vector<Agglomerate>();
Agglomerate a, b, newAgglo;
a = this.matchingSet.get((int) cr.get(0));
b = this.matchingSet.get((int) cr.get(1));
agglomeratesToMerge.add(a);
agglomeratesToMerge.add(b);
newAgglo = Agglomerate.merge(a, b);
int newC = this.matchingSet.indexOf(a);
public ClusteringResult reArrange(final Data data, int c, int n, int nbClusters, ClusteringResult clusRes, int[] clusterMap) {
int nbObjects = data.getWholeDataNbObjects();
Iterator<DataObject> dataToClassify = data.getWholeSourceDataObjects();
int[] prevClusterMap = clusRes.getClusterMap();
int start = (int) cr.get(1);
for(int i=0; i<clusterMap.length; i++) {
DataObject obj1 = dataToClassify.next();
if(clusterMap[i] == c) {
int m = 0;
for (Iterator iter = clusRes.getData().getWholeSourceDataObjects(); iter.hasNext();) {
if (obj1 == (DataObject) iter.next()) {
if (prevClusterMap[m] != 0) {
clusterMap[i] = prevClusterMap[m] + nbClusters-1;
}
break;
}
m++;
}
for (int i=start+1; i<this.matchingSet.size(); i++) {
if (cr.contains(i)) {
b = this.matchingSet.get(i);
newAgglo = Agglomerate.merge(newAgglo, b);
agglomeratesToMerge.add(b);
}
}
this.nbClusters += n-1;
return ClusteringResult.gerenerateDefaultClusteringResult(this, clusterMap, this.weights,
nbClusters + n-1, data, this.qualityIndices, getColors());
// on supprime les anciens clusters et ajoute le nouveau
this.matchingSet.removeAll(agglomeratesToMerge);
this.matchingSet.add(newC, newAgglo);
this.nbClusters = this.matchingSet.size();
return this.classify(data,
clusRes.getClusterMap().length != data.getWholeDataNbObjects());
}
// a faire !
public ClusteringResult reClusterAgglomerate(final Data data, int c, ClusteringResult clusRes, boolean fromSample) {
int nbObjects = -1;
Iterator<DataObject> dataToClassify = null;
public ClusteringResult reclassAgglomerate(final Data data, int c, ClusteringResult clusRes) {
DistanceMatrix dm;
Agglomerate o;
DataObject tmpDataObject;
Vector<Agglomerate> newMatchingSet = this.matchingSet;
Vector<Agglomerate> forReclass = this.matchingSet;
if (fromSample) {
nbObjects = data.getNbObjects();
dataToClassify = data.iterator();
} else {
nbObjects = data.getWholeDataNbObjects();
dataToClassify = data.getWholeSourceDataObjects();
}
// recup les objets du cluster à reclass
Data clusterData = clusRes.getData(c, true);
final Vector<Agglomerate> matchingSet = this.cutDendogram(this.nbClusters);
int[] prevClusterMap = clusRes.getClusterMap();
Iterator<DataObject> prevDataToClassify = clusRes.getData().getWholeSourceDataObjects();
// Vector<Agglomerate> prevAgglo = clusRes.getLearningResult()
this.matchingSet.remove(c);
return null;
}
/**
* @return retourne la racine de l'abre hierarchique.
*/
public Agglomerate getHierarchy() {
if (!this.m.reduced()) {
System.out.println("warning, bad usage of getHierarchy()");
Iterator<DataObject> iter = clusterData.iterator();
while(iter.hasNext()) {
tmpDataObject = iter.next();
o = new Agglomerate(tmpDataObject);
forReclass.add(o);
dm = new DistanceMatrix(forReclass, this.params.getModel(), this.params.getDistanceParameters());
int index = dm.findClosePairOfAgglo(forReclass.size()-1, this.params.getModel(), this.params.getDistanceParameters());
newMatchingSet.get(index).content.add(tmpDataObject);
forReclass.removeElement(o);
}
return this.m.getLastAgglomerate();
}
this.matchingSet = newMatchingSet;
@Override
public Object clone() {
return new LearningResultAHC(this);
this.nbClusters = this.matchingSet.size();
return this.classify(data,
clusRes.getClusterMap().length != data.getWholeDataNbObjects());
}
public ClusteringResult replaceAgglomerate(final Data data, int c, int n, ClusteringResult clusRes, LearningResultAHC learningResSplit) {
// on supprime l'ancien cluster et on ajoute les nouveaux
this.matchingSet.remove(c);
this.matchingSet.addAll(c, learningResSplit.matchingSet);
this.nbClusters = this.matchingSet.size();
@Override
protected void setQualityIndices() {
// TODO Auto-generated method stub
return this.classify(data,
clusRes.getClusterMap().length != data.getWholeDataNbObjects());
}
@Override
public LearningResult ImportResult(String path) throws MethodNotImplementedException {
......
......@@ -3,6 +3,7 @@ package jcl.learning.methods.multistrategy.samarah;
import java.awt.Color;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
......@@ -252,8 +253,6 @@ public class HybridClassification extends Classification implements Runnable, It
// Choix des conflits a resoudre
this.conflicts = this.worthConflicts();
int a = 5;
a = 6;
for (int i = 0; i < this.conflicts.size(); i++) {
final SamarahConflict conf = this.conflicts.get(i);
......@@ -753,6 +752,7 @@ public class HybridClassification extends Classification implements Runnable, It
this.notifyObservers(HybridClassification.START);
this.evalMax = this.eval;
this.gammaMax = this.eval.GAMMA;
this.agentsMax = this.agents;
this.clusteringResultInitial = this.unification(false);
this.setChanged();
this.notifyObservers(HybridClassification.VIEW_AGENTS);
......@@ -887,7 +887,9 @@ public class HybridClassification extends Classification implements Runnable, It
// we just have a specific behavior for the first classification
imported = false;
}
this.setChanged();
this.setChanged();
this.agents = (Vector<LearningAgent>) (this.agentsMax.clone());
this.eval = this.evalMax;
this.setClusteringResult(this.unification(false));
/*
......@@ -1467,15 +1469,20 @@ public class HybridClassification extends Classification implements Runnable, It
}
for (int i = 0; i < nbre_agents; i++) {
a = this.getAgent(i);
final int k = clustermaps[i][p];
if (k >= 0) {
vote[i][k] += 1;
}
for (int j = 0; j < nbre_agents; j++) {
if ((j != i) && (k >= 0)) {
final int km = this.evalMax.alpha[i][j].maxColumn(k);
a = this.getAgent(j);
final int kj = clustermaps[j][p];
// we weight the impact of the vote
......@@ -1491,6 +1498,7 @@ public class HybridClassification extends Classification implements Runnable, It
double max = vote[0][0];
for (int i = 0; i < nbre_agents; i++) {
a = this.getAgent(i);
for (int j = 0; j < a.getNbClusters(); j++) {
if (vote[i][j] > max) {
max = vote[i][j];
......@@ -1538,7 +1546,8 @@ public class HybridClassification extends Classification implements Runnable, It
} catch (final ClassCastException ex) {
agentMin = 0;
}
this.overall_stat = ff;
if (this.first_stat == null) {
this.first_stat = stat;
......
......@@ -343,7 +343,7 @@ public class SamarahConflict {
eval.addHistory(tour, "split A" + ag1.getId());
}
} else if (gamma4 >= gamma1 && gamma4 >= gamma2 && gamma4 >= gamma3) {
solution = new SamarahConflict(this.agent1, ag2, this.classe,
solution = new SamarahConflict(ag1, ag2, this.classe,
this.degre);
eval.addHistory(tour, "merge A" + ag2.getId() + " & split A"
+ ag1.getId());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment