Skip to content
Snippets Groups Projects
Commit a463be4b authored by VERNEREY Charles's avatar VERNEREY Charles
Browse files

Add instructions for the API

parent 714b9363
Branches
No related tags found
No related merge requests found
......@@ -175,3 +175,4 @@ $RECYCLE.BIN/
RankLib/
svm_rank_linux64/
results/exp_*
results/train
\ No newline at end of file
......@@ -7,7 +7,7 @@ exp_time = results/exp_time
jar_cmd = java -cp target/choquet-rank-1.0.0-jar-with-dependencies.jar
install:
mvn package
mvn -DskipTests package
exp_passive:
rm -rf ${exp_passive}
mkdir -p ${exp_passive}/learn
......
# Instructions pour utiliser l'API
Pour pouvoir utiliser l'API, vous avez besoin dans un premier temps de suivre les instructions de la section "Experiments requirements" du fichier README.md afin de compiler le projet. Il existe alors deux points d'entrée pour l'API en utilisant la ligne de commande.
## Création des jeux d'entraînement et de test
La première étape est de séparer l'ensemble de règles en un jeu d'entraînement et un jeu de test qui serviront pour alimenter notre modèle. Nous pouvons appeler l'API à l'aide la ligne de commande suivante :
```bash
java -cp target/choquet-rank-1.0.0-jar-with-dependencies.jar io.gitlab.chaver.minimax.cli.SplitTrainingTestCli
```
Nous allons illustrer l'usage de cette API avec l'exemple suivant après avoir exécuté la commande `mkdir results/train` pour créer un dossier qui servira à stocker nos résultats :
```bash
java -cp target/choquet-rank-1.0.0-jar-with-dependencies.jar io.gitlab.chaver.minimax.cli.SplitTrainingTestCli -d results/rules/iris --train 0.26 -r results/train/iris -m phi:kruskal:yuleQ --seed 1234
```
L'usage de chaque paramètre est le suivant :
- `-d` : représente le chemin des règles à utiliser pour l'entraînement du modèle. Dans cet exemple, deux fichiers vont être lus :
- *results/rules/iris_sols.jsonl* : fichier où chaque ligne représente une règle d'association
- *results/rules/iris_prop.jsonl* : fichier qui contient d'autres informations utiles comme le nombre de transactions de la base de données
- `--train` : représente le pourcentage de règles à utiliser pour l'entraînement du modèle, c'est un réel compris entre 0 et 1. Dans cet exemple, nous utilisons 26% de règles pour entraîner le modèle et le reste pour le test.
- `-r` : représente le chemin où seront stockés le fichier d'entraînement et de test. Dans cet exemple, deux fichiers vont être créés :
- *results/train/iris_train.jsonl* : fichier qui contiendra toutes les règles utilisées pour l'entraînement du modèle
- *results/train/iris_test.jsonl* : idem avec les règles utilisées pour le test du modèle
- `-m` : représente les mesures à calculer pour chaque règle et qui seront utilisées pour apprendre le modèle dans la prochaine étape. Dans cet exemple, nous utilisons les mesures phi, kruskal et yuleQ (chaque mesure étant séparée par :). Les mesures suivantes sont disponibles (voir la classe `RuleMeasures` du package `io.gitlab.chaver.minimax.rules.io`) :
```java
// Measure names
public static final String confidence = "confidence";
public static final String lift = "lift";
public static final String cosine = "cosine";
public static final String phi = "phi";
public static final String kruskal = "kruskal";
public static final String yuleQ = "yuleQ";
public static final String addedValue = "pavillon";
public static final String certainty = "certainty";
public static final String support = "support";
public static final String revsupport = "revsup";
```
- `--seed` : une seed qui permet d'assurer la reproductibilité des expériences
## Apprentissage du modèle et évaluation
Dans une deuxième étape, nous allons apprendre un modèle à l'aide du jeu d'entraînement généré précédemment et nous allons évaluer ce dernier sur le jeu de test. Nous pouvons appeler l'API correspondante à l'aide de la ligne de commande suivante :
```bash
java -cp target/choquet-rank-1.0.0-jar-with-dependencies.jar io.gitlab.chaver.minimax.cli.LearnFunctionAndRankCli
```
Nous allons illustrer l'usage de cette API avec l'exemple suivant :
```bash
java -cp target/choquet-rank-1.0.0-jar-with-dependencies.jar io.gitlab.chaver.minimax.cli.LearnFunctionAndRankCli -d results/rules/iris -m phi:kruskal:yuleQ --seed 1234 --tt results/train/iris -o linear -l kappalab -r results/train/iris
```
L'usage de `-d`, `-m` et `--seed` est le même que précédemment (ces paramètres doivent avoir la même valeur que précédemment). L'usage des autres paramètres est le suivant :
- `--tt` : correspond au chemin des fichiers d'entraînement de test du modèle (i.e. la valeur correspondante à `-r` lors de l'appel de l'API précédente)
- `-o` : nom de l'oracle utilisé, pour l'instant les valeurs suivantes sont possibles :
- **linear** : fonction linéaire (somme pondérée)
- **owa** : Ordered Weighted Average
- `-l` : nom de l'algorithme d'apprentissage utilisé pour apprendre le modèle, les valeurs suivantes sont possibles :
- **kappalab**
- **ahp**
- **svm**
- `-r` : chemin où sera stocké les résultats de l'apprentissage, 3 fichiers vont être créés dans cet exemple :
- *results/train/iris_func.jsonl* : représente la fonction apprise du modèle
- *results/train/iris_metrics.jsonl* : représente les métriques utilisées pour évaluer la qualité du modèle
- *results/train/iris_ordered_test_rules.jsonl* : fichier avec les règles du jeu de test classées à l'aide la fonction apprise du modèle
Il est également possible de préciser des paramètres supplémentaires en fonction de l'algorithme d'apprentissage choisi. Si c'est kappalab, alors les paramètres suivants peuvent être rajoutés :
- `--delta` : un nombre réel > 0 qui représente le delta minimum entre deux alternatives (valeur par défaut : 1e-5)
- `--kadd` : un entier > 0 qui représente la k-additivité du modèle (valeur par défaut : 2)
- `--sigf` : un entier > 0 qui représente le nombre de chiffres significatifs utilisé dans l'apprentissage (valeur par défaut : 3)
Pour svm, le paramètre suivant peut être ajouté :
- `-c` : un réel > 0 qui représente le paramètre de régularisation du modèle (valeur par défaut : 0.01)
Nous allons analyser chaque fichier résultat. Commençons par `iris_func.jsonl` qui représente la fonction apprise du modèle :
```json
{
"functionType": "mobiusChoquet",
"weights": [
0,
0.4148,
0.3067,
0.3215,
0.1618,
-0.2738,
0.069
],
"kAdditivity": 2,
"nbCriteria": 3,
"timeToLearn": 0.66,
"timeOut": false,
"nbIterations": 0,
"shapleyValues": [
0.3588,
0.4221,
0.2191
],
"interactionIndices": [
[
0,
0.1618,
-0.2738
],
[
0.1618,
0,
0.069
],
[
-0.2738,
0.069,
0
]
],
"obj": [
0.0001
],
"weightLabels": [
"{}",
"{phi}",
"{kruskal}",
"{yuleQ}",
"{phi,kruskal}",
"{phi,yuleQ}",
"{kruskal,yuleQ}"
],
"measureNames": [
"phi",
"kruskal",
"yuleQ"
]
}
```
Chaque champ a le rôle suivant :
- **functionType** : Le type de fonction apprise
- **measureNames** : Le nom de chaque mesure utilisée en entrée de la fonction
- **weights** et **weightLabels** : Les poids de la fonction apprise ainsi que le label associé à chaque poids. Dans l'exemple ci-dessus, nous avons les poids suivants :
| Label | Poids |
| --------------- | ------- |
| {} | 0 |
| {phi} | 0.4148 |
| {kruskal} | 0.3067 |
| {yuleQ} | 0.3215 |
| {phi,kruskal} | 0.1618 |
| {phi,yuleQ} | -0.2738 |
| {kruskal,yuleQ} | 0.069 |
- **kAdditivity** : La k-additivité du modèle (utile pour une fonction de type mobiusChoquet)
- **nbCriteria** : Le nombre de mesures utilisé en entrée de la fonction
- **timeToLearn** : Temps (en secondes) nécessaire pour apprendre la fonction (ici 0.66 secondes)
- **timeOut** : Booléen qui indique si l'apprentissage a été réalisé avec succès dans le temps imparti (si = TRUE cela signifie que l'on a pas pu apprendre de fonction dans le temps imparti)
- **nbIterations** : Valeur pas utile ici
- **shapleyValues** : Ce champ existe uniquement si le type de la fonction est mobiusChoquet. Il représente les valeurs de Shapley pour chaque mesure. Dans cet exemple, nous avons les valeurs suivantes :
| Mesure | Valeur de Shapley |
| ------- | ----------------- |
| phi | 0.3588 |
| kruskal | 0.4221 |
| yuleQ | 0.2191 |
- **interactionIndices** : Les indices d'interaction entre les différentes mesures si le type de la fonction est mobiusChoquet. Dans cet exemple, nous avons les indices d'interaction suivants :
| | phi | kruskal | yuleQ |
| ----------- | ------- | ------- | ------- |
| **phi** | 0 | 0.1618 | -0.2738 |
| **kruskal** | 0.1618 | 0 | 0.069 |
| **yuleQ** | -0.2738 | 0.069 | 0 |
- **obj** : Pas utile ici
Le fichier `iris_metrics.jsonl` a la forme suivante :
```json
{"kendall":0.999960332152113,"rec@1%":1.0,"AP@10%":1.0,"rec@10%":1.0,"spearman":0.999920664304226,"AP@1%":1.0}
```
Il représente un ensemble de métriques utilisées pour évaluer la qualité de la fonction apprise.
Enfin, le fichier `iris_ordered_test_rules.jsonl` a la forme suivante :
```json
{"x":[13],"y":[1,10],"measureValues":{"phi":1.0,"yuleQ":1.0,"kruskal":1.0},"score":1.0}
{"x":[10],"y":[1,13],"measureValues":{"phi":1.0,"yuleQ":1.0,"kruskal":1.0},"score":1.0}
{"x":[1],"y":[10,13],"measureValues":{"phi":1.0,"yuleQ":1.0,"kruskal":1.0},"score":1.0}
{"x":[4,13],"y":[1,10],"measureValues":{"phi":0.9488738697784996,"yuleQ":0.9996303742812153,"kruskal":0.9378170749383968},"score":0.9592490587495673}
{"x":[13],"y":[1,4,10],"measureValues":{"phi":0.9488738697784999,"yuleQ":0.9996303742812153,"kruskal":0.9336012834087966},"score":0.9569830708024073}
{"x":[1],"y":[4,10,13],"measureValues":{"phi":0.9488738697784999,"yuleQ":0.9996303742812153,"kruskal":0.9336012834087966},"score":0.9569830708024073}
{"x":[15],"y":[3,12],"measureValues":{"phi":0.913059470358805,"yuleQ":0.9942253850314515,"kruskal":0.8941710652068109},"score":0.929001794156864}
{"x":[2],"y":[14],"measureValues":{"phi":0.9010118042966065,"yuleQ":0.9930542928261625,"kruskal":0.8851183844495352},"score":0.922060751191058}
```
Chaque ligne représente une règle d'association du jeu de test. Les règles sont ordonnées par score décroissant, où le score est calculé à l'aide de la fonction apprise.
## Labels du dataset Eisen
Le fichier `data/eisen.names` contient le nom de chaque item du dataset eisen, où la première ligne réprésente le nom de l'item 1, la deuxième ligne le nom de l'item 2, etc...
Vous pouvez utiliser ce fichier pour afficher les noms des items de x et y dans chaque règle de eisen. Par exemple, si vous avez la règle suivante :
```json
{"x":[1,2],"y":[12]}
```
En utilisant le fichier eisen.names, vous pourrez afficher cette règle sur l'interface graphique de l'utilisateur :
```
{GO:0005737,GO:0016787} => {PHENOT:"reduced fitness in rich medium (YPD)"}
```
\ No newline at end of file
......@@ -44,15 +44,15 @@ public class LearnFunctionAndRankCli implements Callable<Integer> {
private String resPath;
// Kappalab parameters
@Option(names = "--delta", description = "Delta parameter (kappalab)")
@Option(names = "--delta", description = "Delta parameter (kappalab, default value : 1e-5)")
private double delta = 1e-5;
@Option(names = "--kadd", description = "k-additivity of the model (kappalab)")
@Option(names = "--kadd", description = "k-additivity of the model (kappalab, default value : 2)")
private int kAdd = 2;
@Option(names = "--sigf", description = "Number of significant figures (kappalab)")
@Option(names = "--sigf", description = "Number of significant figures (kappalab, default value : 3)")
private int sigf = 3;
// SVM parameters
@Option(names = "-c", description = "Regularisation parameter (SVM)")
@Option(names = "-c", description = "Regularisation parameter (svm, default value : 0.01)")
private double regularisationParameter = 0.01;
......@@ -174,6 +174,7 @@ public class LearnFunctionAndRankCli implements Callable<Integer> {
AbstractRankingLearning algo = getLearningAlgo(expectedRanking);
FunctionParameters functionParameters = algo.learn();
functionParameters.addWeightLabels(measures);
functionParameters.setMeasureNames(measures);
IScoreFunction<IAlternative> func = ScoreFunctionFactory.getScoreFunction(functionParameters);
Ranking<IAlternative> actualTestAlternativesRanking = computeRankingWithOracle(new ScoreFunctionOracle(func), testAlternatives);
Ranking<IAlternative> expectedTestAlternativesRanking = computeRankingWithOracle(oracle, testAlternatives);
......@@ -190,7 +191,7 @@ public class LearnFunctionAndRankCli implements Callable<Integer> {
IAlternative a = testAlternatives.get(pos);
testRulesRankedWithLearnedFunc.get(i).setScore(func.computeScore(a));
}
writeRules(resPath + "_rules.jsonl", testRulesRankedWithLearnedFunc);
writeRules(resPath + "_ordered_test_rules.jsonl", testRulesRankedWithLearnedFunc);
writeObject(resPath + "_func.jsonl", functionParameters);
writeObject(resPath + "_metrics.jsonl", rankingMetricValues);
return 0;
......
......@@ -25,7 +25,7 @@ public class SplitTrainingTestCli implements Callable<Integer> {
@Option(names = "-d", description = "Path of the rules data", required = true)
private String dataPath;
@Option(names = "--train", description = "% of data used for the training (value in [0,1])", required = true)
@Option(names = "--train", description = "%% of data used for the training (value in [0,1])", required = true)
private double trainingPercentage;
@Option(names = "-r", description = "Path of the result files", required = true)
private String resPath;
......
......@@ -32,6 +32,7 @@ public class FunctionParameters {
private double[][] interactionIndices;
private double[] obj;
private String[] weightLabels;
private String[] measureNames;
private BitSet[] orderCapacitySets() {
int maxNbCapacitySets = (int) Math.pow(2, nbCriteria);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment