Skip to content

Commit

Permalink
Improve stability of coclustering IV results (#191)
Browse files Browse the repository at this point in the history
La stabilite des resultats d'analyse bivariee et plus generalement de coclustering
 a ete mise en place recemment pour les tests massifs de la version 10.2 via LearningTest.
Lors du merge de dev-v11, cette stabilisation a ete reportee.
Il s'agit de l'extension de cette stabilisation au cas du coclustering IV

Methodes principales impactees:
- KWDatagrid, KWSortableObjectComparePartValue -> KWSortableObjectCompareValue
  - methode prenant en compte la claxsse virtuelle KWDGValue pour les valeurs de type Symbol ou VarPartK
  - prise en compte de l'index aleatoire en critere de tri secondaire
- KWDataGridManager::SortAttributePartsByTargetGroups
  - generalisation de la perturbation aleatoire au cas IV
  - implementation generique unique

Tests sur tout LearningTest
  • Loading branch information
marcboulle authored Mar 13, 2024
1 parent 787233e commit 92740b7
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 53 deletions.
12 changes: 10 additions & 2 deletions src/Learning/KWDataPreparation/KWDataGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4738,8 +4738,9 @@ int KWDGValueCompareTypicality(const void* elem1, const void* elem2)
return value1->CompareTypicality(value2);
}

int KWSortableObjectComparePartValue(const void* elem1, const void* elem2)
int KWSortableObjectCompareValue(const void* elem1, const void* elem2)
{
int nCompare;
KWDGValue* value1;
KWDGValue* value2;

Expand All @@ -4750,7 +4751,14 @@ int KWSortableObjectComparePartValue(const void* elem1, const void* elem2)
value1 = cast(KWDGValue*, cast(KWSortableObject*, *(Object**)elem1)->GetSortValue());
value2 = cast(KWDGValue*, cast(KWSortableObject*, *(Object**)elem2)->GetSortValue());

return value1->CompareValue(value2);
// Comparaison sur la valeur
nCompare = value1->CompareValue(value2);

// Comparaison sur l'index si egal
if (nCompare == 0)
nCompare = cast(KWSortableObject*, *(Object**)elem1)->GetIndex() -
cast(KWSortableObject*, *(Object**)elem2)->GetIndex();
return nCompare;
}

//////////////////////////////////////////////////////////////////////////////
Expand Down
7 changes: 4 additions & 3 deletions src/Learning/KWDataPreparation/KWDataGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ class KWDGValueSet : public KWDGPartValues

//////////////////////////////////////////////////////////////////////////////
// Classe KWDGValue
// Classe virtuelle pour mutualiser la gestion des valeur de type Symbol ou VarPart
// Classe virtuelle pour mutualiser la gestion des valeurs de type Symbol ou VarPart
class KWDGValue : public Object
{
public:
Expand Down Expand Up @@ -1147,8 +1147,9 @@ int KWDGValueCompareFrequency(const void* elem1, const void* elem2);
// Comparaison de deux typicalite
int KWDGValueCompareTypicality(const void* elem1, const void* elem2);

// Comparaison de deux objets KWSortableObject contenant des KWDGValue, par valeur
int KWSortableObjectComparePartValue(const void* elem1, const void* elem2);
// Comparaison de deux objets KWSortableObject contenant des KWDGValue, par valeur puis par index
// Permet un comparaison generique pour des valeurs de type Symbol ou VarPart
int KWSortableObjectCompareValue(const void* elem1, const void* elem2);

//////////////////////////////////////////////////////////////////////////////
// Classe KWDGSymbolValueSet
Expand Down
54 changes: 10 additions & 44 deletions src/Learning/KWDataPreparation/KWDataGridManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4159,8 +4159,7 @@ void KWDataGridManager::SortAttributePartsByTargetGroups(const KWDGAttribute* so
boolean bIsIndexed;
ObjectArray oaSourceParts;
ObjectArray oaAssociations;
KWSortableSymbol* associationSymbol;
KWSortableObject* associationVarPart;
KWSortableObject* associationValue;
KWDGPart* sourcePart;
KWDGPart* groupedPart;
IntVector ivRandomIndexes;
Expand Down Expand Up @@ -4189,21 +4188,12 @@ void KWDataGridManager::SortAttributePartsByTargetGroups(const KWDGAttribute* so

// Tri des association, apres une randomisation pour avoir un ordre aleatoire par groupe
// CH IV Refactoring: a revoir plus tard apres avoir integre la retokenisation dans le cadre du GenerateVNS
// CH IV Refactoring: Code specifique suite a refactoring et unification avec l'ancienne methode SortVarPartAttributeParts
// CH IV Refactoring: Pourquoi le Shuffle est fait dans le cas Symbol et pas VarPart? on ne sait pas
// CH IV Refactoring: Probleme potentiel supplementaire, faire un shuffle suivi d'un sort entraine des instabilite entre
// CH IV Refactoring: windows et linux, car le Sort de windows ne semble pas etre un "stable sort" (qui garantit qu'en
// CH IV Refactoring: cas d'egalite, les items sont dans le meme ordre que l'ordre initial)
//
// CH IV Refactoring: Probleme des instabilites corrige en V10.2.0, et correction reportee, mais uniquement dans le cas
// CH IV Refactoring: des valeurs Sumbol d'un variable categorielle: corrction a transposer dans le cas VarPart

// Construction d'un vecteur d'index des parties source pour les gerer en ordre aleatoire
ivRandomIndexes.SetSize(oaSourceParts.GetSize());
for (n = 0; n < ivRandomIndexes.GetSize(); n++)
ivRandomIndexes.SetAt(n, n);
if (sourceAttribute->GetAttributeType() == KWType::Symbol)
ivRandomIndexes.Shuffle();
ivRandomIndexes.Shuffle();

// Initialisation d'un tableau d'associations entre index de partie source et
// (premiere) valeur de groupe source
Expand All @@ -4220,29 +4210,14 @@ void KWDataGridManager::SortAttributePartsByTargetGroups(const KWDGAttribute* so
groupedPart = groupedAttribute->LookupGroupablePart(sourcePart->GetValueSet()->GetHeadValue());

// Creation de l'association entre index de partie et premiere valeur du groupe
if (sourceAttribute->GetAttributeType() == KWType::Symbol)
{
associationSymbol = new KWSortableSymbol;
oaAssociations.SetAt(nSource, associationSymbol);
associationSymbol->SetIndex(nRandomIndex);
associationSymbol->SetSortValue(groupedPart->GetValueSet()->GetHeadValue()->GetSymbolValue());
}
else
{
// CH IV Refactoring: a revoir et unifier avec la getion des valeurs Symbol
associationVarPart = new KWSortableObject;
oaAssociations.SetAt(nSource, associationVarPart);
associationVarPart->SetIndex(nSource);
associationVarPart->SetSortValue(groupedPart->GetValueSet()->GetHeadValue());
}
associationValue = new KWSortableObject;
oaAssociations.SetAt(nSource, associationValue);
associationValue->SetIndex(nRandomIndex);
associationValue->SetSortValue(groupedPart->GetValueSet()->GetHeadValue());
}

// Tri des association, apres une randomisation pour avoir un ordre aleatoire par groupe
if (sourceAttribute->GetAttributeType() == KWType::Symbol)
oaAssociations.SetCompareFunction(KWSortableSymbolCompareValue);
else
// CH IV Refactoring: a revoir et unifier avec la getion des valeurs Symbol
oaAssociations.SetCompareFunction(KWSortableObjectComparePartValue);
oaAssociations.SetCompareFunction(KWSortableObjectCompareValue);
oaAssociations.Sort();

// On range dans le tableau en sortie les parties sources, triees par groupe
Expand All @@ -4251,18 +4226,9 @@ void KWDataGridManager::SortAttributePartsByTargetGroups(const KWDGAttribute* so
oaSortedGroupedParts->SetSize(oaSourceParts.GetSize());
for (n = 0; n < oaAssociations.GetSize(); n++)
{
if (sourceAttribute->GetAttributeType() == KWType::Symbol)
{
associationSymbol = cast(KWSortableSymbol*, oaAssociations.GetAt(n));
nRandomIndex = associationSymbol->GetIndex();
nSource = ivRandomIndexes.GetAt(nRandomIndex);
}
else
{
// CH IV Refactoring: a revoir et unifier avec la getion des valeurs Symbol
associationVarPart = cast(KWSortableObject*, oaAssociations.GetAt(n));
nSource = associationVarPart->GetIndex();
}
associationValue = cast(KWSortableObject*, oaAssociations.GetAt(n));
nRandomIndex = associationValue->GetIndex();
nSource = ivRandomIndexes.GetAt(nRandomIndex);

// Recherche de la partie source
sourcePart = cast(KWDGPart*, oaSourceParts.GetAt(nSource));
Expand Down
5 changes: 2 additions & 3 deletions src/Learning/MODL/MODL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void SetWindowsDebugDir(const ALString& sDatasetFamily, const ALString& sDataset
// A parametrer pour chaque utilisateur
// Devra etre fait plus proprement quand tout l'equipe sera sur git, par exemple via une variable
// d'environnement et quelques commentaires clairs
sUserRootPath = "D:/Users/miib6422/Documents/boullema/LearningTest/TestKhiops/";
sUserRootPath = "D:/Users/miib6422/Documents/boullema/LearningTest.V10.5.0-a1/LearningTest/TestKhiops/";

// Pour permettre de continuer a utiliser LearningTest, on ne fait rien s'il y a deja un fichier test.prm
// dans le repertoire courante
Expand All @@ -37,8 +37,7 @@ int main(int argc, char** argv)

// Choix du repertoire de lancement pour le debugage sous Windows (a commenter apres fin du debug)
// SetWindowsDebugDir("Standard", "IrisLight");
// SetWindowsDebugDir("Standard", "Iris2D");
SetWindowsDebugDir("BugsMultiTables", "BugUnsortedRootTable");
// SetWindowsDebugDir("Standard", "IrisU2D");

// Parametrage des logs memoires depuis les variables d'environnement, pris en compte dans KWLearningProject
// KhiopsMemStatsLogFileName, KhiopsMemStatsLogFrequency, KhiopsMemStatsLogToCollect
Expand Down
2 changes: 1 addition & 1 deletion src/Learning/MODL_Coclustering/MODL_Coclustering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void SetWindowsDebugDir(const ALString& sDatasetFamily, const ALString& sDataset
// A parametrer pour chaque utilisateur
// Devra etre fait plus proprement quand tout l'equipe sera sur git, par exemple via une variable
// d'environnement et quelques commentaires clairs
sUserRootPath = "D:/Users/miib6422/Documents/boullema/LearningTest/TestCoclustering/";
sUserRootPath = "D:/Users/miib6422/Documents/boullema/LearningTest.V10.5.0-a1/LearningTest/TestCoclustering/";

// Pour permettre de continuer a utiliser LearningTest, on ne fait rien s'il y a deja un fichier test.prm
// dans le repertoire courante
Expand Down

0 comments on commit 92740b7

Please sign in to comment.