diff --git a/doc-sources/changelog.rst b/doc-sources/changelog.rst index 7e4c45b7..192dfc1d 100644 --- a/doc-sources/changelog.rst +++ b/doc-sources/changelog.rst @@ -4,6 +4,20 @@ Changelog ========= +Version 0.11.0 +============== + +- **Breaking** Rename ``category_correlation`` to ``preference_direction`` in problem files +- **Breaking** Rename the ``growing`` preference direction to ``increasing`` in problem files +- **Breaking** Rename the ``categories`` attribute in problem files to ``ordered_categories`` in problem files +- Make names of generated categories more explicit ("Worst category", "Intermediate category N", "Best category") +- Support ``isotone`` (resp. ``antitone``) as a synonym for ``increasing`` (resp. ``decreasing``) in problem files +- Add ``lincs describe`` command to produce human-readable descriptions of problems and models +- **Remove** comments about termination conditions from learned models, but: +- Add ``--mrsort.weights-profiles-breed.output-metadata`` to generate in YAML the data previously found in those comments +- Provide a Jupyter notebook to help follow the "Get Started" guide (and use Jupyter for all integration tests) +- Document the "externally managed" error on Ubuntu 23.4+ + (In versions below, the term "category correlation" was used instead of "preference direction".) Versions 0.10.0 to 0.10.3 diff --git a/doc-sources/conceptual-overview/conceptual-overview.ipynb b/doc-sources/conceptual-overview/conceptual-overview.ipynb index 4b2fafb2..b98db066 100644 --- a/doc-sources/conceptual-overview/conceptual-overview.ipynb +++ b/doc-sources/conceptual-overview/conceptual-overview.ipynb @@ -21,7 +21,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs classify problem.yml model.yml alternatives.csv\n", + "# Reproduction command (with lincs version 0.11.0): lincs classify problem.yml model.yml alternatives.csv\n", "name,Math,Physics,Literature,History,category\n", "A,1,1,1,1,\"Full scholarship\"\n", "B,1,1,1,0,\"Full scholarship\"\n", diff --git a/doc-sources/get-started.rst b/doc-sources/get-started.rst index 1a2d99a0..72363775 100644 --- a/doc-sources/get-started.rst +++ b/doc-sources/get-started.rst @@ -68,7 +68,7 @@ So, start by generating a classification problem with 4 criteria and 3 categorie The generated ``problem.yml`` should look like:: - # Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 40 + # Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 40 kind: classification-problem format_version: 1 criteria: @@ -132,7 +132,7 @@ Then generate an NCS classification model:: It should look like:: - # Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort + # Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort kind: ncs-classification-model format_version: 1 accepted_values: @@ -199,7 +199,7 @@ Then we'll need to think about the how the ``--max-imbalance`` option interacts It should start with something like this, and contain 1000 alternatives:: - # Reproduction command (with lincs version 0.10.4-dev): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0 + # Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0 name,"Criterion 1","Criterion 2","Criterion 3","Criterion 4",category "Alternative 1",0.37454012,0.796543002,0.95071429,0.183434784,"Best category" "Alternative 2",0.731993914,0.779690981,0.598658502,0.596850157,"Intermediate category 1" @@ -237,7 +237,7 @@ The learning set doesn't contain all the information from the original model, and the trained model was reconstituted from this partial information, so it is numerically different:: - # Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0 + # Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0 kind: ncs-classification-model format_version: 1 accepted_values: diff --git a/doc-sources/get-started/get-started.ipynb b/doc-sources/get-started/get-started.ipynb index d03bd5cc..14cf5b6c 100644 --- a/doc-sources/get-started/get-started.ipynb +++ b/doc-sources/get-started/get-started.ipynb @@ -48,7 +48,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 40\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 40\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -126,7 +126,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", @@ -216,7 +216,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0\n", "name,\"Criterion 1\",\"Criterion 2\",\"Criterion 3\",\"Criterion 4\",category\n", "\"Alternative 1\",0.37454012,0.796543002,0.95071429,0.183434784,\"Best category\"\n", "\"Alternative 2\",0.731993914,0.779690981,0.598658502,0.596850157,\"Intermediate category 1\"\n", @@ -270,7 +270,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/doc-sources/user-guide.rst b/doc-sources/user-guide.rst index dbe1f98e..ffa6adcc 100644 --- a/doc-sources/user-guide.rst +++ b/doc-sources/user-guide.rst @@ -473,7 +473,7 @@ And:: They produce a different kind of model, with the sufficient coalitions specified explicitly by their roots:: - # Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions + # Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions kind: ncs-classification-model format_version: 1 accepted_values: diff --git a/doc-sources/user-guide/alglib-learning/alglib-learning.ipynb b/doc-sources/user-guide/alglib-learning/alglib-learning.ipynb index 8714af46..ec946a2c 100644 --- a/doc-sources/user-guide/alglib-learning/alglib-learning.ipynb +++ b/doc-sources/user-guide/alglib-learning/alglib-learning.ipynb @@ -27,7 +27,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver alglib --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver alglib --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/doc-sources/user-guide/gpu-learning/gpu-learning.ipynb b/doc-sources/user-guide/gpu-learning/gpu-learning.ipynb index 72117e87..29646dcd 100644 --- a/doc-sources/user-guide/gpu-learning/gpu-learning.ipynb +++ b/doc-sources/user-guide/gpu-learning/gpu-learning.ipynb @@ -27,7 +27,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor gpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor gpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/doc-sources/user-guide/sat-learning/sat-learning.ipynb b/doc-sources/user-guide/sat-learning/sat-learning.ipynb index 0f3bf4dd..8c48a999 100644 --- a/doc-sources/user-guide/sat-learning/sat-learning.ipynb +++ b/doc-sources/user-guide/sat-learning/sat-learning.ipynb @@ -22,7 +22,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", @@ -58,7 +58,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy max-sat-by-separation\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy max-sat-by-separation\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/doc-sources/user-guide/synthetic-data/synthetic-data.ipynb b/doc-sources/user-guide/synthetic-data/synthetic-data.ipynb index 025efec3..5e42db69 100644 --- a/doc-sources/user-guide/synthetic-data/synthetic-data.ipynb +++ b/doc-sources/user-guide/synthetic-data/synthetic-data.ipynb @@ -14,7 +14,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 57\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 57\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -63,7 +63,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-model problem.yml --random-seed 58 --model-type mrsort\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 58 --model-type mrsort\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", @@ -101,7 +101,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classified-alternatives problem.yml model.yml 100 --random-seed 59 --misclassified-count 0\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 100 --random-seed 59 --misclassified-count 0\n", "name,\"Criterion 1\",\"Criterion 2\",\"Criterion 3\",\"Criterion 4\",category\n", "\"Alternative 1\",0.924035132,0.804616809,0.157870576,0.637420833,\"Best category\"\n", "\"Alternative 2\",0.866915047,0.979161799,0.0841569453,0.397855282,\"Best category\"\n", @@ -224,7 +224,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 60 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 60 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/docs/.buildinfo b/docs/.buildinfo index 23a0d121..52e6e2c1 100644 --- a/docs/.buildinfo +++ b/docs/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 21415a206eb54523072fadedfdf8571f +config: b8cf68fa18ac3570036bef5ce646b33b tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/.doctrees/changelog.doctree b/docs/.doctrees/changelog.doctree index 1d17eaa9..261404de 100644 Binary files a/docs/.doctrees/changelog.doctree and b/docs/.doctrees/changelog.doctree differ diff --git a/docs/.doctrees/conceptual-overview.doctree b/docs/.doctrees/conceptual-overview.doctree index b05c75f4..b55631ce 100644 Binary files a/docs/.doctrees/conceptual-overview.doctree and b/docs/.doctrees/conceptual-overview.doctree differ diff --git a/docs/.doctrees/contributor-guide.doctree b/docs/.doctrees/contributor-guide.doctree index 78ad702d..14dc098b 100644 Binary files a/docs/.doctrees/contributor-guide.doctree and b/docs/.doctrees/contributor-guide.doctree differ diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index a826f545..d7b1744b 100644 Binary files a/docs/.doctrees/environment.pickle and b/docs/.doctrees/environment.pickle differ diff --git a/docs/.doctrees/get-started.doctree b/docs/.doctrees/get-started.doctree index 4c3f82bd..ef1d3797 100644 Binary files a/docs/.doctrees/get-started.doctree and b/docs/.doctrees/get-started.doctree differ diff --git a/docs/.doctrees/reference.doctree b/docs/.doctrees/reference.doctree index b911739a..c5d76b57 100644 Binary files a/docs/.doctrees/reference.doctree and b/docs/.doctrees/reference.doctree differ diff --git a/docs/.doctrees/user-guide.doctree b/docs/.doctrees/user-guide.doctree index cc9648eb..e81e10f3 100644 Binary files a/docs/.doctrees/user-guide.doctree and b/docs/.doctrees/user-guide.doctree differ diff --git a/docs/README.html b/docs/README.html index cfa39cb6..192950a7 100644 --- a/docs/README.html +++ b/docs/README.html @@ -5,11 +5,11 @@ - Contributors — lincs 0.10.3 documentation + Contributors — lincs 0.11.0 documentation - + diff --git a/docs/_downloads/88ec4004d09b5e85c9e1ff9b908b40ad/problem-schema.yml b/docs/_downloads/88ec4004d09b5e85c9e1ff9b908b40ad/problem-schema.yml index 79d94bc8..ab05943b 100644 --- a/docs/_downloads/88ec4004d09b5e85c9e1ff9b908b40ad/problem-schema.yml +++ b/docs/_downloads/88ec4004d09b5e85c9e1ff9b908b40ad/problem-schema.yml @@ -17,13 +17,13 @@ properties: name: type: string value_type: - description: May be extended in the future to handle criteria with integer values, or explicitely enumarated values. + description: May be extended in the future to handle criteria with integer values, or explicitly enumerated values. type: string enum: [real] - category_correlation: - description: May be extended in the future to handle single-peaked criteria, or criteria with unknown correlation. + preference_direction: + description: May be extended in the future to handle single-peaked criteria, or criteria with unknown preference direction. type: string - enum: [growing, decreasing] + enum: [increasing, isotone, decreasing, antitone] min_value: type: number max_value: @@ -31,13 +31,13 @@ properties: required: - name - value_type - - category_correlation + - preference_direction - min_value - max_value additionalProperties: false minItems: 1 - categories: - description: Structural information about categories in the classification problem. + ordered_categories: + description: Structural information about categories in the classification problem, ordered from the worst to the best. type: array items: type: object @@ -52,5 +52,5 @@ required: - kind - format_version - criteria - - categories + - ordered_categories additionalProperties: false diff --git a/docs/_images/alternatives.png b/docs/_images/alternatives.png index 7df2525d..ea23fb0b 100644 Binary files a/docs/_images/alternatives.png and b/docs/_images/alternatives.png differ diff --git a/docs/_images/model.png b/docs/_images/model.png index f823e6a1..2a7db9a0 100644 Binary files a/docs/_images/model.png and b/docs/_images/model.png differ diff --git a/docs/_sources/changelog.rst.txt b/docs/_sources/changelog.rst.txt index 374cf257..192dfc1d 100644 --- a/docs/_sources/changelog.rst.txt +++ b/docs/_sources/changelog.rst.txt @@ -4,6 +4,22 @@ Changelog ========= +Version 0.11.0 +============== + +- **Breaking** Rename ``category_correlation`` to ``preference_direction`` in problem files +- **Breaking** Rename the ``growing`` preference direction to ``increasing`` in problem files +- **Breaking** Rename the ``categories`` attribute in problem files to ``ordered_categories`` in problem files +- Make names of generated categories more explicit ("Worst category", "Intermediate category N", "Best category") +- Support ``isotone`` (resp. ``antitone``) as a synonym for ``increasing`` (resp. ``decreasing``) in problem files +- Add ``lincs describe`` command to produce human-readable descriptions of problems and models +- **Remove** comments about termination conditions from learned models, but: +- Add ``--mrsort.weights-profiles-breed.output-metadata`` to generate in YAML the data previously found in those comments +- Provide a Jupyter notebook to help follow the "Get Started" guide (and use Jupyter for all integration tests) +- Document the "externally managed" error on Ubuntu 23.4+ + +(In versions below, the term "category correlation" was used instead of "preference direction".) + Versions 0.10.0 to 0.10.3 ========================= diff --git a/docs/_sources/conceptual-overview.rst.txt b/docs/_sources/conceptual-overview.rst.txt index acbf6bf9..0e600e25 100644 --- a/docs/_sources/conceptual-overview.rst.txt +++ b/docs/_sources/conceptual-overview.rst.txt @@ -152,76 +152,6 @@ You can check that the constraints of NCS models are satisfied: The profiles for this model look like this: -.. START concept-example/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - lincs visualize classification-model problem.yml model.yml concept-example-model.png - cp concept-example-model.png ../../../../doc-sources - - lincs classify problem.yml model.yml alternatives.csv --output-alternatives classified-alternatives.csv - diff classified-alternatives.csv expected-classified-alternatives.csv -.. STOP - -.. START concept-example/problem.yml - kind: classification-problem - format_version: 1 - criteria: - - name: Math - value_type: real - category_correlation: growing - min_value: 0 - max_value: 1 - - name: Physics - value_type: real - category_correlation: growing - min_value: 0 - max_value: 1 - - name: Literature - value_type: real - category_correlation: growing - min_value: 0 - max_value: 1 - - name: History - value_type: real - category_correlation: growing - min_value: 0 - max_value: 1 - categories: - - name: No scholarship - - name: Partial scholarship - - name: Full scholarship -.. STOP - -.. START concept-example/model.yml - kind: ncs-classification-model - format_version: 1 - accepted_values: - - kind: thresholds - thresholds: [0.6, 0.75] - - kind: thresholds - thresholds: [0.55, 0.9] - - kind: thresholds - thresholds: [0.7, 0.8] - - kind: thresholds - thresholds: [0.5, 0.65] - sufficient_coalitions: - - kind: roots - upset_roots: - - [0, 2] - - [1, 2] - - [0, 3] - - [1, 3] - - kind: roots - upset_roots: - - [0, 1, 2] - - [0, 1, 3] - - [0, 2, 3] - - [1, 2, 3] -.. STOP - .. image:: concept-example-model.png :alt: Model visualization :align: center @@ -353,25 +283,6 @@ If this set is in :math:`\mathcal{F}^2`, then they get a full scholarship. Else, we then check if the set of criteria where they get grades above :math:`b^1` is in :math:`\mathcal{F}^1`. If yes, they get a partial scholarship. -.. START concept-example/alternatives.csv - name,Math,Physics,Literature,History,category - A,1,1,1,1, - B,1,1,1,0, - C,0.8,0.7,0.85,0.6, - D,1,0,1,0, - E,1,1,0,0, -.. STOP - -.. START concept-example/expected-classified-alternatives.csv - # Reproduction command (with lincs version 0.10.3): lincs classify problem.yml model.yml alternatives.csv - name,Math,Physics,Literature,History,category - A,1,1,1,1,"Full scholarship" - B,1,1,1,0,"Full scholarship" - C,0.800000012,0.699999988,0.850000024,0.600000024,"Partial scholarship" - D,1,0,1,0,"Partial scholarship" - E,1,1,0,0,"No scholarship" -.. STOP - ======= ============================================ ====================== ======================== =============================== ======================== =========== Student Grades Above :math:`b^2` In :math:`\mathcal{F}^2` Above :math:`b^1` In :math:`\mathcal{F}^1` Scholarship ======= ============================================ ====================== ======================== =============================== ======================== =========== diff --git a/docs/_sources/contributor-guide.rst.txt b/docs/_sources/contributor-guide.rst.txt index cb044c79..3c82b585 100644 --- a/docs/_sources/contributor-guide.rst.txt +++ b/docs/_sources/contributor-guide.rst.txt @@ -128,104 +128,7 @@ Examples: But beware of virtual function calls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. START virtual-cost/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - g++ -c -O3 lib.cpp -o lib.o - g++ -O3 no-virtual.cpp lib.o -o no-virtual - g++ -O3 yes-virtual.cpp lib.o -o yes-virtual - - time ./no-virtual - time ./yes-virtual -.. STOP - -.. highlight:: c++ - -.. details:: Virtual function calls are costly (click for details) - - .. START virtual-cost/lib.hpp - - Given these classes:: - - class Foo { - public: - virtual void yes_virtual() = 0; - void no_virtual(); - }; - - class ActualFoo : public Foo { - public: - void yes_virtual() override; - }; - - .. STOP - - .. EXTEND virtual-cost/lib.hpp - Foo* makeFoo(); - .. STOP - - .. START virtual-cost/lib.cpp - #include "lib.hpp" - .. STOP - - .. EXTEND virtual-cost/lib.cpp - - And functions:: - - void Foo::no_virtual() {} - void ActualFoo::yes_virtual() {} - - Foo* makeFoo() { return new ActualFoo; } - - .. STOP - - .. START virtual-cost/no-virtual.cpp - #include "lib.hpp" - - int main() { - .. STOP - - .. EXTEND virtual-cost/no-virtual.cpp - - The following code runs in ~0.93s:: - - Foo* foo = makeFoo(); - - for (int i = 0; i != 1'000'000'000; ++i) { - foo->no_virtual(); - } - - .. STOP - - .. EXTEND virtual-cost/no-virtual.cpp - } - .. STOP - - .. START virtual-cost/yes-virtual.cpp - #include "lib.hpp" - - int main() { - .. STOP - - .. EXTEND virtual-cost/yes-virtual.cpp - - And the following code runs in ~1.12s:: - - Foo* foo = makeFoo(); - for (int i = 0; i != 1'000'000'000; ++i) { - foo->yes_virtual(); - } - - .. STOP - - .. EXTEND virtual-cost/yes-virtual.cpp - } - .. STOP - -So, although virtual function calls are useful, they must be used with care. +Virtual function calls are somewhat costly (see ``integration-tests/virtual-cost``) so, although they are useful, they must be used with care. It's best to keep them for cases where they are not called too often; up to a few thousands per learning should be OK. When polymorphism is required for frequent calls, it's best to use template-based static polymorphism. @@ -238,7 +141,7 @@ So, why not all templates? One could now consider using templates everywhere, and not use virtual function calls at all. This would have the following negative consequences: -The number of explicit template instantiations would explode incombinatorially. +The number of explicit template instantiations would explode in a combinatorial way. For example, the ``LinearProgram`` template parameter of ``.../optimize-weights/linear-program.hpp`` is currently instantiated explicitly for each LP solver in ``.../optimize-weights/linear-program.cpp``. If ``LearnMrsortByWeightsProfilesBreed`` was a template, it would have to be instantiated for the whole Cartesian product of all variants of each strategy, to a great maintenance cost. Note that this is not specific to explicit template instanciation, because we expose *lincs* as a Python library: diff --git a/docs/_sources/get-started.rst.txt b/docs/_sources/get-started.rst.txt index 9fe71b82..72363775 100644 --- a/docs/_sources/get-started.rst.txt +++ b/docs/_sources/get-started.rst.txt @@ -1,3 +1,5 @@ +.. WARNING: this file is generated from 'doc-sources/get-started.rst.tmpl'. MANUAL EDITS WILL BE LOST. + .. Copyright 2023 Vincent Jacques =========== @@ -11,6 +13,9 @@ Get *lincs* We provide binary wheels for *lincs* on Linux, Windows and macOS for x86_64 processors, so running ``pip install lincs --only-binary lincs`` should be enough on those systems. +We generally recommend you use ``pip`` in a virtual environment (``python -m venv``) or directly ``pipx`` to install any package, including *lincs*. +Recent Ubuntu systems will even enforce that, by `refusing to install PyPI packages `_ in the "externally managed" default environment. + If you're on a platform for which we don't make wheels, you'll need to build *lincs* from sources. We don't recommend you do that, because it can be a lot of work. If you really want to go that route, you may want to start by reading the `GitHub Actions workflow `_ we use to build the binary wheels. @@ -22,127 +27,112 @@ If you end up modifying *lincs* to make it work on your platform, we kindly ask Start using *lincs*' command-line interface =========================================== -.. START help/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - lincs --help >actual-help.txt - diff expected-help.txt actual-help.txt -.. STOP - -.. START help/expected-help.txt +If you're a Jupyter user, you can `download the notebook `_ this section is based on. .. highlight:: text The command-line interface is the easiest way to get started with *lincs*, starting with ``lincs --help``, which should output something like:: Usage: lincs [OPTIONS] COMMAND [ARGS]... - + lincs (Learn and Infer Non-Compensatory Sorting) is a set of tools for training and using MCDA models. - + Options: --version Show the version and exit. --help Show this message and exit. - + Commands: classification-accuracy Compute a classification accuracy. classify Classify alternatives. + describe Provide human-readable descriptions. generate Generate synthetic data. info Get information about lincs itself. learn Learn a model. visualize Make graphs from data. -.. STOP It's organized into sub-commands, the first one being ``generate``, to generate synthetic pseudo-random data. *lincs* is designed to handle real-world data, but it's often easier to start with synthetic data to get familiar with the tooling and required file formats. Synthetic data is described in our :ref:`conceptual overview documentation `. -.. START command-line-example/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR -.. STOP - .. highlight:: shell -.. EXTEND command-line-example/run.sh - So, start by generating a classification problem with 4 criteria and 3 categories:: lincs generate classification-problem 4 3 --output-problem problem.yml -.. APPEND-TO-LAST-LINE --random-seed 40 -.. STOP .. highlight:: yaml -.. START command-line-example/expected-problem.yml - The generated ``problem.yml`` should look like:: - # Reproduction command (with lincs version 0.10.3): lincs generate classification-problem 4 3 --random-seed 40 + # Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 40 kind: classification-problem format_version: 1 criteria: - name: Criterion 1 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 1 - name: Criterion 2 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 1 - name: Criterion 3 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 1 - name: Criterion 4 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 1 - categories: - - name: Category 1 - - name: Category 2 - - name: Category 3 + ordered_categories: + - name: Worst category + - name: Intermediate category 1 + - name: Best category -.. STOP You can edit this file to change the criteria names, the number of categories, *etc.* as long as you keep the same format. That format is explained in details in our :ref:`user guide `. The concept of "classification problem" is described in our :ref:`conceptual overview documentation `. -.. EXTEND command-line-example/run.sh - diff expected-problem.yml problem.yml -.. STOP +If you want a human-readable explanation of the problem, you can use:: -.. highlight:: shell + lincs describe classification-problem problem.yml -.. EXTEND command-line-example/run.sh +It will tell you something like:: + + This a classification problem into 3 ordered categories named "Worst category", "Intermediate category 1" and "Best category". + The best category is "Best category" and the worst category is "Worst category". + There are 4 classification criteria (in no particular order). + Criterion "Criterion 1" takes real values between 0.0 and 1.0 included. + Higher values of "Criterion 1" are known to be better. + Criterion "Criterion 2" takes real values between 0.0 and 1.0 included. + Higher values of "Criterion 2" are known to be better. + Criterion "Criterion 3" takes real values between 0.0 and 1.0 included. + Higher values of "Criterion 3" are known to be better. + Criterion "Criterion 4" takes real values between 0.0 and 1.0 included. + Higher values of "Criterion 4" are known to be better. + + +.. highlight:: shell Then generate an NCS classification model:: lincs generate classification-model problem.yml --output-model model.yml -.. APPEND-TO-LAST-LINE --random-seed 41 -.. STOP .. highlight:: yaml -.. START command-line-example/expected-model.yml - It should look like:: - # Reproduction command (with lincs version 0.10.3): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort + # Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort kind: ncs-classification-model format_version: 1 accepted_values: @@ -160,27 +150,15 @@ It should look like:: criterion_weights: [0.147771254, 0.618687689, 0.406786472, 0.0960085914] - *coalitions -.. STOP The file format, including the ``*coalitions`` YAML reference, is documented in our :ref:`user guide `. -.. EXTEND command-line-example/run.sh - diff expected-model.yml model.yml -.. STOP - .. highlight:: shell -.. EXTEND command-line-example/run.sh - You can visualize it using:: lincs visualize classification-model problem.yml model.yml model.png -.. STOP - -.. EXTEND command-line-example/run.sh - cp model.png ../../../../doc-sources -.. STOP It should output something like: @@ -188,14 +166,28 @@ It should output something like: :alt: Model visualization :align: center -.. EXTEND command-line-example/run.sh +The model format is quite generic to ensure *lincs* can evolve to handle future models, +so you may want to get a human-readable description of a model, including wether it's an MR-Sort or Uc-NCS model, using:: + + lincs describe classification-model problem.yml model.yml + +It should output something like:: + + This is a MR-Sort (a.k.a. 1-Uc-NCS) model: an NCS model where the sufficient coalitions are specified using the same criterion weights for all boundaries. + The weights associated to each criterion are: + - Criterion "Criterion 1": 0.15 + - Criterion "Criterion 2": 0.62 + - Criterion "Criterion 3": 0.41 + - Criterion "Criterion 4": 0.10 + To get into an upper category, an alternative must be better than the following profiles on a set of criteria whose weights add up to at least 1: + - For category "Intermediate category 1": at least 0.26 on criterion "Criterion 1", at least 0.06 on criterion "Criterion 2", at least 0.16 on criterion "Criterion 3", and at least 0.05 on criterion "Criterion 4" + - For category "Best category": at least 0.68 on criterion "Criterion 1", at least 0.32 on criterion "Criterion 2", at least 0.67 on criterion "Criterion 3", and at least 0.60 on criterion "Criterion 4" + And finally generate a set of classified alternatives:: lincs generate classified-alternatives problem.yml model.yml 1000 --output-alternatives learning-set.csv -.. APPEND-TO-LAST-LINE --random-seed 42 -.. STOP The file format is documented in our :ref:`reference documentation `. @@ -205,37 +197,23 @@ Then we'll need to think about the how the ``--max-imbalance`` option interacts .. highlight:: text -.. START command-line-example/expected-learning-set.csv - It should start with something like this, and contain 1000 alternatives:: - # Reproduction command (with lincs version 0.10.3): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0 + # Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0 name,"Criterion 1","Criterion 2","Criterion 3","Criterion 4",category - "Alternative 1",0.37454012,0.796543002,0.95071429,0.183434784,"Category 3" - "Alternative 2",0.731993914,0.779690981,0.598658502,0.596850157,"Category 2" - "Alternative 3",0.156018645,0.445832759,0.15599452,0.0999749228,"Category 1" - "Alternative 4",0.0580836125,0.4592489,0.866176128,0.333708614,"Category 3" - "Alternative 5",0.601114988,0.14286682,0.708072603,0.650888503,"Category 2" + "Alternative 1",0.37454012,0.796543002,0.95071429,0.183434784,"Best category" + "Alternative 2",0.731993914,0.779690981,0.598658502,0.596850157,"Intermediate category 1" + "Alternative 3",0.156018645,0.445832759,0.15599452,0.0999749228,"Worst category" + "Alternative 4",0.0580836125,0.4592489,0.866176128,0.333708614,"Best category" + "Alternative 5",0.601114988,0.14286682,0.708072603,0.650888503,"Intermediate category 1" -.. STOP - -.. EXTEND command-line-example/run.sh - diff expected-learning-set.csv <(head -n 7 learning-set.csv) -.. STOP .. highlight:: shell -.. EXTEND command-line-example/run.sh - You can visualize its first five alternatives using:: lincs visualize classification-model problem.yml model.yml --alternatives learning-set.csv --alternatives-count 5 alternatives.png -.. STOP - -.. EXTEND command-line-example/run.sh - cp alternatives.png ../../../../doc-sources -.. STOP It should output something like: @@ -247,27 +225,19 @@ It should output something like: .. highlight:: shell -.. EXTEND command-line-example/run.sh - You now have a (synthetic) learning set. You can use it to train a new model:: lincs learn classification-model problem.yml learning-set.csv --output-model trained-model.yml -.. APPEND-TO-LAST-LINE --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 -.. STOP .. highlight:: yaml -.. START command-line-example/expected-trained-model.yml - The trained model has the same structure as the original (synthetic) model because they are both MR-Sort models for the same problem. The learning set doesn't contain all the information from the original model, and the trained model was reconstituted from this partial information, so it is numerically different:: - # Reproduction command (with lincs version 0.10.3): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0 - # Termination condition: target accuracy reached - # Number of iterations: 22 + # Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0 kind: ncs-classification-model format_version: 1 accepted_values: @@ -285,100 +255,63 @@ so it is numerically different:: criterion_weights: [0, 1.01327896e-06, 0.999998987, 0] - *coalitions -.. STOP - -.. EXTEND command-line-example/run.sh - diff expected-trained-model.yml trained-model.yml -.. STOP If the training is effective, the resulting trained model should however behave closely to the original one. To see how close a trained model is to the original one, you can reclassify a testing set. .. highlight:: shell -.. EXTEND command-line-example/run.sh - First, generate a testing set from the original model:: lincs generate classified-alternatives problem.yml model.yml 3000 --output-alternatives testing-set.csv -.. APPEND-TO-LAST-LINE --random-seed 44 -.. STOP - .. highlight:: shell -.. EXTEND command-line-example/run.sh - Then ask the trained model to classify it:: lincs classify problem.yml trained-model.yml testing-set.csv --output-alternatives reclassified-testing-set.csv -.. STOP .. highlight:: shell -.. EXTEND command-line-example/run.sh - There are a few differences between the original testing set and the reclassified one:: diff testing-set.csv reclassified-testing-set.csv -.. APPEND-TO-LAST-LINE | tail -n +5 >classification-diff.txt || true -.. STOP - .. highlight:: diff -.. START command-line-example/expected-classification-diff.txt - That command should show a few alternatives that are not classified the same way by the original and the trained model:: 522c522 - < "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Category 3" + < "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Best category" --- - > "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Category 2" + > "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Intermediate category 1" 615c615 - < "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Category 2" + < "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Intermediate category 1" --- - > "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Category 1" + > "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Worst category" 2596c2596 - < "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Category 2" + < "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Intermediate category 1" --- - > "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Category 1" + > "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Worst category" 2610c2610 - < "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Category 2" + < "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Intermediate category 1" --- - > "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Category 1" + > "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Worst category" -.. STOP - -.. EXTEND command-line-example/run.sh - diff expected-classification-diff.txt classification-diff.txt -.. STOP .. highlight:: shell -.. EXTEND command-line-example/run.sh - You can also measure the classification accuracy of the trained model on that testing set:: lincs classification-accuracy problem.yml trained-model.yml testing-set.csv -.. APPEND-TO-LAST-LINE >classification-accuracy.txt -.. STOP - -.. START command-line-example/expected-classification-accuracy.txt - .. highlight:: text It should be close to 100%:: 2996/3000 -.. STOP - -.. EXTEND command-line-example/run.sh - diff expected-classification-accuracy.txt classification-accuracy.txt -.. STOP What now? diff --git a/docs/_sources/user-guide.rst.txt b/docs/_sources/user-guide.rst.txt index 540eca33..ffa6adcc 100644 --- a/docs/_sources/user-guide.rst.txt +++ b/docs/_sources/user-guide.rst.txt @@ -1,3 +1,5 @@ +.. WARNING: this file is generated from 'doc-sources/user-guide.rst.tmpl'. MANUAL EDITS WILL BE LOST. + .. Copyright 2023 Vincent Jacques ========== @@ -23,24 +25,6 @@ Formatting data for *lincs* The concept of classification problem is defined in our :ref:`conceptual overview `. To describe problems, *lincs* uses YAML files conforming to the `JSON schema `_ you'll find in our :ref:`reference documentation `. -.. START file-formats/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - lincs generate classification-model problem.yml --random-seed 42 --output-model mrsort-model.yml - diff <(tail -n +2 mrsort-model.yml) expected-mrsort-model.yml - - # Check that the NCS model is correct (we don't have explicit commands for that, so we use generate classified-alternatives) - lincs generate classified-alternatives problem.yml ncs-model.yml 1 >/dev/null - - lincs classify problem.yml mrsort-model.yml unclassified-alternatives.csv --output-alternatives classified-alternatives.csv - diff <(tail -n +2 classified-alternatives.csv) expected-classified-alternatives.csv -.. STOP - -.. START file-formats/problem.yml - Here is an example of a problem file:: kind: classification-problem @@ -48,20 +32,19 @@ Here is an example of a problem file:: criteria: - name: Criterion 1 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 20 - name: Criterion 2 value_type: real - category_correlation: decreasing + preference_direction: decreasing min_value: -5 max_value: 5 - categories: + ordered_categories: - name: Low - name: Medium - name: High -.. STOP The two first keys, ``kind`` and ``format_version`` are here to identify exactly the file format. For now, they must always be set to ``classification-problem`` and ``1`` respectively. @@ -77,13 +60,13 @@ Each criterion has a ``name``. Currently, criteria can only take floating point values, so their ``value_type`` is always ``real``. We expect this could evolve to also support criteria with integer or explicitly enumerated values. -Then, the ``category_correlation`` key describe what makes "good values" for this criterion. -If it is ``growing`` (resp. ``decreasing``), then higher (resp. lower) numerical values correspond to upper categories. -Note that this correlation comes from expert knowledge about the structure of the problem, +Then, the ``preference_direction`` key describe what makes "good values" for this criterion. +If it is ``increasing`` (resp. ``decreasing``), then higher (resp. lower) numerical values correspond to upper categories. +Note that this preference direction comes from expert knowledge about the structure of the problem, and will be used as an absolute truth when learning a model for this problem. -We expect the supported correlations could evolve to also support criteria with single-peaked correlation, +We expect the supported preference directions could evolve to also support single-peaked criteria, where intermediate numerical value correspond to upper categories, and extreme values to lower categories. -We also expect this could evolve to support criteria with unknown correlation, +We also expect this could evolve to support criteria with unknown preference direction, to support the case where no expert knowledge is available and delegate this choice to the learning process. Finally, for criteria with numerical ``value_type`` (currently all of them), @@ -114,8 +97,6 @@ referencing the problem file by name would not be robust because files can be re and referencing the problem file by content (using a hash) would forbid any change in the problem file. So it's the user's responsibility to keep track of that information and always give *lincs* the correct problem file along with a model file. -.. START file-formats/expected-mrsort-model.yml - Here is an example of a model file corresponding to the problem file above:: kind: ncs-classification-model @@ -131,7 +112,6 @@ Here is an example of a model file corresponding to the problem file above:: criterion_weights: [0.938825667, 0.343733728] - *coalitions -.. STOP Like for problem files, the two first keys must take exactly these values. @@ -149,21 +129,21 @@ For such a criterion, the determination of the accepted values will require two So our file format takes an transposed approach and focusses on criteria instead of profiles: for each criterion, it describes the method used to accept values at different category levels. -For current criteria (with ``growing`` or ``decreasing`` correlation), the method is always ``kind: thresholds``, +For current criteria (with ``increasing`` or ``decreasing`` preference direction), the method is always ``kind: thresholds``, and the ``thresholds`` attribute lists the successive values required to enter an upper category. It must have as many elements as there are boundaries between categories, *i.e.* as there are categories minus one. -It's always sorted, in increasing order for ``growing`` criteria and in decreasing order for ``decreasing`` criteria. +It's always sorted, in increasing order for ``increasing`` criteria and in decreasing order for ``decreasing`` criteria. Note that this list is not a profile: it does not describe the limits between categories. The matrix made of these lists is the transposed of the matrix made of the profiles. -When we support criteria with single-peaked or unknown correlation, +When we support single-peaked criteria or criteria with unknown preference direction, we'll introduce other ``kinds`` of accepted values with new attributes instead of ``thresholds``. ================================== ======================== ========================== -Criterion ``category_correlation`` Accepted values ``kind`` Accepted values attributes +Criterion ``preference_direction`` Accepted values ``kind`` Accepted values attributes ================================== ======================== ========================== -``growing`` ``thresholds`` ``thresholds`` +``increasing`` ``thresholds`` ``thresholds`` ``decreasing`` ``thresholds`` ``thresholds`` ================================== ======================== ========================== @@ -195,8 +175,6 @@ Sufficient coalitions ``kind`` Sufficient coalitions attributes ``roots`` ``upset_roots`` ============================== ================================ -.. START file-formats/ncs-model.yml - Here is another model corresponding to the problem file above, but this time using the ``roots`` kind of sufficient coalitions, and using different coalitions for the two boundaries (so, no YAML anchor):: @@ -215,7 +193,6 @@ and using different coalitions for the two boundaries (so, no YAML anchor):: upset_roots: - [0, 1] -.. STOP "Alternatives" files -------------------- @@ -227,8 +204,6 @@ Like model files, alternatives files are always associated to a problem file. .. highlight:: text -.. START file-formats/expected-classified-alternatives.csv - Here is an example corresponding to the problem above:: name,"Criterion 1","Criterion 2",category @@ -238,15 +213,12 @@ Here is an example corresponding to the problem above:: "Alternative 4",18.0154629,1.33949804,Medium "Alternative 5",9.30789757,2.66963387,Medium -.. STOP Its header line contains the names of its columns. Its first column, ``name``, contains the names of the alternatives. Its intermediate columns, named after the names of criteria, contain the values of the criteria for each alternative. Its last column, ``category``, contains the names of the categories in which each alternative is classified. -.. START file-formats/unclassified-alternatives.csv - Values in the ``category`` column can be empty to describe alternatives that are not (yet) classified:: name,"Criterion 1","Criterion 2",category @@ -256,7 +228,6 @@ Values in the ``category`` column can be empty to describe alternatives that are "Alternative 4",18.0154629,1.33949804, "Alternative 5",9.30789757,2.66963387, -.. STOP .. _user-comments-in-generated-files: @@ -294,39 +265,25 @@ In all cases, the :ref:`comments ` left by *li Generating a problem -------------------- -.. START synthetic-data/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - With ``lincs generate classification-problem``, you can generate a classification problem file. Using its default settings, you just have to pass it the numbers of criteria and categories you want, as you saw in our :doc:`get started guide `:: lincs generate classification-problem 4 3 -.. APPEND-TO-LAST-LINE --output-problem problem.yml -.. STOP - The ``--help`` option on the command-line and our :ref:`reference documentation ` describe the options available to tweak the generated problem. Most notably: - ``--denormalized-min-max`` generates problems with pseudo-random ``min_value`` and ``max_value`` for each criterion. By default, they are always set at 0 and 1. -- ``--allow-decreasing-criteria`` chooses pseudo-randomly the ``category_corelation`` of each criterion between ``growing`` and ``decreasing``. By default, all criteria have ``growing`` correlation. +- ``--allow-decreasing-criteria`` chooses pseudo-randomly the ``preference_direction`` of each criterion between ``increasing`` and ``decreasing``. By default, all criteria have ``increasing`` preference direction. Generating a model ------------------ -.. EXTEND synthetic-data/run.sh - With ``lincs generate classification-model``, you can generate a classification model file. Using its default settings, you just have to pass it the problem file you want to use:: lincs generate classification-model problem.yml -.. APPEND-TO-LAST-LINE --output-model model.yml -.. STOP - For now, *lincs* can only generate MR-Sort models, so the ``--model-type`` option can only take its default value: ``mrsort``. We expect this could change if we implement the generation of other types of models. @@ -337,15 +294,10 @@ This effectively impacts how hard it is for alternatives to get into upper categ Generating alternatives ----------------------- -.. EXTEND synthetic-data/run.sh - With its default settings, ``lincs generate classified-alternatives`` requires only the problem and model files and the number of alternatives to generate:: lincs generate classified-alternatives problem.yml model.yml 100 -.. APPEND-TO-LAST-LINE --output-alternatives learning-set.csv -.. STOP - This generates 100 random alternatives, and then classifies them according to the model. By default, no effort is made to balance the number of alternatives in each category. @@ -370,16 +322,11 @@ After alternatives are generated and classified, this option randomly selects th Learning a model ================ -.. EXTEND synthetic-data/run.sh - As you've seen in our get started guide, the basic command to learn a classification model with *lincs* is ``lincs learn classification-model``. With its default settings, you just have to pass it a problem file and a learning set file (of classified alternatives):: lincs learn classification-model problem.yml learning-set.csv -.. APPEND-TO-LAST-LINE --output-model learned-model.yml -.. STOP - Its ``--help`` option and our reference documentation give you a list of the numerous options it accepts. An whole tree of options @@ -440,6 +387,9 @@ Or maybe a small multiple of that number. The ``--mrsort.weights-profiles-breed.verbose`` option can be used to make *lincs* display information about the progress of the learning. +The ``--mrsort.weights-profiles-breed.output-metadata`` options can be used to produce a YAML file giving information about the learning process: +the reason it stopped (accuracy reached, time limit, *etc.*), how many WPB iterations it took, *etc.* + Termination ........... @@ -462,50 +412,13 @@ That strategy uses a linear program, and lets you choose among several solvers w By default, it uses GLOP, which is a part of `Google's OR-Tools `_. -.. START alglib-learning/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - cp ../../get-started/command-line-example/{problem.yml,learning-set.csv} . - Here is an example using the `Alglib `_ solver:: lincs learn classification-model problem.yml learning-set.csv \ --mrsort.weights-profiles-breed.linear-program.solver alglib -.. APPEND-TO-LAST-LINE --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 -.. APPEND-TO-LAST-LINE --output-model alglib-trained-model.yml - - diff expected-alglib-trained-model.yml alglib-trained-model.yml - -.. STOP - It should produce a very similar model, with slight numerical differences. -.. START alglib-learning/expected-alglib-trained-model.yml - # Reproduction command (with lincs version 0.10.3): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver alglib --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0 - # Termination condition: target accuracy reached - # Number of iterations: 9 - kind: ncs-classification-model - format_version: 1 - accepted_values: - - kind: thresholds - thresholds: [0.924693644, 0.971395075] - - kind: thresholds - thresholds: [0.0556534864, 0.326433569] - - kind: thresholds - thresholds: [0.162616938, 0.671892762] - - kind: thresholds - thresholds: [0.942387044, 0.988728762] - sufficient_coalitions: - - &coalitions - kind: weights - criterion_weights: [0.293799639, 0.386859566, 0.613140464, 0.304567546] - - *coalitions -.. STOP - "Profiles" step ............... @@ -521,32 +434,11 @@ This is the case for example on macOS, where CUDA is not supported. Binary wheels for Linux and Windows do support it though. You can check with ``lincs info has-gpu``. -.. START gpu-learning/uses-gpu -.. STOP - -.. START gpu-learning/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - cp ../../get-started/command-line-example/{problem.yml,learning-set.csv} . - cp ../../get-started/command-line-example/expected-trained-model.yml . - - diff <(echo "lincs was compiled with CUDA support") <(lincs info has-gpu) - Here is an example:: lincs learn classification-model problem.yml learning-set.csv \ --mrsort.weights-profiles-breed.accuracy-heuristic.processor gpu -.. APPEND-TO-LAST-LINE --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 -.. APPEND-TO-LAST-LINE --output-model gpu-trained-model.yml - - diff <(sed s/cpu/gpu/ expected-trained-model.yml) gpu-trained-model.yml - -.. STOP - If you specify the random seed, it will produce the exact same model as when using the CPU; this is an important feature of *lincs*, that the GPU code has the same behavior as the CPU code. @@ -563,14 +455,6 @@ SAT-based strategies .. highlight:: shell -.. START sat-learnings/run.sh - set -o errexit - set -o nounset - set -o pipefail - trap 'echo "Error on line $LINENO"' ERR - - cp ../../get-started/command-line-example/{problem.yml,learning-set.csv} . - You can also use entirely different approaches using SAT and max-SAT solvers. The tradeoffs offered by these methods are highlighted in our :ref:`conceptual overview `. @@ -580,28 +464,16 @@ Here are two examples:: lincs learn classification-model problem.yml learning-set.csv \ --model-type ucncs --ucncs.strategy sat-by-coalitions -.. APPEND-TO-LAST-LINE --output-model sat-by-coalitions-trained-model.yml - And:: lincs learn classification-model problem.yml learning-set.csv \ --model-type ucncs --ucncs.strategy max-sat-by-separation -.. APPEND-TO-LAST-LINE --output-model max-sat-by-separation-trained-model.yml - -.. - diff expected-sat-by-coalitions-trained-model.yml sat-by-coalitions-trained-model.yml - diff expected-max-sat-by-separation-trained-model.yml max-sat-by-separation-trained-model.yml - -.. STOP - .. highlight:: yaml -.. START sat-learnings/expected-sat-by-coalitions-trained-model.yml - They produce a different kind of model, with the sufficient coalitions specified explicitly by their roots:: - # Reproduction command (with lincs version 0.10.3): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions + # Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions kind: ncs-classification-model format_version: 1 accepted_values: @@ -620,29 +492,6 @@ They produce a different kind of model, with the sufficient coalitions specified - [1, 2] - *coalitions -.. STOP - -.. START sat-learnings/expected-max-sat-by-separation-trained-model.yml - # Reproduction command (with lincs version 0.10.3): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy max-sat-by-separation - kind: ncs-classification-model - format_version: 1 - accepted_values: - - kind: thresholds - thresholds: [0.944162905, 0.944440365] - - kind: thresholds - thresholds: [0.0552680492, 0.325211823] - - kind: thresholds - thresholds: [0.161919117, 0.672662616] - - kind: thresholds - thresholds: [0.000378949801, 0.224962443] - sufficient_coalitions: - - &coalitions - kind: roots - upset_roots: - - [1, 2] - - *coalitions -.. STOP - Using a model ============= @@ -667,6 +516,12 @@ In that case, the ``category`` column must be populated as it serves as a refere That command displays the number of alternatives that were correctly classified and the total number of alternatives in the learning set. +Getting human-readable information about a problem or model +----------------------------------------------------------- + +You can use ``lincs describe classification-problem problem.yml`` to get a human-readable description of a problem, +and ``lincs describe classification-model problem.yml model.yml`` to get one for a model, including wether it's an MR-Sort or Uc-NCS model. + Visualizing a model and alternatives ------------------------------------ diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js index 06c0c5e5..9dc22d64 100644 --- a/docs/_static/documentation_options.js +++ b/docs/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '0.10.3', + VERSION: '0.11.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/changelog.html b/docs/changelog.html index fcdc4cb0..86fbcf71 100644 --- a/docs/changelog.html +++ b/docs/changelog.html @@ -5,11 +5,11 @@ - Changelog — lincs 0.10.3 documentation + Changelog — lincs 0.11.0 documentation - + @@ -34,6 +34,22 @@

Changelog

+
+

Version 0.11.0

+
    +
  • Breaking Rename category_correlation to preference_direction in problem files

  • +
  • Breaking Rename the growing preference direction to increasing in problem files

  • +
  • Breaking Rename the categories attribute in problem files to ordered_categories in problem files

  • +
  • Make names of generated categories more explicit (“Worst category”, “Intermediate category N”, “Best category”)

  • +
  • Support isotone (resp. antitone) as a synonym for increasing (resp. decreasing) in problem files

  • +
  • Add lincs describe command to produce human-readable descriptions of problems and models

  • +
  • Remove comments about termination conditions from learned models, but:

  • +
  • Add --mrsort.weights-profiles-breed.output-metadata to generate in YAML the data previously found in those comments

  • +
  • Provide a Jupyter notebook to help follow the “Get Started” guide (and use Jupyter for all integration tests)

  • +
  • Document the “externally managed” error on Ubuntu 23.4+

  • +
+

(In versions below, the term “category correlation” was used instead of “preference direction”.)

+

Versions 0.10.0 to 0.10.3

This is the first release candidate for version 1.0.0.

@@ -268,6 +284,7 @@

Navigation

  • Reference
  • Contributor guide
  • Changelog
      +
    • Version 0.11.0
    • Versions 0.10.0 to 0.10.3
    • Versions 0.9.0 to 0.9.2
    • Version 0.8.7
    • diff --git a/docs/conceptual-overview.html b/docs/conceptual-overview.html index a4b2d131..412e9cf0 100644 --- a/docs/conceptual-overview.html +++ b/docs/conceptual-overview.html @@ -5,11 +5,11 @@ - Conceptual overview — lincs 0.10.3 documentation + Conceptual overview — lincs 0.11.0 documentation - + diff --git a/docs/contributor-guide.html b/docs/contributor-guide.html index 8143c2f5..b0c2db75 100644 --- a/docs/contributor-guide.html +++ b/docs/contributor-guide.html @@ -5,11 +5,11 @@ - Contributor guide — lincs 0.10.3 documentation + Contributor guide — lincs 0.11.0 documentation - + @@ -112,21 +112,33 @@

      ./run-development-cycle.sh -
      ---skip-long
      -

      Skip long tests to save time. Implies –single-python-version. Please run the full development cycle at least once before submitting your changes.

      +
      +--skip-unit
      +

      Skip unit tests to save time.

      -
      ---skip-unit
      -

      Skip unit tests to save time. Please run the full development cycle at least once before submitting your changes.

      +
      +--skip-long-unit
      +

      Skip long unit tests to save time.

      +
      + +
      +
      +--skip-cpp-unit
      +

      Skip C++ unit tests to save time.

      +
      + +
      +
      +--skip-notebooks
      +

      Skip notebooks to save time.

      -
      ---stop-after-unit
      -

      Stop before integration tests to save time. Please run the full development cycle at least once before submitting your changes.

      +
      +--skip-unchanged-notebooks
      +

      Skip notebooks that have no ‘git diff’ to save time.

      @@ -155,6 +167,12 @@

      ./publish.sh
      ./publish.sh [OPTIONS] {patch|minor|major}
       
      +

      Options

      +
      +
      +--dry-run
      +
      +

      Arguments

      @@ -203,44 +221,7 @@

      Strategies

      But beware of virtual function calls

      -
      - -Virtual function calls are costly (click for details)

      Given these classes:

      -
      class Foo {
      - public:
      -  virtual void yes_virtual() = 0;
      -  void no_virtual();
      -};
      -
      -class ActualFoo : public Foo {
      - public:
      -  void yes_virtual() override;
      -};
      -
      -
      -

      And functions:

      -
      void Foo::no_virtual() {}
      -void ActualFoo::yes_virtual() {}
      -
      -Foo* makeFoo() { return new ActualFoo; }
      -
      -
      -

      The following code runs in ~0.93s:

      -
      Foo* foo = makeFoo();
      -
      -for (int i = 0; i != 1'000'000'000; ++i) {
      -  foo->no_virtual();
      -}
      -
      -
      -

      And the following code runs in ~1.12s:

      -
      Foo* foo = makeFoo();
      -for (int i = 0; i != 1'000'000'000; ++i) {
      -  foo->yes_virtual();
      -}
      -
      -
      -

      So, although virtual function calls are useful, they must be used with care. +

      Virtual function calls are somewhat costly (see integration-tests/virtual-cost) so, although they are useful, they must be used with care. It’s best to keep them for cases where they are not called too often; up to a few thousands per learning should be OK. When polymorphism is required for frequent calls, it’s best to use template-based static polymorphism.

      An example of that can be found in lincs/liblincs/learning/mrsort-by-weights-profiles-breed/optimize-weights/linear-program.hpp, @@ -250,7 +231,7 @@

      But beware of virtual function calls

      One could now consider using templates everywhere, and not use virtual function calls at all. This would have the following negative consequences:

      -

      The number of explicit template instantiations would explode incombinatorially. +

      The number of explicit template instantiations would explode in a combinatorial way. For example, the LinearProgram template parameter of .../optimize-weights/linear-program.hpp is currently instantiated explicitly for each LP solver in .../optimize-weights/linear-program.cpp. If LearnMrsortByWeightsProfilesBreed was a template, it would have to be instantiated for the whole Cartesian product of all variants of each strategy, to a great maintenance cost. Note that this is not specific to explicit template instanciation, because we expose lincs as a Python library: diff --git a/docs/genindex.html b/docs/genindex.html index 9f15758f..c0d3a453 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -4,11 +4,11 @@ - Index — lincs 0.10.3 documentation + Index — lincs 0.11.0 documentation - + @@ -79,6 +79,13 @@

      Symbols

      +
    • + --dry-run + +
    • @@ -200,6 +207,13 @@

      Symbols

    • +
    • + --mrsort.weights-profiles-breed.output-metadata + +
    • @@ -216,8 +230,6 @@

      Symbols

    • lincs-learn-classification-model command line option
  • - - + + +
  • + --output-description + +
  • @@ -290,24 +313,38 @@

    Symbols

  • - --skip-long + --skip-cpp-unit
  • - --skip-unit + --skip-long-unit
  • +
  • + --skip-notebooks + +
  • +
  • + --skip-unchanged-notebooks + +
  • - --stop-after-unit + --skip-unit
  • @@ -342,6 +379,8 @@

    Symbols

    ./publish.sh command line option
  • @@ -357,11 +396,15 @@

    Symbols

  • --single-python-version
  • -
  • --skip-long +
  • --skip-cpp-unit
  • -
  • --skip-unit +
  • --skip-long-unit +
  • +
  • --skip-notebooks
  • -
  • --stop-after-unit +
  • --skip-unchanged-notebooks +
  • +
  • --skip-unit
  • --unit-coverage
  • @@ -461,6 +504,26 @@

    L

  • MODEL
  • PROBLEM +
  • + +
  • + lincs-describe-classification-model command line option + +
  • +
  • + lincs-describe-classification-problem command line option + +
  • @@ -550,6 +613,8 @@

    L

  • --mrsort.weights-profiles-breed.max-iterations-without-progress
  • --mrsort.weights-profiles-breed.models-count +
  • +
  • --mrsort.weights-profiles-breed.output-metadata
  • --mrsort.weights-profiles-breed.profiles-strategy
  • @@ -598,6 +663,8 @@

    M

  • lincs-classification-accuracy command line option
  • lincs-classify command line option +
  • +
  • lincs-describe-classification-model command line option
  • lincs-generate-classified-alternatives command line option
  • @@ -630,6 +697,10 @@

    P

  • lincs-classification-accuracy command line option
  • lincs-classify command line option +
  • +
  • lincs-describe-classification-model command line option +
  • +
  • lincs-describe-classification-problem command line option
  • lincs-generate-classification-model command line option
  • diff --git a/docs/get-started.html b/docs/get-started.html index d20208e9..ee23777c 100644 --- a/docs/get-started.html +++ b/docs/get-started.html @@ -5,11 +5,11 @@ - Get started — lincs 0.10.3 documentation + Get started — lincs 0.11.0 documentation - + @@ -38,6 +38,8 @@

    Get started

    We provide binary wheels for lincs on Linux, Windows and macOS for x86_64 processors, so running pip install lincs --only-binary lincs should be enough on those systems.

    +

    We generally recommend you use pip in a virtual environment (python -m venv) or directly pipx to install any package, including lincs. +Recent Ubuntu systems will even enforce that, by refusing to install PyPI packages in the “externally managed” default environment.

    If you’re on a platform for which we don’t make wheels, you’ll need to build lincs from sources. We don’t recommend you do that, because it can be a lot of work. If you really want to go that route, you may want to start by reading the GitHub Actions workflow we use to build the binary wheels. @@ -46,6 +48,7 @@

    Get lincs

    Start using lincs’ command-line interface

    +

    If you’re a Jupyter user, you can download the notebook this section is based on.

    The command-line interface is the easiest way to get started with lincs, starting with lincs --help, which should output something like:

    Usage: lincs [OPTIONS] COMMAND [ARGS]...
     
    @@ -59,6 +62,7 @@ 

    Get lincsproblem.yml should look like:

    -
    # Reproduction command (with lincs version 0.10.3): lincs generate classification-problem 4 3 --random-seed 40
    +
    # Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 40
     kind: classification-problem
     format_version: 1
     criteria:
       - name: Criterion 1
         value_type: real
    -    category_correlation: growing
    +    preference_direction: increasing
         min_value: 0
         max_value: 1
       - name: Criterion 2
         value_type: real
    -    category_correlation: growing
    +    preference_direction: increasing
         min_value: 0
         max_value: 1
       - name: Criterion 3
         value_type: real
    -    category_correlation: growing
    +    preference_direction: increasing
         min_value: 0
         max_value: 1
       - name: Criterion 4
         value_type: real
    -    category_correlation: growing
    +    preference_direction: increasing
         min_value: 0
         max_value: 1
    -categories:
    -  - name: Category 1
    -  - name: Category 2
    -  - name: Category 3
    +ordered_categories:
    +  - name: Worst category
    +  - name: Intermediate category 1
    +  - name: Best category
     

    You can edit this file to change the criteria names, the number of categories, etc. as long as you keep the same format. That format is explained in details in our user guide. The concept of “classification problem” is described in our conceptual overview documentation.

    +

    If you want a human-readable explanation of the problem, you can use:

    +
    lincs describe classification-problem problem.yml
    +
    +
    +

    It will tell you something like:

    +
    This a classification problem into 3 ordered categories named "Worst category", "Intermediate category 1" and "Best category".
    +The best category is "Best category" and the worst category is "Worst category".
    +There are 4 classification criteria (in no particular order).
    +Criterion "Criterion 1" takes real values between 0.0 and 1.0 included.
    +Higher values of "Criterion 1" are known to be better.
    +Criterion "Criterion 2" takes real values between 0.0 and 1.0 included.
    +Higher values of "Criterion 2" are known to be better.
    +Criterion "Criterion 3" takes real values between 0.0 and 1.0 included.
    +Higher values of "Criterion 3" are known to be better.
    +Criterion "Criterion 4" takes real values between 0.0 and 1.0 included.
    +Higher values of "Criterion 4" are known to be better.
    +
    +

    Then generate an NCS classification model:

    lincs generate classification-model problem.yml --output-model model.yml
     

    It should look like:

    -
    # Reproduction command (with lincs version 0.10.3): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort
    +
    # Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort
     kind: ncs-classification-model
     format_version: 1
     accepted_values:
    @@ -137,6 +159,23 @@ 

    Get lincs +

    The model format is quite generic to ensure lincs can evolve to handle future models, +so you may want to get a human-readable description of a model, including wether it’s an MR-Sort or Uc-NCS model, using:

    +
    lincs describe classification-model problem.yml model.yml
    +
    +
    +

    It should output something like:

    +
    This is a MR-Sort (a.k.a. 1-Uc-NCS) model: an NCS model where the sufficient coalitions are specified using the same criterion weights for all boundaries.
    +The weights associated to each criterion are:
    +  - Criterion "Criterion 1": 0.15
    +  - Criterion "Criterion 2": 0.62
    +  - Criterion "Criterion 3": 0.41
    +  - Criterion "Criterion 4": 0.10
    +To get into an upper category, an alternative must be better than the following profiles on a set of criteria whose weights add up to at least 1:
    +  - For category "Intermediate category 1": at least 0.26 on criterion "Criterion 1", at least 0.06 on criterion "Criterion 2", at least 0.16 on criterion "Criterion 3", and at least 0.05 on criterion "Criterion 4"
    +  - For category "Best category": at least 0.68 on criterion "Criterion 1", at least 0.32 on criterion "Criterion 2", at least 0.67 on criterion "Criterion 3", and at least 0.60 on criterion "Criterion 4"
    +
    +

    And finally generate a set of classified alternatives:

    lincs generate classified-alternatives problem.yml model.yml 1000 --output-alternatives learning-set.csv
     
    @@ -146,13 +185,13 @@

    Get lincs--max-imbalance option interacts with that feature.

    It should start with something like this, and contain 1000 alternatives:

    -
    # Reproduction command (with lincs version 0.10.3): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0
    +
    # Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0
     name,"Criterion 1","Criterion 2","Criterion 3","Criterion 4",category
    -"Alternative 1",0.37454012,0.796543002,0.95071429,0.183434784,"Category 3"
    -"Alternative 2",0.731993914,0.779690981,0.598658502,0.596850157,"Category 2"
    -"Alternative 3",0.156018645,0.445832759,0.15599452,0.0999749228,"Category 1"
    -"Alternative 4",0.0580836125,0.4592489,0.866176128,0.333708614,"Category 3"
    -"Alternative 5",0.601114988,0.14286682,0.708072603,0.650888503,"Category 2"
    +"Alternative 1",0.37454012,0.796543002,0.95071429,0.183434784,"Best category"
    +"Alternative 2",0.731993914,0.779690981,0.598658502,0.596850157,"Intermediate category 1"
    +"Alternative 3",0.156018645,0.445832759,0.15599452,0.0999749228,"Worst category"
    +"Alternative 4",0.0580836125,0.4592489,0.866176128,0.333708614,"Best category"
    +"Alternative 5",0.601114988,0.14286682,0.708072603,0.650888503,"Intermediate category 1"
     

    You can visualize its first five alternatives using:

    @@ -170,9 +209,7 @@

    Get lincs
    # Reproduction command (with lincs version 0.10.3): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0
    -# Termination condition: target accuracy reached
    -# Number of iterations: 22
    +
    # Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0
     kind: ncs-classification-model
     format_version: 1
     accepted_values:
    @@ -207,21 +244,21 @@ 

    Get lincs
    522c522
    -< "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Category 3"
    +< "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Best category"
     ---
    -> "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Category 2"
    +> "Alternative 520",0.617141366,0.326259822,0.901315808,0.460642993,"Intermediate category 1"
     615c615
    -< "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Category 2"
    +< "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Intermediate category 1"
     ---
    -> "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Category 1"
    +> "Alternative 613",0.547554553,0.0552174859,0.690436542,0.511019647,"Worst category"
     2596c2596
    -< "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Category 2"
    +< "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Intermediate category 1"
     ---
    -> "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Category 1"
    +> "Alternative 2594",0.234433308,0.780464768,0.162389532,0.622178912,"Worst category"
     2610c2610
    -< "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Category 2"
    +< "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Intermediate category 1"
     ---
    -> "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Category 1"
    +> "Alternative 2608",0.881479025,0.055544015,0.82936728,0.853676081,"Worst category"
     

    You can also measure the classification accuracy of the trained model on that testing set:

    diff --git a/docs/get-started.ipynb b/docs/get-started.ipynb new file mode 100644 index 00000000..14cf5b6c --- /dev/null +++ b/docs/get-started.ipynb @@ -0,0 +1,385 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "361e4c6f-f368-4a4f-87fe-7b577ed1b3a5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Usage: lincs [OPTIONS] COMMAND [ARGS]...\n", + "\n", + " lincs (Learn and Infer Non-Compensatory Sorting) is a set of tools for\n", + " training and using MCDA models.\n", + "\n", + "Options:\n", + " --version Show the version and exit.\n", + " --help Show this message and exit.\n", + "\n", + "Commands:\n", + " classification-accuracy Compute a classification accuracy.\n", + " classify Classify alternatives.\n", + " describe Provide human-readable descriptions.\n", + " generate Generate synthetic data.\n", + " info Get information about lincs itself.\n", + " learn Learn a model.\n", + " visualize Make graphs from data.\n" + ] + } + ], + "source": [ + "lincs --help" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a3e8e6c9-d553-4b3a-b9c3-8708b2036dc8", + "metadata": { + "append_to_source": [ + "--random-seed 40" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 40\n", + "kind: classification-problem\n", + "format_version: 1\n", + "criteria:\n", + " - name: Criterion 1\n", + " value_type: real\n", + " preference_direction: increasing\n", + " min_value: 0\n", + " max_value: 1\n", + " - name: Criterion 2\n", + " value_type: real\n", + " preference_direction: increasing\n", + " min_value: 0\n", + " max_value: 1\n", + " - name: Criterion 3\n", + " value_type: real\n", + " preference_direction: increasing\n", + " min_value: 0\n", + " max_value: 1\n", + " - name: Criterion 4\n", + " value_type: real\n", + " preference_direction: increasing\n", + " min_value: 0\n", + " max_value: 1\n", + "ordered_categories:\n", + " - name: Worst category\n", + " - name: Intermediate category 1\n", + " - name: Best category\n" + ] + } + ], + "source": [ + "lincs generate classification-problem 4 3 --output-problem problem.yml\n", + "cat problem.yml" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "74b56034-e9b3-45f3-85fb-ba05ddce97e1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This a classification problem into 3 ordered categories named \"Worst category\", \"Intermediate category 1\" and \"Best category\".\n", + "The best category is \"Best category\" and the worst category is \"Worst category\".\n", + "There are 4 classification criteria (in no particular order).\n", + "Criterion \"Criterion 1\" takes real values between 0.0 and 1.0 included.\n", + "Higher values of \"Criterion 1\" are known to be better.\n", + "Criterion \"Criterion 2\" takes real values between 0.0 and 1.0 included.\n", + "Higher values of \"Criterion 2\" are known to be better.\n", + "Criterion \"Criterion 3\" takes real values between 0.0 and 1.0 included.\n", + "Higher values of \"Criterion 3\" are known to be better.\n", + "Criterion \"Criterion 4\" takes real values between 0.0 and 1.0 included.\n", + "Higher values of \"Criterion 4\" are known to be better.\n" + ] + } + ], + "source": [ + "lincs describe classification-problem problem.yml" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b5c6832d-9133-4ee7-92c2-9d2e8fa78a3e", + "metadata": { + "append_to_source": [ + "--random-seed 41" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-model problem.yml --random-seed 41 --model-type mrsort\n", + "kind: ncs-classification-model\n", + "format_version: 1\n", + "accepted_values:\n", + " - kind: thresholds\n", + " thresholds: [0.255905151, 0.676961303]\n", + " - kind: thresholds\n", + " thresholds: [0.0551739037, 0.324553937]\n", + " - kind: thresholds\n", + " thresholds: [0.162252158, 0.673279881]\n", + " - kind: thresholds\n", + " thresholds: [0.0526000932, 0.598555863]\n", + "sufficient_coalitions:\n", + " - &coalitions\n", + " kind: weights\n", + " criterion_weights: [0.147771254, 0.618687689, 0.406786472, 0.0960085914]\n", + " - *coalitions\n" + ] + } + ], + "source": [ + "lincs generate classification-model problem.yml --output-model model.yml\n", + "cat model.yml" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "53873ac0-1b9c-4704-9b77-194be2ad8143", + "metadata": { + "append_to_source": [ + "", + "", + "cp model.png .." + ] + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAYAAAByNR6YAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABUT0lEQVR4nO3dd3hUVeLG8e+dkt5JSIGEQOgqvaN0VnbXAmtfFFnbqmDFuhZEURTsvayiq65lbetPXbuIohRpohQBQwepSWZSpt37+yMwEnq5yaS8n+fheZi57cydk5l3zj33HMOyLAsRERERsY0j0gUQERERqW8UsERERERs5op0AexkmiYbNmwgMTERwzAiXRwRERGpYyzLwuPxkJOTg8Nx5O1Q9Spgbdiwgdzc3EgXQ0REROq4tWvX0rRp0yPevl4FrMTERKDypCQlJdm6b9M0WbhwIQAdO3Y8qlQrciRUByXSVAcl0mqiDpaUlJCbmxvOFEeqXgWsXZcFk5KSqiVgJSQkhPevDxapaaqDEmmqgxJpNVkHj7arkf46RERERGymgCUiIiJiMwUsEREREZspYImIiIjYTAFLRERExGYKWCIiIiI2U8ASERERsZkCloiIiIjNjjhgDRgwgKuvvtrGooiIiIjUD7WyBWvatGkYhkFRUVGkiyIiIiJy2GplwBIRERGpy44qYAWDQcaOHUtycjLp6encdtttWJYFgM/n47rrrqNJkybEx8fTs2dPpk2bFt529erVnHzyyaSmphIfH88xxxzDRx99xKpVqxg4cCAAqampGIbB6NGjj6aYIiIiIjXqqCZ7fumll7jwwguZPXs2P/zwA5dccgl5eXlcfPHFjB07lsWLF/P666+Tk5PDu+++y7Bhw1i0aBGtWrVizJgx+P1+pk+fTnx8PIsXLyYhIYHc3FzefvttTjvtNJYtW0ZSUhKxsbGHVS7TNDFN82he2gH3afe+RQ6F6qBEmuqgRFpN1EG79ntUASs3N5eHHnoIwzBo06YNixYt4qGHHuLEE09k6tSprFmzhpycHACuu+46Pv74Y6ZOnco999zDmjVrOO200zjuuOMAaNGiRXi/aWlpADRu3JiUlJT9Ht/n8+Hz+cKPS0pKAFi4cGF4tm27mKbJsmXLCIQCVAQrNIu81DjTNPnll18AVAclIlQHJdJ21cFoZzRAtdRBr9dry36OKmD16tULwzDCj3v37s0DDzzAokWLCIVCtG7dusr6Pp+PRo0aAXDllVdy2WWX8emnnzJkyBBOO+00OnTocFjHnzRpEhMmTDial3DYVhatZNP6TfpgkRpnmiYbNm8AYHP8ZtVBqXGqgxJpu+pg96zukS7KQR1VwNofr9eL0+lk7ty5OJ3OKst2tSxddNFFnHjiiXz44Yd8+umnTJo0iQceeIArrrjikI9z8803c+2114Yfl5SUkJubS8eOHUlKSrLnxey0q8mwdHMpSc2T9MEiNc40Tdj5eya/Xb7qoNQ41UGJtF11sE1uGzp37lwtdXDX1bCjdVQBa9asWVUez5w5k1atWtG5c2dCoRCbN2/mhBNO2O/2ubm5XHrppVx66aXcfPPNPPfcc1xxxRVERUUBEAqFDnj86OhooqOj93re4XBUy0l3OBw4DEe17V/kYBxGZb1THZRIUR2USNv9e7i6vutt2c/RbLxmzRquvfZali1bxmuvvcZjjz3GVVddRevWrRk5ciSjRo3inXfeobCwkNmzZzNp0iQ+/PBDAK6++mo++eQTCgsLmTdvHl999RXt2rUDoFmzZhiGwQcffMCWLVtsux4qIiIiUhOOKmCNGjWK8vJyevTowZgxY7jqqqu45JJLAJg6dSqjRo1i3LhxtGnThuHDhzNnzhzy8vKAytapMWPG0K5dO4YNG0br1q158sknAWjSpAkTJkzgpptuIjMzk7Fjxx7lyxQRERGpOYa1a+CqeqCkpITk5GSKi4urpQ/W/PnzmffbPJJaqA+W1DzTNFm1eBUA+e3V/0VqnuqgRNquOjgobxBdu3Sttj5YdmQJ/XWIiIiI2EwBS0RERMRmClgiIiIiNlPAEhEREbGZApaIiIiIzRSwRERERGymgCUiIiJiMwUsEREREZspYImIiIjYTAFLRERExGYKWCIiIiI2U8ASERERsZkCloiIiIjNFLBEREREbKaAJSIiImIzBSwRERERmylgiYiIiNhMAUtERETEZgpYIiIiIjZTwBIRERGxmQKWiIiIiM0UsERERERspoAlIiIiYjMFLBERERGbKWCJiIiI2EwBS0RERMRmClgiIiIiNlPAEhEREbGZApaIiIiIzRSwRERERGymgCUiIiJiMwUsEREREZspYImIiIjYTAFLRERExGYKWCIiIiI2U8ASERERsZkCloiIiIjN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WW4PmUblZcVks6hO3/yzPwpYIrXQjlAs34UKcJNP66gttGAd8eaOfa4bMpyUOFPUOiUidUIAJ2sDKawlBcgDoJGzrPKyolFEqlVEXKg0omW0gwKWSC0WwMnP/ix+JossRxEBZzkJVikbXU3Y7khV65SI1AvbQnFsC8Wxa0LrWCNAtttDY6OINKuIJLO4VtwMdDgUsETqiA3BJFYHmgPQzNcWh8MR4RKJiFSPcssd7jIBlZ3nM12lZDh3sN1ZSppR+39UKmCJiIhIrWbiYGMwkfVmPKsDxfyhDsxbrZ/AIiIiIjZTwBIRERGxmQKWiIiIiM0UsERERERspoAlIiIiYjMFLBERERGbKWCJiIiI2EwBS0RERMRmClgiIiIiNlPAEhEREbGZApaIiIiIzRSwRERERGxWawOWYRi89957kS6GiIiIyGGLSMDy+/2ROKyIiIhIjXDt68kPPviAc889l23btuF0OlmwYAGdO3fmxhtv5N577wXgoosuoqKigldeeYW3336b22+/nRUrVpCdnc0VV1zBuHHjwvvLz8/nwgsvZPny5bz33nv85S9/4dlnn+Xaa6/l7bffZseOHWRmZnLppZdy8803k5+fD8CIESMAaNasGatWrTrkF2WaJqZpHuEpOfA+q2PfIodi97qnOiiRoDookVYT38V27XefAeuEE07A4/Ewf/58unXrxtdff016ejrTpk0Lr/P1119z4403MnfuXM4880zuuOMOzjrrLL777jsuv/xyGjVqxOjRo8Pr33///dx+++2MHz8egEcffZT333+fN998k7y8PNauXcvatWsBmDNnDo0bN2bq1KkMGzYMp9O5z8L7fD58Pl/4cUlJCQALFy4kISHhqE7MnkzTZNmyZazdUEys14/DUWuvrko9ZZomG9f8Gn6sOig1TXVQIm1XHVzmLMLhMKqlDnq9Xlv2s8+AlZycTKdOnZg2bRrdunVj2rRpXHPNNUyYMAGv10txcTErVqygf//+3HHHHQwePJjbbrsNgNatW7N48WKmTJlSJWANGjSoSqvWmjVraNWqFccffzyGYdCsWbPwsoyMDABSUlLIysrab+EnTZrEhAkTjuoEHK6clBhycpL0wSI1zjRN4sriAWiuOigRoDookbarDjocRqSLclD7DFgA/fv3Z9q0aYwbN45vvvmGSZMm8eabb/Ltt9+yfft2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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "lincs visualize classification-model problem.yml model.yml model.png\n", + "cat model.png | display" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9cf24956-d8ef-4396-b32f-896ce1ae3f1a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This is a MR-Sort (a.k.a. 1-Uc-NCS) model: an NCS model where the sufficient coalitions are specified using the same criterion weights for all boundaries.\n", + "The weights associated to each criterion are:\n", + " - Criterion \"Criterion 1\": 0.15\n", + " - Criterion \"Criterion 2\": 0.62\n", + " - Criterion \"Criterion 3\": 0.41\n", + " - Criterion \"Criterion 4\": 0.10\n", + "To get into an upper category, an alternative must be better than the following profiles on a set of criteria whose weights add up to at least 1:\n", + " - For category \"Intermediate category 1\": at least 0.26 on criterion \"Criterion 1\", at least 0.06 on criterion \"Criterion 2\", at least 0.16 on criterion \"Criterion 3\", and at least 0.05 on criterion \"Criterion 4\"\n", + " - For category \"Best category\": at least 0.68 on criterion \"Criterion 1\", at least 0.32 on criterion \"Criterion 2\", at least 0.67 on criterion \"Criterion 3\", and at least 0.60 on criterion \"Criterion 4\"\n" + ] + } + ], + "source": [ + "lincs describe classification-model problem.yml model.yml" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "b5bf08d4-a963-4a9c-89e6-3c9fefb718b0", + "metadata": { + "append_to_source": [ + "--random-seed 42" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 1000 --random-seed 42 --misclassified-count 0\n", + "name,\"Criterion 1\",\"Criterion 2\",\"Criterion 3\",\"Criterion 4\",category\n", + "\"Alternative 1\",0.37454012,0.796543002,0.95071429,0.183434784,\"Best category\"\n", + "\"Alternative 2\",0.731993914,0.779690981,0.598658502,0.596850157,\"Intermediate category 1\"\n", + "\"Alternative 3\",0.156018645,0.445832759,0.15599452,0.0999749228,\"Worst category\"\n", + "\"Alternative 4\",0.0580836125,0.4592489,0.866176128,0.333708614,\"Best category\"\n", + "\"Alternative 5\",0.601114988,0.14286682,0.708072603,0.650888503,\"Intermediate category 1\"\n" + ] + } + ], + "source": [ + "lincs generate classified-alternatives problem.yml model.yml 1000 --output-alternatives learning-set.csv\n", + "head -n 7 learning-set.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f5cd7bd4-b451-467b-a5cb-17eee19fb1d5", + "metadata": { + "append_to_source": [ + "", + "", + "cp alternatives.png .." + ] + }, + "outputs": [ + { + "data": { + "image/png": "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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "lincs visualize classification-model problem.yml model.yml --alternatives learning-set.csv --alternatives-count 5 alternatives.png\n", + "cat alternatives.png | display" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "754ae3aa-3f1d-4371-8a53-429d4267e6a8", + "metadata": { + "append_to_source": [ + "--mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 43 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "kind: ncs-classification-model\n", + "format_version: 1\n", + "accepted_values:\n", + " - kind: thresholds\n", + " thresholds: [0.339874953, 0.421424538]\n", + " - kind: thresholds\n", + " thresholds: [0.0556534864, 0.326433569]\n", + " - kind: thresholds\n", + " thresholds: [0.162616938, 0.67343241]\n", + " - kind: thresholds\n", + " thresholds: [0.0878681168, 0.252649099]\n", + "sufficient_coalitions:\n", + " - &coalitions\n", + " kind: weights\n", + " criterion_weights: [0, 1.01327896e-06, 0.999998987, 0]\n", + " - *coalitions\n" + ] + } + ], + "source": [ + "lincs learn classification-model problem.yml learning-set.csv --output-model trained-model.yml\n", + "cat trained-model.yml" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "97923a47-2ae8-4b2b-8400-cd43dc2e1426", + "metadata": { + "append_to_source": [ + "--random-seed 44" + ] + }, + "outputs": [], + "source": [ + "lincs generate classified-alternatives problem.yml model.yml 3000 --output-alternatives testing-set.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "f41d3d04-a669-4d82-98be-652b760f19ce", + "metadata": { + "append_to_source": [ + "", + "| tail -n +5" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "522c522\n", + "< \"Alternative 520\",0.617141366,0.326259822,0.901315808,0.460642993,\"Best category\"\n", + "---\n", + "> \"Alternative 520\",0.617141366,0.326259822,0.901315808,0.460642993,\"Intermediate category 1\"\n", + "615c615\n", + "< \"Alternative 613\",0.547554553,0.0552174859,0.690436542,0.511019647,\"Intermediate category 1\"\n", + "---\n", + "> \"Alternative 613\",0.547554553,0.0552174859,0.690436542,0.511019647,\"Worst category\"\n", + "2596c2596\n", + "< \"Alternative 2594\",0.234433308,0.780464768,0.162389532,0.622178912,\"Intermediate category 1\"\n", + "---\n", + "> \"Alternative 2594\",0.234433308,0.780464768,0.162389532,0.622178912,\"Worst category\"\n", + "2610c2610\n", + "< \"Alternative 2608\",0.881479025,0.055544015,0.82936728,0.853676081,\"Intermediate category 1\"\n", + "---\n", + "> \"Alternative 2608\",0.881479025,0.055544015,0.82936728,0.853676081,\"Worst category\"\n" + ] + } + ], + "source": [ + "lincs classify problem.yml trained-model.yml testing-set.csv --output-alternatives reclassified-testing-set.csv\n", + "diff testing-set.csv reclassified-testing-set.csv" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "21f39e5a-f22b-45ca-bb64-3cfef5d7b05f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2996/3000\n" + ] + } + ], + "source": [ + "lincs classification-accuracy problem.yml trained-model.yml testing-set.csv" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/index.html b/docs/index.html index 6195b9b2..d3adcc67 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,11 +5,11 @@ - README — lincs 0.10.3 documentation + README — lincs 0.11.0 documentation - + diff --git a/docs/objects.inv b/docs/objects.inv index 84385b36..8a09f119 100644 Binary files a/docs/objects.inv and b/docs/objects.inv differ diff --git a/docs/reference.html b/docs/reference.html index c573463f..fe7104e9 100644 --- a/docs/reference.html +++ b/docs/reference.html @@ -5,11 +5,11 @@ - Reference — lincs 0.10.3 documentation + Reference — lincs 0.11.0 documentation - + @@ -98,7 +98,7 @@

    File formats

    May be extended in the future to handle criteria with integer values, or explicitely enumarated values.

    +

    May be extended in the future to handle criteria with integer values, or explicitly enumerated values.

    type

    string

    @@ -107,16 +107,16 @@

    File formats
      -
    • category_correlation

    • +
    • preference_direction

    -

    May be extended in the future to handle single-peaked criteria, or criteria with unknown correlation.

    +

    May be extended in the future to handle single-peaked criteria, or criteria with unknown preference direction.

    type

    string

    enum

    -

    growing, decreasing

    +

    increasing, isotone, decreasing, antitone

    generate

    @@ -519,7 +577,7 @@
    classification-problem
    --allow-decreasing-criteria
    -

    Allow criteria to have decreasing correlation to categories. (By default, all criteria have growing correlation)

    +

    Allow criteria to have decreasing preference direction. (By default, all criteria have increasing preference direction)

    @@ -964,6 +1022,19 @@
    classification-model +
    +--mrsort.weights-profiles-breed.output-metadata <mrsort__weights_profiles_breed__output_metadata>
    +

    Write metadata about the learning process to this file.

    +
    +
    Only valid if:
    +
    +
      +
    • --model-type is mrsort

    • +
    • --mrsort.strategy is weights-profiles-breed

    • +
    +
    +

    Arguments

    diff --git a/docs/search.html b/docs/search.html index 8ba1d30e..d0055baa 100644 --- a/docs/search.html +++ b/docs/search.html @@ -4,12 +4,12 @@ - Search — lincs 0.10.3 documentation + Search — lincs 0.11.0 documentation - + diff --git a/docs/searchindex.js b/docs/searchindex.js index 0dd8fbb2..117aa55d 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["README", "changelog", "conceptual-overview", "contributor-guide", "get-started", "index", "reference", "user-guide"], "filenames": ["README.rst", "changelog.rst", "conceptual-overview.rst", "contributor-guide.rst", "get-started.rst", "index.rst", "reference.rst", "user-guide.rst"], "titles": ["Contributors", "Changelog", "Conceptual overview", "Contributor guide", "Get started", "README", "Reference", "User Guide"], "terms": {"learn": [0, 1, 3, 4, 5], "infer": [0, 4, 5, 6], "non": [0, 4, 5, 6], "compensatori": [0, 4, 5, 6], "sort": [0, 1, 4, 5, 6, 7], "i": [0, 1, 2, 3, 4, 5, 6, 7], "collect": [0, 5], "command": [0, 1, 3, 5, 7], "line": [0, 1, 3, 5, 7], "util": [0, 4, 5], "support": [0, 1, 5, 6, 7], "linux": [0, 1, 4, 5, 7], "maco": [0, 1, 4, 5, 7], "window": [0, 1, 4, 5, 7], "gpu": [0, 1, 3, 5, 7], "ar": [0, 1, 2, 3, 4, 5, 6, 7], "avail": [0, 5], "becaus": [0, 2, 3, 4, 5, 7], "cuda": [0, 1, 2, 3, 5, 6, 7], "On": [0, 3, 5], "3": [0, 2, 4, 5, 7], "os": [0, 5], "onli": [0, 1, 2, 3, 4, 5, 6, 7], "x86_64": [0, 4, 5], "cpu": [0, 1, 3, 4, 5, 6, 7], "licens": [0, 1, 5], "under": [0, 3, 5], "gnu": [0, 5], "lesser": [0, 5], "gener": [0, 1, 2, 4, 5], "public": [0, 1, 3, 5], "v3": [0, 5], "0": [0, 2, 3, 4, 5, 6, 7], "indic": [0, 5, 7], "two": [0, 2, 4, 5, 7], "copi": [0, 5], "instal": [0, 1, 3, 4, 5], "from": [0, 2, 3, 4, 5, 6, 7], "python": [0, 1, 2, 5], "packag": [0, 1, 3, 5], "index": [0, 2, 3, 5], "Its": [0, 2, 5, 6, 7], "document": [0, 1, 2, 4, 5, 7], "its": [0, 2, 3, 4, 5, 6, 7], "sourc": [0, 3, 4, 5, 6], "code": [0, 1, 3, 5, 6, 7], "github": [0, 3, 4, 5, 6], "question": [0, 2, 5, 7], "remark": [0, 5, 7], "bug": [0, 1, 3, 5], "want": [0, 2, 3, 4, 5, 7], "contribut": [0, 4, 5], "open": [0, 3, 5], "an": [0, 1, 2, 4, 5, 6], "issu": [0, 5], "discuss": [0, 3, 5], "todo": [0, 3, 4, 5], "featur": [0, 1, 3, 4, 5, 7], "later": [0, 3, 4, 5], "make": [0, 1, 3, 4, 5, 6, 7], "c": [0, 1, 5, 7], "librari": [0, 3, 5], "m1": [0, 5], "m2": [0, 5], "chip": [0, 5], "much": [0, 3, 5, 7], "arm": [0, 5], "processor": [0, 4, 5, 6, 7], "manag": [0, 5], "when": [0, 1, 2, 3, 5, 6, 7], "we": [0, 2, 3, 4, 5, 7], "publish": [0, 1, 5], "paper": [0, 5], "add": [0, 1, 5, 6, 7], "note": [0, 2, 3, 5, 7], "ask": [0, 4, 5], "academ": [0, 2, 5], "kindli": [0, 4, 5], "cite": [0, 5], "our": [0, 2, 3, 4, 5, 7], "work": [0, 3, 4, 5], "mic": [0, 3, 5, 6], "research": [0, 5], "team": [0, 5], "centralesup\u00e9lec": [0, 5], "main": [0, 2, 3, 5], "author": [0, 5], "alphabet": [0, 5], "order": [0, 2, 5, 7], "laurent": [0, 5], "cabaret": [0, 5], "perform": [0, 1, 2, 3, 5, 7], "optim": [0, 3, 5, 7], "vincent": [0, 5], "jacqu": [0, 5], "engin": [0, 5], "mousseau": [0, 5], "domain": [0, 1, 5], "expertis": [0, 5], "wassila": [0, 5], "ouerdan": [0, 5], "you": [0, 2, 3, 4, 5, 6, 7], "should": [0, 2, 3, 4, 5, 6, 7], "abl": [0, 5], "us": [0, 1, 2, 3, 5, 6], "without": [0, 1, 2, 3, 5, 6, 7], "being": [0, 2, 4, 5], "specialist": [0, 5], "nc": [0, 1, 4, 5, 7], "model": [0, 1, 2, 4, 5], "just": [0, 2, 3, 5, 6, 7], "follow": [0, 2, 3, 5, 6, 7], "section": [0, 3, 5, 7], "below": [0, 5], "design": [0, 4, 5], "easi": [0, 3, 5, 7], "extend": [0, 2, 5, 6, 7], "even": [0, 3, 5, 7], "replac": [0, 5], "part": [0, 1, 3, 5, 7], "exist": [0, 2, 5, 7], "see": [0, 1, 3, 4, 5, 6], "guid": [0, 1, 2, 4, 5, 6], "more": [0, 1, 2, 3, 4, 5, 7], "detail": [0, 1, 3, 4, 5, 7], "depend": [0, 1, 4, 5, 7], "your": [0, 2, 4, 5, 7], "favorit": [0, 5], "approach": [0, 1, 2, 4, 5, 6, 7], "can": [0, 2, 3, 4, 5, 6, 7], "either": [0, 5, 6, 7], "hand": [0, 5, 7], "conceptu": [0, 4, 5, 7], "overview": [0, 4, 5, 7], "The": [0, 2, 3, 4, 5, 7], "former": [0, 5], "show": [0, 4, 5, 6], "how": [0, 2, 4, 5, 7], "latter": [0, 5], "explain": [0, 3, 4, 5, 7], "concept": [0, 2, 4, 5, 7], "behind": [0, 5], "them": [0, 1, 2, 3, 4, 5, 7], "what": [0, 3, 5], "": [0, 1, 2, 3, 4, 5, 6], "etc": [0, 3, 4, 5, 7], "If": [0, 2, 3, 4, 5, 6, 7], "doubt": [0, 5], "highli": [0, 5], "recommend": [0, 2, 3, 4, 5, 7], "read": [0, 2, 3, 4, 5, 6, 7], "other": [0, 2, 3, 5, 7], "one": [0, 2, 3, 4, 5, 6, 7], "after": [0, 1, 3, 5, 7], "onc": [0, 3, 4, 5], "ve": [0, 4, 5, 7], "bit": [0, 5, 7], "up": [0, 2, 3, 4, 5, 6, 7], "user": [0, 1, 3, 4, 5, 6], "refer": [0, 4, 5, 7], "1": [0, 3, 4, 5, 6, 7], "semant": [0, 5], "api": [0, 1, 3, 5], "must": [0, 2, 3, 5, 6, 7], "declar": [0, 5], "accord": [0, 2, 5, 6, 7], "semver": [0, 5], "constitut": [0, 2, 5], "exclus": [0, 5], "level": [0, 2, 3, 5, 6, 7], "consid": [0, 2, 3, 5], "chang": [0, 1, 4, 5, 7], "backward": [0, 5, 7], "compat": [0, 5, 7], "client": [0, 5], "doesn": [0, 2, 4, 5], "t": [0, 2, 3, 4, 5, 6], "need": [0, 3, 4, 5, 7], "modifi": [0, 3, 4, 5, 7], "keep": [0, 3, 4, 5, 7], "requir": [0, 3, 4, 5, 6, 7], "recompil": [0, 5], "some": [0, 2, 3, 5, 7], "case": [0, 3, 5, 7], "futur": [0, 5, 6], "might": [0, 2, 3, 5], "behavior": [0, 5, 7], "especi": [0, 5], "regard": [0, 5], "pseudo": [0, 1, 2, 4, 5, 6, 7], "random": [0, 1, 2, 4, 5, 6], "plan": [0, 5], "do": [0, 2, 4, 5, 7], "ll": [0, 2, 3, 4, 5, 7], "interfac": [0, 3, 5], "In": [0, 2, 5, 7], "mean": [0, 5, 7], "time": [0, 1, 2, 3, 5, 7], "chose": [0, 5], "wai": [0, 2, 3, 4, 5, 6, 7], "expect": [0, 2, 3, 5, 7], "unanticip": [0, 5], "option": [0, 1, 3, 4, 5, 6], "argument": [0, 3, 5, 6], "thei": [0, 1, 2, 3, 4, 5, 7], "releas": [0, 1, 5], "find": [0, 2, 3, 5, 7], "better": [0, 2, 5], "most": [0, 2, 3, 5, 6, 7], "advic": [0, 5], "write": [0, 3, 5, 6], "script": [0, 3, 5], "explicit": [0, 3, 5, 6, 7], "where": [0, 2, 3, 5, 7], "matter": [0, 5], "reli": [0, 3, 5, 7], "implicit": [0, 5], "potenti": [0, 5], "improv": [0, 1, 5, 6, 7], "same": [0, 2, 3, 4, 5, 6, 7], "specif": [0, 3, 5, 7], "appli": [0, 2, 3, 5, 7], "produc": [0, 1, 2, 5, 7], "thi": [0, 1, 2, 3, 4, 5, 6, 7], "lead": [0, 5, 7], "about": [0, 3, 4, 5, 6], "allow": [0, 1, 2, 3, 5, 6, 7], "flexibl": [0, 1, 5], "input": [0, 5, 7], "both": [0, 3, 4, 5], "old": [0, 3, 5], "But": [0, 2, 5, 7], "incompat": [0, 5], "To": [0, 2, 3, 4, 5, 7], "solv": [0, 5, 6, 7], "impos": [0, 5], "addit": [0, 2, 5, 7], "constraint": [0, 2, 5], "motiv": [0, 3, 5], "That": [0, 3, 4, 5, 7], "know": [0, 3, 5, 7], "alreadi": [0, 2, 5, 7], "so": [0, 1, 2, 4, 5, 7], "adapt": [0, 1, 5], "first": [1, 2, 3, 4, 6, 7], "candid": 1, "break": 1, "descript": [1, 2, 6, 7], "accept": [1, 6], "valu": [1, 2, 3, 6], "json": [1, 6, 7], "schema": [1, 6, 7], "renam": [1, 7], "ucnc": [1, 6, 7], "strategi": [1, 4, 6], "output": [1, 4, 6, 7], "altern": [1, 2, 4], "fix": [1, 3, 6, 7], "end": [1, 4], "linc": [1, 2, 3], "visual": [1, 3, 4], "criteria": [1, 2, 4, 6], "min": [1, 2, 6, 7], "max": [1, 2, 3, 4, 6, 7], "categori": [1, 2, 4, 6], "correl": [1, 6, 7], "valid": [1, 6, 7], "consist": [1, 2, 3, 7], "problem": [1, 2, 4], "load": 1, "file": [1, 2, 3, 4], "reproduct": [1, 4, 7], "classifi": [1, 4], "pre": [1, 2, 6], "process": [1, 6, 7], "set": [1, 2, 3, 4, 6, 7], "befor": [1, 2, 3, 6, 7], "all": [1, 2, 4, 6, 7], "algorithm": [1, 2, 3], "possibl": [1, 2, 3], "each": [1, 2, 3, 6, 7], "criterion": [1, 2, 4, 6, 7], "list": [1, 7], "actual": [1, 2, 3, 6, 7], "start": [1, 2, 3, 6, 7], "now": [1, 2, 3, 7], "have": [1, 2, 3, 4, 6, 7], "increas": [1, 7], "rang": [1, 2, 7], "integ": [1, 2, 6, 7], "simplif": [1, 2], "implement": [1, 2, 3, 7], "weight": [1, 2, 3, 4, 6], "profil": [1, 2, 3, 4, 6], "breed": [1, 3, 4, 6], "expos": [1, 3], "sufficientcoalit": 1, "upset_root": [1, 6, 7], "name": [1, 4, 6, 7], "imbal": [1, 4, 6, 7], "cleaner": 1, "error": 1, "too": [1, 2, 3, 7], "tight": 1, "print": [1, 6, 7], "number": [1, 2, 3, 4, 6, 7], "iter": [1, 3, 4, 6], "wpb": [1, 2], "displai": [1, 7], "comment": [1, 6], "variou": 1, "readabl": 1, "integr": [1, 3], "compil": [1, 3, 6], "openmp": [1, 2], "distribut": 1, "binari": [1, 3, 4, 7], "wheel": [1, 3, 4, 7], "durat": [1, 2, 6, 7], "second": [1, 6, 7], "termin": [1, 3, 4, 6], "condit": [1, 4, 7], "chrone": [1, 3], "verbos": [1, 6, 7], "mode": 1, "pernici": 1, "memori": [1, 2], "bugfix": 1, "sure": [1, 6, 7], "built": [1, 3, 7], "build": [1, 3, 4], "nvcc": 1, "e": [1, 2, 3, 6, 7], "g": [1, 3, 6, 7], "provid": [1, 2, 3, 4], "info": [1, 4, 7], "ha": [1, 2, 3, 4, 7], "classif": [1, 3, 4], "help": [1, 2, 3, 4, 7], "sat": [1, 2, 3, 6], "coalit": [1, 2, 4, 6], "separ": [1, 2, 6, 7], "hopefulli": 1, "correct": [1, 3, 7], "yaml": [1, 2, 4, 6, 7], "anchor": [1, 7], "alias": 1, "limit": [1, 7], "repetit": [1, 7], "format": [1, 2, 4], "describ": [1, 2, 3, 4, 6, 7], "u": [1, 3, 7], "textsf": [1, 7], "specifi": [1, 2, 3, 6, 7], "minimum": [1, 2], "maximum": [1, 2, 6], "synthet": [1, 3, 4, 6], "data": [1, 3, 4, 6], "attribut": [1, 2, 7], "denorm": [1, 6, 7], "decreas": [1, 6, 7], "state": 1, "re": [1, 2, 3, 4, 7], "enough": [1, 2, 3, 4], "decim": 1, "store": [1, 2], "float": [1, 7], "point": [1, 7], "avoid": [1, 3, 7], "ani": [1, 3, 7], "loss": 1, "precis": 1, "log": 1, "final": [1, 2, 3, 4, 7], "accuraci": [1, 4], "mrsort": [1, 3, 4, 6, 7], "test": [1, 3, 4], "remov": [1, 4], "buggi": 1, "method": [1, 2, 7], "misclassify_altern": 1, "synthes": 1, "nois": [1, 7], "expend": 1, "suffici": [1, 2, 6], "root": [1, 3, 6, 7], "manylinux_2_31": 1, "flow": 1, "arrai": [1, 6], "scalar": 1, "between": [1, 2, 3, 4, 6, 7], "yet": [1, 2, 4, 7], "though": [1, 7], "control": [1, 7], "over": 1, "expans": 1, "except": 1, "fail": [1, 2], "develop": [1, 2], "machin": [1, 3, 7], "never": 1, "properli": 1, "heurist": [1, 2, 4, 6, 7], "introduc": [1, 2, 3, 7], "alglib": [1, 3, 6, 7], "lp": [1, 3], "solver": [1, 4, 6, 7], "docker": [1, 3], "imag": [1, 3, 6], "everywher": [1, 3], "lgplv3": 1, "miss": [1, 4], "header": [1, 6, 7], "mr": [1, 4, 7], "sobri": [1, 2], "sum": [1, 2, 6, 7], "pypi": [1, 3], "websit": 1, "kick": 1, "off": 1, "effort": [1, 7], "quit": [1, 2, 3, 7], "nice": 1, "readm": [1, 3, 7], "initi": [1, 4, 6, 7], "littl": 1, "function": [1, 2], "denot": 2, "interv": 2, "b": 2, "includ": [2, 4], "often": [2, 3, 4, 7], "zero": [2, 7], "choic": [2, 3, 7], "match": 2, "convent": 2, "program": [2, 3, 4, 6, 7], "languag": [2, 3], "close": [2, 4], "For": [2, 3, 6, 7], "4": [2, 4, 7], "2": [2, 4, 6, 7], "n": 2, "contain": [2, 3, 4, 6, 7], "element": [2, 7], "given": [2, 3, 7], "subset": [2, 7], "power": 2, "mathcal": 2, "p": 2, "focus": 2, "task": [2, 3], "worst": 2, "best": [2, 3, 7], "possibli": 2, "intermedi": [2, 6, 7], "assign": 2, "base": [2, 3, 4, 6], "itself": [2, 4, 6], "vocabulari": 2, "voluntarili": 2, "abstract": [2, 3], "wide": 2, "applic": 2, "concret": [2, 3], "let": [2, 7], "sai": 2, "scholarship": 2, "student": 2, "fund": 2, "polici": 2, "grade": 2, "get": [2, 3, 6, 7], "And": [2, 3, 4, 7], "favor": [2, 7], "younger": 2, "come": [2, 7], "modest": 2, "background": 2, "differ": [2, 3, 4, 6, 7], "topic": 2, "ag": 2, "famili": 2, "incom": 2, "could": [2, 3, 4, 7], "triag": 2, "patient": 2, "hospit": 2, "vital": 2, "sign": 2, "A": [2, 3, 7], "defin": [2, 3, 7], "mathbb": 2, "geq": 2, "x_i": 2, "_": 2, "total": [2, 7], "preccurlyeq_i": 2, "h": 2, "prec": 2, "confus": 2, "expon": 2, "cartesian": [2, 3], "product": [2, 3], "x": 2, "prod_": 2, "x_0": 2, "x_": 2, "inform": [2, 4, 6, 7], "csv": [2, 4, 6, 7], "autom": 2, "new": [2, 4, 7], "call": [2, 7], "train": [2, 4, 6], "ground": 2, "truth": [2, 6, 7], "phase": 2, "f": 2, "rightarrow": 2, "parametr": 2, "form": [2, 3, 7], "paramet": [2, 3], "fit": [2, 3], "higher": [2, 7], "sometim": 2, "import": [2, 3, 7], "compens": 2, "captur": [2, 7], "idea": [2, 3], "There": [2, 4], "mani": [2, 6, 7], "share": 2, "vari": 2, "were": [2, 7], "deni": 2, "bouyssou": 2, "thierri": 2, "marchant": 2, "articl": 2, "axiomat": 2, "noncompensatori": 2, "mcdm": 2, "ii": 2, "than": [2, 3, 7], "lower": [2, 7], "It": [2, 3, 4, 6, 7], "good": [2, 3, 7], "abov": [2, 3, 7], "sever": [2, 3, 7], "reach": [2, 4, 6, 7], "singl": [2, 3, 4, 6, 7], "addition": 2, "h_0": 2, "h_": 2, "still": [2, 3], "subseteq": 2, "With": [2, 7], "h_i": 2, "_i": 2, "inclus": 2, "imbric": 2, "supseteq": 2, "which": [2, 3, 4, 7], "default": [2, 4, 6, 7], "mapsto": 2, "cup": 2, "succcurlyeq_i": 2, "natur": [2, 3], "simplifi": 2, "mai": [2, 3, 4, 6, 7], "slightli": 2, "equival": 2, "somewhat": [2, 7], "simpl": [2, 7], "well": [2, 3], "ensur": [2, 6, 7], "behav": [2, 4], "intuit": 2, "ness": 2, "few": [2, 3, 4, 7], "upper": [2, 7], "select": [2, 3, 7], "ones": [2, 7], "continu": 2, "three": [2, 7], "partial": [2, 4], "full": [2, 3], "further": 2, "thing": [2, 3], "sacrif": 2, "interest": 2, "four": 2, "math": 2, "m": 2, "physic": [2, 7], "literatur": 2, "l": 2, "histori": 2, "normal": 2, "forget": 2, "clariti": 2, "instead": [2, 3, 6, 7], "x_m": 2, "x_p": 2, "x_l": 2, "x_h": 2, "1_m": 2, "1_p": 2, "1_l": 2, "1_h": 2, "6": 2, "55": 2, "7": [2, 7], "5": [2, 4, 6, 7], "2_m": 2, "2_p": 2, "2_l": 2, "2_h": 2, "75": 2, "9": [2, 4, 6, 7], "8": 2, "65": 2, "check": [2, 3, 6, 7], "satisfi": [2, 6], "1_i": 2, "2_i": 2, "look": [2, 3, 4], "like": [2, 3, 4, 7], "repres": [2, 6], "lattic": 2, "arrow": 2, "materi": 2, "relationship": 2, "black": 2, "grei": 2, "here": [2, 3, 7], "els": [2, 3], "ye": 2, "unus": 2, "85": 2, "No": 2, "d": [2, 3], "none": 2, "prose": 2, "formul": 2, "who": 2, "excel": 2, "least": [2, 3, 4, 6, 7], "subject": 2, "scientif": 2, "literari": 2, "back": [2, 4], "common": 2, "less": [2, 3], "computation": [2, 3], "simpler": 2, "previou": [2, 3, 7], "ne": 2, "threshold": [2, 4, 6, 7], "wa": [2, 3, 4, 6, 7], "agn\u00e8": 2, "leroi": 2, "et": 2, "al": 2, "multipl": [2, 3, 7], "w_i": 2, "sum_": 2, "again": 2, "answer": 2, "try": [2, 3, 4, 6, 7], "w_m": 2, "w_p": 2, "w_l": 2, "w_h": 2, "give": [2, 3, 6, 7], "16": 2, "equat": 2, "among": [2, 7], "lt": 2, "notin": 2, "ge": 2, "last": [2, 3, 6, 7], "solut": 2, "By": [2, 3, 6, 7], "contrast": 2, "express": 2, "greater": [2, 7], "fewer": 2, "success": [2, 7], "measur": [2, 3, 4], "metric": 2, "quicker": 2, "portion": [2, 4, 6, 7], "real": [2, 4, 6, 7], "world": [2, 4, 6], "noisi": 2, "inconsist": 2, "prevent": 2, "result": [2, 3, 4, 6, 7], "those": [2, 3, 4, 6, 7], "imposs": 2, "100": [2, 4, 7], "summari": 2, "typic": 2, "failur": [2, 3], "quickest": 2, "noth": [2, 3], "goal": 2, "far": [2, 7], "longest": 2, "simpli": [2, 7], "anyth": [2, 3, 6], "configur": [2, 3], "take": [2, 3, 7], "long": [2, 3, 4], "comput": [2, 4, 6], "resourc": 2, "alwai": [2, 7], "longer": [2, 3], "practic": 2, "ali": 2, "tlili": 2, "khale": 2, "belahc\u00e8n": 2, "effici": 2, "maxsat": 2, "conveni": 2, "gather": 2, "place": [2, 3, 4], "olivi": 2, "hi": 2, "ph": 2, "thesi": 2, "originali": 2, "emma": 2, "dixneuf": 2, "thibault": 2, "monsel": 2, "thoma": 2, "vindard": 2, "sequenti": 2, "parallel": [2, 7], "known": 2, "origin": [2, 4, 7], "compar": [2, 3], "evalu": 2, "qualiti": 2, "clean": 2, "haven": [2, 4], "done": [2, 3, 4], "strongli": [3, 7], "familiar": [3, 4], "rest": 3, "project": [3, 4], "also": [3, 4, 7], "exampl": [3, 7], "talk": 3, "pleas": [3, 7], "awar": 3, "progress": [3, 6, 7], "kind": [3, 4, 6, 7], "exercis": 3, "clairvoy": 3, "predict": 3, "got": 3, "wrong": 3, "hesit": 3, "contact": 3, "begin": [3, 7], "scale": [3, 7], "minor": 3, "major": 3, "refactor": 3, "typo": 3, "web": 3, "spare": 3, "clone": 3, "repositori": 3, "think": [3, 4], "entir": [3, 7], "architectur": 3, "deserv": 3, "rewrit": 3, "http": [3, 6], "com": 3, "lab": [3, 6], "don": [3, 4, 6], "spend": 3, "someth": [3, 4], "reject": 3, "reason": [3, 7], "appar": 3, "moment": 3, "yourself": 3, "tell": [3, 7], "report": 3, "everyth": [3, 7], "recogn": 3, "intimid": 3, "everyon": 3, "experi": [3, 7], "fluenci": 3, "tool": [3, 4, 6, 7], "willing": 3, "feedback": [3, 7], "assur": 3, "construct": 3, "manner": [3, 7], "similar": [3, 7], "inspir": 3, "git": 3, "grep": 3, "theoldth": 3, "thenewth": 3, "blame": 3, "identifi": [3, 7], "commit": 3, "next": 3, "recent": 3, "version": [3, 4, 6, 7], "bash": 3, "nvidia": 3, "runtim": 3, "loop": [3, 7], "repeat": [3, 7], "cach": 3, "subsequ": 3, "faster": 3, "unit": 3, "speed": 3, "eventu": 3, "maintain": 3, "pull": 3, "request": 3, "doc": 3, "io": [3, 6], "page": 3, "push": 3, "impact": [3, 7], "save": 3, "submit": 3, "coverag": 3, "stop": 3, "right": 3, "impli": 3, "skip": [3, 7], "forbid": [3, 7], "automat": 3, "warn": 3, "doe": [3, 7], "explicitli": [3, 7], "doctest": 3, "doctest_opt": 3, "pass": [3, 7], "verbatim": 3, "patch": 3, "thin": 3, "wrapper": 3, "basic": [3, 7], "rst": 3, "setup": 3, "py": 3, "manifest": 3, "licenc": 3, "local": 3, "render": 3, "current": [3, 4, 7], "dev": 3, "accompani": 3, "pattern": [3, 7], "inject": 3, "easili": 3, "switch": 3, "particularli": 3, "variant": 3, "benchmark": 3, "perspect": 3, "distinct": 3, "recurs": 3, "piec": 3, "learnmrsortbyweightsprofilesbre": 3, "weightsoptimizationstrategi": 3, "profilesimprovementstrategi": 3, "improveprofileswithaccuracyheuristiconcpu": 3, "improveprofileswithaccuracyheuristicongpu": 3, "costli": 3, "click": 3, "class": 3, "foo": 3, "void": 3, "yes_virtu": 3, "no_virtu": 3, "actualfoo": 3, "overrid": 3, "makefoo": 3, "return": [3, 6], "93": 3, "int": 3, "000": 3, "12": 3, "although": 3, "care": 3, "thousand": 3, "per": [3, 4, 6, 7], "ok": 3, "polymorph": 3, "frequent": 3, "found": [3, 6, 7], "liblinc": 3, "linear": [3, 4, 6, 7], "hpp": 3, "linearprogram": 3, "cost": 3, "One": 3, "would": [3, 7], "neg": 3, "consequ": 3, "instanti": 3, "explod": 3, "incombinatori": 3, "cpp": 3, "whole": 3, "great": 3, "mainten": 3, "instanci": 3, "modul": 3, "access": 3, "custom": 3, "side": 3, "happen": 3, "restructuredtext": 3, "sphinx": 3, "extent": 3, "edit": [3, 4], "html": [3, 6], "browser": 3, "anticip": [3, 7], "2024": 3, "famou": 3, "word": 3, "mind": [3, 4], "written": [3, 6, 7], "partli": 3, "usabl": 3, "arguabl": [3, 7], "easier": [3, 4], "core": [3, 7], "intens": 3, "interpret": 3, "multi": 3, "thread": 3, "suggest": [3, 4], "someon": 3, "becom": 3, "counter": 3, "through": 3, "breedingstrategi": 3, "reduc": [3, 7], "high": [3, 7], "optimizeweightsusingglop": 3, "spent": 3, "locat": 3, "rare": 3, "signific": 3, "advertis": 3, "boil": 3, "down": 3, "veri": [3, 7], "effect": [3, 4, 7], "unless": 3, "clear": 3, "bilion": 3, "step": 3, "previous": 3, "mimic": 3, "null": 3, "As": [3, 7], "via": 3, "duck": 3, "type": [3, 4, 6, 7], "dockerfil": 3, "foobar": 3, "typedef": 3, "liblincs_modul": 3, "__init__": 3, "command_line_interfac": 3, "txt": 3, "accordingli": 3, "procedur": 3, "0a790ef": 3, "modif": 3, "had": 3, "been": 3, "restructur": 3, "sinc": 3, "besid": 3, "run": 4, "pip": 4, "system": 4, "platform": 4, "lot": 4, "realli": 4, "go": 4, "rout": 4, "action": 4, "workflow": 4, "probabl": 4, "easiest": 4, "usag": 4, "arg": [4, 6], "mcda": [4, 6], "exit": [4, 6], "messag": 4, "graph": [4, 6, 7], "organ": 4, "sub": 4, "handl": [4, 6], "yml": [4, 7], "10": [4, 7], "seed": [4, 6, 7], "40": 4, "format_vers": [4, 6, 7], "value_typ": [4, 6, 7], "category_correl": [4, 6, 7], "grow": [4, 6, 7], "min_valu": [4, 6, 7], "max_valu": [4, 6, 7], "Then": [4, 7], "41": 4, "accepted_valu": [4, 6, 7], "255905151": 4, "676961303": 4, "0551739037": 4, "324553937": 4, "162252158": 4, "673279881": 4, "0526000932": 4, "598555863": 4, "sufficient_coalit": [4, 6, 7], "criterion_weight": [4, 6, 7], "147771254": 4, "618687689": 4, "406786472": 4, "0960085914": 4, "png": [4, 6, 7], "1000": 4, "split": 4, "interact": 4, "42": 4, "misclassifi": [4, 6, 7], "count": [4, 6, 7], "37454012": 4, "796543002": 4, "95071429": 4, "183434784": 4, "731993914": 4, "779690981": 4, "598658502": 4, "596850157": 4, "156018645": 4, "445832759": 4, "15599452": 4, "0999749228": 4, "0580836125": 4, "4592489": 4, "866176128": 4, "333708614": 4, "601114988": 4, "14286682": 4, "708072603": 4, "650888503": 4, "five": 4, "legend": 4, "directli": 4, "structur": [4, 6, 7], "reconstitut": 4, "numer": [4, 7], "43": 4, "maxim": [4, 6], "discrimin": [4, 6], "glop": [4, 6, 7], "reiniti": [4, 6, 7], "accur": [4, 6, 7], "target": [4, 6, 7], "22": 4, "339874953": 4, "421424538": 4, "0556534864": 4, "326433569": 4, "162616938": 4, "67343241": 4, "0878681168": 4, "252649099": 4, "01327896e": 4, "06": 4, "999998987": 4, "howev": 4, "reclassifi": 4, "3000": 4, "diff": 4, "522c522": 4, "520": 4, "617141366": 4, "326259822": 4, "901315808": 4, "460642993": 4, "615c615": 4, "613": 4, "547554553": 4, "0552174859": 4, "690436542": 4, "511019647": 4, "2596c2596": 4, "2594": 4, "234433308": 4, "780464768": 4, "162389532": 4, "622178912": 4, "2610c2610": 4, "2608": 4, "881479025": 4, "055544015": 4, "82936728": 4, "853676081": 4, "2996": 4, "demonstr": 4, "comfort": 4, "text": 6, "standard": [6, 7], "object": 6, "properti": 6, "string": 6, "const": 6, "item": [6, 7], "enumar": 6, "enum": 6, "peak": [6, 7], "unknown": [6, 7], "additionalproperti": 6, "fals": 6, "minitem": 6, "determin": [6, 7], "oneof": 6, "lowest": 6, "comma": 6, "ignor": [6, 7], "quot": 6, "whitespac": 6, "column": [6, 7], "associ": [6, 7], "Their": 6, "empti": [6, 7], "unclassifi": 6, "testing_set": 6, "output_altern": 6, "output_model": 6, "random_se": 6, "model_typ": 6, "mrsort__fixed_weights_sum": 6, "criteria_count": 6, "categories_count": 6, "output_problem": 6, "alternatives_count": 6, "max_imbal": 6, "balanc": [6, 7], "forc": 6, "size": [6, 7], "perfectli": [6, 7], "fraction": [6, 7], "misclassified_count": 6, "whether": 6, "otherwis": 6, "quiet": 6, "learning_set": 6, "ucncs__strategi": 6, "transform": 6, "mrsort__strategi": 6, "top": [6, 7], "mrsort__weights_profiles_breed__target_accuraci": 6, "mrsort__weights_profiles_breed__max_iter": 6, "mrsort__weights_profiles_breed__max_iterations_without_progress": 6, "mrsort__weights_profiles_breed__max_dur": 6, "mrsort__weights_profiles_breed__max_duration_without_progress": 6, "mrsort__weights_profiles_breed__models_count": 6, "temporari": 6, "mrsort__weights_profiles_breed__initialization_strategi": 6, "mrsort__weights_profiles_breed__weights_strategi": 6, "mrsort__weights_profiles_breed__linear_program__solv": 6, "mrsort__weights_profiles_breed__profiles_strategi": 6, "mrsort__weights_profiles_breed__accuracy_heuristic__random_se": 6, "mrsort__weights_profiles_breed__accuracy_heuristic__processor": 6, "mrsort__weights_profiles_breed__breed_strategi": 6, "mrsort__weights_profiles_breed__reinitialize_least_accurate__port": 6, "stderr": 6, "while": 6, "establish": 7, "manipul": 7, "conform": 7, "20": 7, "low": 7, "medium": 7, "kei": 7, "exactli": 7, "respect": 7, "third": 7, "evolv": 7, "enumer": 7, "resp": 7, "correspond": 7, "expert": 7, "knowledg": 7, "absolut": 7, "extrem": 7, "deleg": 7, "fourth": 7, "rel": 7, "fact": 7, "technic": 7, "embed": 7, "unwant": 7, "referenc": 7, "robust": 7, "content": 7, "hash": 7, "respons": 7, "track": 7, "along": 7, "49331188": 7, "15": 7, "9249287": 7, "49812794": 7, "15932083": 7, "938825667": 7, "343733728": 7, "lack": 7, "transpos": 7, "focuss": 7, "enter": 7, "boundari": 7, "minu": 7, "matrix": 7, "made": 7, "ident": 7, "upset": 7, "anoth": 7, "8156891": 7, "39045048": 7, "25551182": 7, "45864725": 7, "18": 7, "4786396": 7, "31117153": 7, "0154629": 7, "33949804": 7, "30789757": 7, "66963387": 7, "These": 7, "reproduc": 7, "parent": 7, "left": 7, "saw": 7, "tweak": 7, "notabl": 7, "choos": 7, "randomli": 7, "category_corel": 7, "equal": 7, "hard": 7, "600": 7, "200": 7, "160": 7, "240": 7, "significantli": 7, "popul": 7, "lenient": 7, "seen": 7, "own": 7, "goe": 7, "sens": 7, "branch": 7, "realiti": 7, "dot": 7, "scheme": 7, "abil": 7, "collis": 7, "join": 7, "smaller": 7, "softwar": 7, "reus": 7, "directori": 7, "small": 7, "difficult": 7, "Or": 7, "mayb": 7, "met": 7, "exceed": 7, "googl": 7, "OR": 7, "slight": 7, "capabl": 7, "exact": 7, "pick": 7, "Not": 7, "said": 7, "tradeoff": 7, "offer": 7, "highlight": 7, "999706864": 7, "0552680492": 7, "325211823": 7, "161919117": 7, "672662616": 7, "995402098": 7, "996754646": 7, "craft": 7, "similarli": 7, "serv": 7, "correctli": 7, "creat": 7, "graphic": 7, "represent": 7, "pretti": 7, "feel": 7, "free": 7, "out": 7}, "objects": {"./publish.sh": [[3, 0, 1, "cmdoption-.-publish.sh-arg-LEVEL", "LEVEL"]], "./run-development-cycle.sh": [[3, 0, 1, "cmdoption-.-run-development-cycle.sh-doctest-option", "--doctest-option"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-forbid-chrones", "--forbid-chrones"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-forbid-gpu", "--forbid-gpu"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-single-python-version", "--single-python-version"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-long", "--skip-long"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-unit", "--skip-unit"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-stop-after-unit", "--stop-after-unit"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-unit-coverage", "--unit-coverage"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-with-docs", "--with-docs"]], "lincs-classification-accuracy": [[6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-PROBLEM", "PROBLEM"], [6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET", "TESTING_SET"]], "lincs-classify": [[6, 0, 1, "cmdoption-lincs-classify-output-alternatives", "--output-alternatives"], [6, 0, 1, "cmdoption-lincs-classify-arg-ALTERNATIVES", "ALTERNATIVES"], [6, 0, 1, "cmdoption-lincs-classify-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-classify-arg-PROBLEM", "PROBLEM"]], "lincs-generate-classification-model": [[6, 0, 1, "cmdoption-lincs-generate-classification-model-model-type", "--model-type"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-output-model", "--output-model"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs-generate-classification-model.--mrsort": [[6, 0, 1, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum", "fixed-weights-sum"]], "lincs-generate-classification-problem": [[6, 0, 1, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria", "--allow-decreasing-criteria"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-denormalized-min-max", "--denormalized-min-max"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-output-problem", "--output-problem"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT", "CATEGORIES_COUNT"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT", "CRITERIA_COUNT"]], "lincs-generate-classified-alternatives": [[6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-max-imbalance", "--max-imbalance"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-misclassified-count", "--misclassified-count"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-output-alternatives", "--output-alternatives"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT", "ALTERNATIVES_COUNT"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM", "PROBLEM"]], "lincs-info-has-gpu": [[6, 0, 1, "cmdoption-lincs-info-has-gpu-quiet", "--quiet"]], "lincs-learn-classification-model": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-model-type", "--model-type"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-output-model", "--output-model"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET", "LEARNING_SET"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs-learn-classification-model.--mrsort": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.strategy", "strategy"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.accuracy-heuristic": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor", "processor"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed", "random-seed"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy", "breed-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy", "initialization-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration", "max-duration"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress", "max-duration-without-progress"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations", "max-iterations"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress", "max-iterations-without-progress"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count", "models-count"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy", "profiles-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy", "target-accuracy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose", "verbose"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy", "weights-strategy"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.linear-program": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver", "solver"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.reinitialize-least-accurate": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion", "portion"]], "lincs-learn-classification-model.--ucncs": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-ucncs.strategy", "strategy"]], "lincs-visualize-classification-model": [[6, 0, 1, "cmdoption-lincs-visualize-classification-model-alternatives", "--alternatives"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-alternatives-count", "--alternatives-count"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT", "OUTPUT"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs": [[6, 0, 1, "cmdoption-lincs-version", "--version"]]}, "objtypes": {"0": "std:cmdoption"}, "objnames": {"0": ["std", "cmdoption", "program option"]}, "titleterms": {"contributor": [0, 3, 5], "project": [0, 5], "goal": [0, 5], "provid": [0, 5], "mcda": [0, 5], "tool": [0, 5], "usabl": [0, 5], "out": [0, 5], "box": [0, 5], "base": [0, 5, 7], "develop": [0, 3, 5], "new": [0, 3, 5], "algorithm": [0, 5], "get": [0, 4, 5], "start": [0, 4, 5], "version": [0, 1, 5], "except": [0, 5], "default": [0, 3, 5], "valu": [0, 5, 7], "file": [0, 5, 6, 7], "format": [0, 5, 6, 7], "linc": [0, 4, 5, 6, 7], "itself": [0, 5], "changelog": 1, "0": 1, "10": 1, "3": 1, "9": 1, "2": 1, "8": 1, "7": 1, "5": 1, "6": 1, "4": 1, "1": [1, 2], "conceptu": 2, "overview": 2, "notat": 2, "about": [2, 7], "classif": [2, 6, 7], "formal": 2, "definit": [2, 3], "learn": [2, 6, 7], "classifi": [2, 6, 7], "non": 2, "compensatori": 2, "sort": 2, "nc": [2, 6], "exampl": 2, "particular": 2, "case": 2, "u": 2, "c": [2, 3], "textsf": 2, "k": 2, "mr": 2, "accuraci": [2, 6, 7], "synthet": [2, 7], "data": [2, 7], "next": [2, 7], "guid": [3, 7], "do": 3, "contribut": 3, "depend": 3, "cycl": 3, "run": 3, "sh": 3, "publish": 3, "directori": 3, "structur": 3, "gener": [3, 6, 7], "design": 3, "strategi": [3, 7], "But": 3, "bewar": 3, "virtual": 3, "function": 3, "call": 3, "so": 3, "why": 3, "all": 3, "templat": 3, "how": 3, "tos": 3, "updat": 3, "document": 3, "choos": 3, "python": 3, "your": 3, "chang": 3, "tweak": 3, "an": [3, 7], "exist": 3, "add": 3, "extens": 3, "point": 3, "dynam": 3, "static": 3, "behavior": 3, "backward": 3, "compat": 3, "extern": 3, "solver": 3, "us": [4, 7], "command": [4, 6], "line": [4, 6], "interfac": [4, 6], "what": [4, 7], "now": 4, "readm": 5, "refer": 6, "The": 6, "problem": [6, 7], "model": [6, 7], "altern": [6, 7], "info": 6, "ha": 6, "gpu": 6, "visual": [6, 7], "user": 7, "criteria": 7, "categori": 7, "accept": 7, "suffici": 7, "coalit": 7, "comment": 7, "random": 7, "whole": 7, "tree": 7, "option": 7, "avail": 7, "sub": 7, "weight": 7, "profil": 7, "breed": 7, "wpb": 7, "termin": 7, "step": 7, "sat": 7, "comput": 7, "": 7}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 58}, "alltitles": {"Contributors": [[0, "contributors"], [5, "contributors"]], "Project goals": [[0, "project-goals"], [5, "project-goals"]], "Provide MCDA tools usable out of the box": [[0, "provide-mcda-tools-usable-out-of-the-box"], [5, "provide-mcda-tools-usable-out-of-the-box"]], "Provide a base for developing new MCDA algorithms": [[0, "provide-a-base-for-developing-new-mcda-algorithms"], [5, "provide-a-base-for-developing-new-mcda-algorithms"]], "Get started": [[0, "get-started"], [4, "get-started"], [5, "get-started"]], "Versioning": [[0, "versioning"], [5, "versioning"]], "Exceptions": [[0, "exceptions"], [5, "exceptions"]], "Default values": [[0, "default-values"], [5, "default-values"]], "File formats": [[0, "file-formats"], [5, "file-formats"], [6, "file-formats"]], "Develop lincs itself": [[0, "develop-lincs-itself"], [5, "develop-lincs-itself"]], "Get lincs": [[4, "get-lincs"]], "Start using lincs\u2019 command-line interface": [[4, "start-using-lincs-command-line-interface"]], "What now?": [[4, "what-now"]], "README": [[5, "readme"]], "Changelog": [[1, "changelog"]], "Versions 0.10.0 to 0.10.3": [[1, "versions-0-10-0-to-0-10-3"]], "Versions 0.9.0 to 0.9.2": [[1, "versions-0-9-0-to-0-9-2"]], "Version 0.8.7": [[1, "version-0-8-7"]], "Versions 0.8.5 to 0.8.6": [[1, "versions-0-8-5-to-0-8-6"]], "Versions 0.8.0 to 0.8.4": [[1, "versions-0-8-0-to-0-8-4"]], "Version 0.7.0": [[1, "version-0-7-0"]], "Version 0.6.0": [[1, "version-0-6-0"]], "Version 0.5.1": [[1, "version-0-5-1"]], "Version 0.5.0": [[1, "version-0-5-0"]], "Version 0.4.5": [[1, "version-0-4-5"]], "Versions 0.4.1 to 0.4.4": [[1, "versions-0-4-1-to-0-4-4"]], "Version 0.4.0": [[1, "version-0-4-0"]], "Versions 0.3.4 to 0.3.7": [[1, "versions-0-3-4-to-0-3-7"]], "Version 0.3.3": [[1, "version-0-3-3"]], "Version 0.3.2": [[1, "version-0-3-2"]], "Version 0.3.1": [[1, "version-0-3-1"]], "Version 0.3.0": [[1, "version-0-3-0"]], "Version 0.2.2": [[1, "version-0-2-2"]], "Version 0.2.1": [[1, "version-0-2-1"]], "Version 0.2.0": [[1, "version-0-2-0"]], "Version 0.1.3": [[1, "version-0-1-3"]], "Contributor guide": [[3, "contributor-guide"]], "Do contribute!": [[3, "do-contribute"]], "Development dependencies": [[3, "development-dependencies"]], "Development cycle": [[3, "development-cycle"]], "./run-development-cycle.sh": [[3, "run-development-cycle-sh"]], "./publish.sh": [[3, "publish-sh"]], "Directory structure": [[3, "directory-structure"]], "General design": [[3, "general-design"]], "Strategies": [[3, "strategies"], [7, "strategies"]], "But beware of virtual function calls": [[3, "but-beware-of-virtual-function-calls"]], "So, why not all templates?": [[3, "so-why-not-all-templates"]], "How-tos": [[3, "how-tos"]], "Update the documentation": [[3, "update-the-documentation"]], "Choose Python or C++ for your change": [[3, "choose-python-or-c-for-your-change"]], "Tweak an existing strategy": [[3, "tweak-an-existing-strategy"]], "Add a new strategy": [[3, "add-a-new-strategy"]], "Add a new extension point": [[3, "add-a-new-extension-point"]], "Dynamic or static?": [[3, "dynamic-or-static"]], "Definition of an dynamic extension point": [[3, "definition-of-an-dynamic-extension-point"]], "Definition of an static extension point": [[3, "definition-of-an-static-extension-point"]], "Default behavior for backward compatibility": [[3, "default-behavior-for-backward-compatibility"]], "Add an external solver": [[3, "add-an-external-solver"]], "Conceptual overview": [[2, "conceptual-overview"]], "Notation": [[2, "notation"]], "About classification": [[2, "about-classification"]], "Formal definition": [[2, null], [2, null], [2, null], [2, null], [2, null]], "Learning and classifying": [[2, "learning-and-classifying"]], "Non-compensatory sorting (NCS)": [[2, "non-compensatory-sorting-ncs"]], "Example": [[2, "example"], [2, "id1"]], "Particular cases": [[2, "particular-cases"]], "U^c \\textsf{-} NCS": [[2, "u-c-textsf-ncs"]], "1 \\textsf{-} U^c \\textsf{-} NCS a.k.a. MR-Sort": [[2, "textsf-u-c-textsf-ncs-a-k-a-mr-sort"]], "Classification accuracy": [[2, "classification-accuracy"]], "Synthetic data": [[2, "synthetic-data"]], "Next": [[2, "next"]], "User Guide": [[7, "user-guide"]], "Formatting data for lincs": [[7, "formatting-data-for-lincs"]], "\u201cProblem\u201d files": [[7, "problem-files"]], "Criteria": [[7, "criteria"]], "Categories": [[7, "categories"]], "\u201cModel\u201d files": [[7, "model-files"]], "Accepted values": [[7, "accepted-values"]], "Sufficient coalitions": [[7, "sufficient-coalitions"]], "\u201cAlternatives\u201d files": [[7, "alternatives-files"]], "Comments in generated files": [[7, "comments-in-generated-files"]], "Generating synthetic data": [[7, "generating-synthetic-data"]], "About randomness": [[7, "about-randomness"]], "Generating a problem": [[7, "generating-a-problem"]], "Generating a model": [[7, "generating-a-model"]], "Generating alternatives": [[7, "generating-alternatives"]], "Learning a model": [[7, "learning-a-model"]], "An whole tree of options": [[7, "an-whole-tree-of-options"]], "Available learning (sub-)strategies": [[7, "available-learning-sub-strategies"]], "Weights, profiles, breed (WPB)": [[7, "weights-profiles-breed-wpb"]], "General options": [[7, "general-options"]], "Termination": [[7, "termination"]], "\u201cWeights\u201d step": [[7, "weights-step"]], "\u201cProfiles\u201d step": [[7, "profiles-step"]], "\u201cBreed\u201d step": [[7, "breed-step"]], "SAT-based strategies": [[7, "sat-based-strategies"]], "Using a model": [[7, "using-a-model"]], "Classifying alternatives": [[7, "classifying-alternatives"]], "Computing a classification accuracy": [[7, "computing-a-classification-accuracy"]], "Visualizing a model and alternatives": [[7, "visualizing-a-model-and-alternatives"]], "What\u2019s next?": [[7, "what-s-next"]], "Reference": [[6, "reference"]], "The problem file": [[6, "the-problem-file"]], "The NCS model file": [[6, "the-ncs-model-file"]], "The alternatives file": [[6, "the-alternatives-file"]], "Command-line interface": [[6, "command-line-interface"]], "lincs": [[6, "lincs"]], "classification-accuracy": [[6, "lincs-classification-accuracy"]], "classify": [[6, "lincs-classify"]], "generate": [[6, "lincs-generate"]], "classification-model": [[6, "lincs-generate-classification-model"], [6, "lincs-learn-classification-model"], [6, "lincs-visualize-classification-model"]], "classification-problem": [[6, "lincs-generate-classification-problem"]], "classified-alternatives": [[6, "lincs-generate-classified-alternatives"]], "info": [[6, "lincs-info"]], "has-gpu": [[6, "lincs-info-has-gpu"]], "learn": [[6, "lincs-learn"]], "visualize": [[6, "lincs-visualize"]]}, "indexentries": {"--doctest-option": [[3, "cmdoption-.-run-development-cycle.sh-doctest-option"]], "--forbid-chrones": [[3, "cmdoption-.-run-development-cycle.sh-forbid-chrones"]], "--forbid-gpu": [[3, "cmdoption-.-run-development-cycle.sh-forbid-gpu"]], "--single-python-version": [[3, "cmdoption-.-run-development-cycle.sh-single-python-version"]], "--skip-long": [[3, "cmdoption-.-run-development-cycle.sh-skip-long"]], "--skip-unit": [[3, "cmdoption-.-run-development-cycle.sh-skip-unit"]], "--stop-after-unit": [[3, "cmdoption-.-run-development-cycle.sh-stop-after-unit"]], "--unit-coverage": [[3, "cmdoption-.-run-development-cycle.sh-unit-coverage"]], "--with-docs": [[3, "cmdoption-.-run-development-cycle.sh-with-docs"]], "./publish.sh command line option": [[3, "cmdoption-.-publish.sh-arg-LEVEL"]], "./run-development-cycle.sh command line option": [[3, "cmdoption-.-run-development-cycle.sh-doctest-option"], [3, "cmdoption-.-run-development-cycle.sh-forbid-chrones"], [3, "cmdoption-.-run-development-cycle.sh-forbid-gpu"], [3, "cmdoption-.-run-development-cycle.sh-single-python-version"], [3, "cmdoption-.-run-development-cycle.sh-skip-long"], [3, "cmdoption-.-run-development-cycle.sh-skip-unit"], [3, "cmdoption-.-run-development-cycle.sh-stop-after-unit"], [3, "cmdoption-.-run-development-cycle.sh-unit-coverage"], [3, "cmdoption-.-run-development-cycle.sh-with-docs"]], "level": [[3, "cmdoption-.-publish.sh-arg-LEVEL"]], "--allow-decreasing-criteria": [[6, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria"]], "--alternatives": [[6, "cmdoption-lincs-visualize-classification-model-alternatives"]], "--alternatives-count": [[6, "cmdoption-lincs-visualize-classification-model-alternatives-count"]], "--denormalized-min-max": [[6, "cmdoption-lincs-generate-classification-problem-denormalized-min-max"]], "--max-imbalance": [[6, "cmdoption-lincs-generate-classified-alternatives-max-imbalance"]], "--misclassified-count": [[6, "cmdoption-lincs-generate-classified-alternatives-misclassified-count"]], "--model-type": [[6, "cmdoption-lincs-generate-classification-model-model-type"], [6, "cmdoption-lincs-learn-classification-model-model-type"]], "--mrsort.fixed-weights-sum": [[6, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum"]], "--mrsort.strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.strategy"]], "--mrsort.weights-profiles-breed.accuracy-heuristic.processor": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor"]], "--mrsort.weights-profiles-breed.accuracy-heuristic.random-seed": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed"]], "--mrsort.weights-profiles-breed.breed-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy"]], "--mrsort.weights-profiles-breed.initialization-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy"]], "--mrsort.weights-profiles-breed.linear-program.solver": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver"]], "--mrsort.weights-profiles-breed.max-duration": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration"]], "--mrsort.weights-profiles-breed.max-duration-without-progress": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress"]], "--mrsort.weights-profiles-breed.max-iterations": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations"]], "--mrsort.weights-profiles-breed.max-iterations-without-progress": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress"]], "--mrsort.weights-profiles-breed.models-count": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count"]], "--mrsort.weights-profiles-breed.profiles-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy"]], "--mrsort.weights-profiles-breed.reinitialize-least-accurate.portion": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion"]], "--mrsort.weights-profiles-breed.target-accuracy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy"]], "--mrsort.weights-profiles-breed.verbose": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose"]], "--mrsort.weights-profiles-breed.weights-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy"]], "--output-alternatives": [[6, "cmdoption-lincs-classify-output-alternatives"], [6, "cmdoption-lincs-generate-classified-alternatives-output-alternatives"]], "--output-model": [[6, "cmdoption-lincs-generate-classification-model-output-model"], [6, "cmdoption-lincs-learn-classification-model-output-model"]], "--output-problem": [[6, "cmdoption-lincs-generate-classification-problem-output-problem"]], "--quiet": [[6, "cmdoption-lincs-info-has-gpu-quiet"]], "--random-seed": [[6, "cmdoption-lincs-generate-classification-model-random-seed"], [6, "cmdoption-lincs-generate-classification-problem-random-seed"], [6, "cmdoption-lincs-generate-classified-alternatives-random-seed"]], "--ucncs.strategy": [[6, "cmdoption-lincs-learn-classification-model-ucncs.strategy"]], "--version": [[6, "cmdoption-lincs-version"]], "alternatives": [[6, "cmdoption-lincs-classify-arg-ALTERNATIVES"]], "alternatives_count": [[6, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT"]], "categories_count": [[6, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT"]], "criteria_count": [[6, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT"]], "learning_set": [[6, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET"]], "model": [[6, "cmdoption-lincs-classification-accuracy-arg-MODEL"], [6, "cmdoption-lincs-classify-arg-MODEL"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL"], [6, "cmdoption-lincs-visualize-classification-model-arg-MODEL"]], "output": [[6, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT"]], "problem": [[6, "cmdoption-lincs-classification-accuracy-arg-PROBLEM"], [6, "cmdoption-lincs-classify-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM"], [6, "cmdoption-lincs-learn-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM"]], "testing_set": [[6, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET"]], "lincs command line option": [[6, "cmdoption-lincs-version"]], "lincs-classification-accuracy command line option": [[6, "cmdoption-lincs-classification-accuracy-arg-MODEL"], [6, "cmdoption-lincs-classification-accuracy-arg-PROBLEM"], [6, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET"]], "lincs-classify command line option": [[6, "cmdoption-lincs-classify-arg-ALTERNATIVES"], [6, "cmdoption-lincs-classify-arg-MODEL"], [6, "cmdoption-lincs-classify-arg-PROBLEM"], [6, "cmdoption-lincs-classify-output-alternatives"]], "lincs-generate-classification-model command line option": [[6, "cmdoption-lincs-generate-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classification-model-model-type"], [6, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum"], [6, "cmdoption-lincs-generate-classification-model-output-model"], [6, "cmdoption-lincs-generate-classification-model-random-seed"]], "lincs-generate-classification-problem command line option": [[6, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria"], [6, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT"], [6, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT"], [6, "cmdoption-lincs-generate-classification-problem-denormalized-min-max"], [6, "cmdoption-lincs-generate-classification-problem-output-problem"], [6, "cmdoption-lincs-generate-classification-problem-random-seed"]], "lincs-generate-classified-alternatives command line option": [[6, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classified-alternatives-max-imbalance"], [6, "cmdoption-lincs-generate-classified-alternatives-misclassified-count"], [6, "cmdoption-lincs-generate-classified-alternatives-output-alternatives"], [6, "cmdoption-lincs-generate-classified-alternatives-random-seed"]], "lincs-info-has-gpu command line option": [[6, "cmdoption-lincs-info-has-gpu-quiet"]], "lincs-learn-classification-model command line option": [[6, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET"], [6, "cmdoption-lincs-learn-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-learn-classification-model-model-type"], [6, "cmdoption-lincs-learn-classification-model-mrsort.strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy"], [6, "cmdoption-lincs-learn-classification-model-output-model"], [6, "cmdoption-lincs-learn-classification-model-ucncs.strategy"]], "lincs-visualize-classification-model command line option": [[6, "cmdoption-lincs-visualize-classification-model-alternatives"], [6, "cmdoption-lincs-visualize-classification-model-alternatives-count"], [6, "cmdoption-lincs-visualize-classification-model-arg-MODEL"], [6, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT"], [6, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM"]]}}) \ No newline at end of file +Search.setIndex({"docnames": ["README", "changelog", "conceptual-overview", "contributor-guide", "get-started", "index", "reference", "user-guide"], "filenames": ["README.rst", "changelog.rst", "conceptual-overview.rst", "contributor-guide.rst", "get-started.rst", "index.rst", "reference.rst", "user-guide.rst"], "titles": ["Contributors", "Changelog", "Conceptual overview", "Contributor guide", "Get started", "README", "Reference", "User Guide"], "terms": {"learn": [0, 1, 3, 4, 5], "infer": [0, 4, 5, 6], "non": [0, 4, 5, 6], "compensatori": [0, 4, 5, 6], "sort": [0, 1, 4, 5, 6, 7], "i": [0, 1, 2, 3, 4, 5, 6, 7], "collect": [0, 5], "command": [0, 1, 3, 5, 7], "line": [0, 1, 3, 5, 7], "util": [0, 4, 5], "support": [0, 1, 5, 6, 7], "linux": [0, 1, 4, 5, 7], "maco": [0, 1, 4, 5, 7], "window": [0, 1, 4, 5, 7], "gpu": [0, 1, 3, 5, 7], "ar": [0, 1, 2, 3, 4, 5, 6, 7], "avail": [0, 5], "becaus": [0, 2, 3, 4, 5, 7], "cuda": [0, 1, 2, 3, 5, 6, 7], "On": [0, 3, 5], "3": [0, 2, 4, 5, 7], "os": [0, 5], "onli": [0, 1, 2, 3, 4, 5, 6, 7], "x86_64": [0, 4, 5], "cpu": [0, 1, 3, 4, 5, 6, 7], "licens": [0, 1, 5], "under": [0, 3, 5], "gnu": [0, 5], "lesser": [0, 5], "gener": [0, 1, 2, 4, 5], "public": [0, 1, 5], "v3": [0, 5], "0": [0, 2, 4, 5, 6, 7], "indic": [0, 5, 7], "two": [0, 2, 4, 5, 7], "copi": [0, 5], "instal": [0, 1, 3, 4, 5], "from": [0, 1, 2, 3, 4, 5, 6, 7], "python": [0, 1, 2, 4, 5], "packag": [0, 1, 3, 4, 5], "index": [0, 2, 3, 5], "Its": [0, 2, 5, 6, 7], "document": [0, 1, 2, 4, 5, 7], "its": [0, 2, 3, 4, 5, 6, 7], "sourc": [0, 3, 4, 5, 6], "code": [0, 1, 3, 5, 6, 7], "github": [0, 3, 4, 5, 6], "question": [0, 2, 5, 7], "remark": [0, 5, 7], "bug": [0, 1, 3, 5], "want": [0, 2, 3, 4, 5, 7], "contribut": [0, 4, 5], "open": [0, 3, 5], "an": [0, 1, 2, 4, 5, 6], "issu": [0, 5], "discuss": [0, 3, 5], "todo": [0, 3, 4, 5], "featur": [0, 1, 3, 4, 5, 7], "later": [0, 3, 4, 5], "make": [0, 1, 3, 4, 5, 6, 7], "c": [0, 1, 5, 7], "librari": [0, 3, 5], "m1": [0, 5], "m2": [0, 5], "chip": [0, 5], "much": [0, 3, 5, 7], "arm": [0, 5], "processor": [0, 4, 5, 6, 7], "manag": [0, 1, 4, 5], "when": [0, 1, 2, 3, 5, 6, 7], "we": [0, 2, 3, 4, 5, 7], "publish": [0, 1, 5], "paper": [0, 5], "add": [0, 1, 4, 5, 6, 7], "note": [0, 2, 3, 5, 7], "ask": [0, 4, 5], "academ": [0, 2, 5], "kindli": [0, 4, 5], "cite": [0, 5], "our": [0, 2, 3, 4, 5, 7], "work": [0, 3, 4, 5], "mic": [0, 3, 5, 6], "research": [0, 5], "team": [0, 5], "centralesup\u00e9lec": [0, 5], "main": [0, 2, 3, 5], "author": [0, 5], "alphabet": [0, 5], "order": [0, 2, 4, 5, 6, 7], "laurent": [0, 5], "cabaret": [0, 5], "perform": [0, 1, 2, 3, 5, 7], "optim": [0, 3, 5, 7], "vincent": [0, 5], "jacqu": [0, 5], "engin": [0, 5], "mousseau": [0, 5], "domain": [0, 1, 5], "expertis": [0, 5], "wassila": [0, 5], "ouerdan": [0, 5], "you": [0, 2, 3, 4, 5, 6, 7], "should": [0, 2, 3, 4, 5, 6, 7], "abl": [0, 5], "us": [0, 1, 2, 3, 5, 6], "without": [0, 1, 2, 3, 5, 6, 7], "being": [0, 2, 4, 5], "specialist": [0, 5], "nc": [0, 1, 4, 5, 7], "model": [0, 1, 2, 4, 5], "just": [0, 2, 3, 5, 6, 7], "follow": [0, 1, 2, 3, 4, 5, 6, 7], "section": [0, 3, 4, 5, 7], "below": [0, 1, 5], "design": [0, 4, 5], "easi": [0, 3, 5, 7], "extend": [0, 2, 5, 6, 7], "even": [0, 3, 4, 5, 7], "replac": [0, 5], "part": [0, 1, 3, 5, 7], "exist": [0, 2, 5, 7], "see": [0, 1, 3, 4, 5, 6], "guid": [0, 1, 2, 4, 5, 6], "more": [0, 1, 2, 3, 4, 5, 7], "detail": [0, 1, 3, 4, 5, 7], "depend": [0, 1, 4, 5, 7], "your": [0, 2, 4, 5, 7], "favorit": [0, 5], "approach": [0, 1, 2, 4, 5, 6, 7], "can": [0, 2, 3, 4, 5, 6, 7], "either": [0, 5, 6, 7], "hand": [0, 5, 7], "conceptu": [0, 4, 5, 7], "overview": [0, 4, 5, 7], "The": [0, 2, 3, 4, 5, 7], "former": [0, 5], "show": [0, 4, 5, 6], "how": [0, 2, 4, 5, 7], "latter": [0, 5], "explain": [0, 3, 4, 5, 7], "concept": [0, 2, 4, 5, 7], "behind": [0, 5], "them": [0, 1, 2, 3, 4, 5, 7], "what": [0, 3, 5], "": [0, 1, 2, 3, 4, 5, 6], "etc": [0, 3, 4, 5, 7], "If": [0, 2, 3, 4, 5, 6, 7], "doubt": [0, 5], "highli": [0, 5], "recommend": [0, 2, 3, 4, 5, 7], "read": [0, 2, 3, 4, 5, 6, 7], "other": [0, 2, 3, 5, 7], "one": [0, 2, 3, 4, 5, 6, 7], "after": [0, 1, 3, 5, 7], "onc": [0, 3, 4, 5], "ve": [0, 4, 5, 7], "bit": [0, 5, 7], "up": [0, 2, 3, 4, 5, 6, 7], "user": [0, 1, 3, 4, 5, 6], "refer": [0, 4, 5, 7], "1": [0, 4, 5, 6, 7], "semant": [0, 5], "api": [0, 1, 3, 5], "must": [0, 2, 3, 4, 5, 6, 7], "declar": [0, 5], "accord": [0, 2, 5, 6, 7], "semver": [0, 5], "constitut": [0, 2, 5], "exclus": [0, 5], "level": [0, 2, 3, 5, 6, 7], "consid": [0, 2, 3, 5], "chang": [0, 1, 4, 5, 7], "backward": [0, 5, 7], "compat": [0, 5, 7], "client": [0, 5], "doesn": [0, 2, 4, 5], "t": [0, 2, 3, 4, 5, 6], "need": [0, 3, 4, 5, 7], "modifi": [0, 3, 4, 5, 7], "keep": [0, 3, 4, 5, 7], "requir": [0, 3, 4, 5, 6, 7], "recompil": [0, 5], "some": [0, 2, 3, 5, 7], "case": [0, 3, 5, 7], "futur": [0, 4, 5, 6], "might": [0, 2, 3, 5], "behavior": [0, 5, 7], "especi": [0, 5], "regard": [0, 5], "pseudo": [0, 1, 2, 4, 5, 6, 7], "random": [0, 1, 2, 4, 5, 6], "plan": [0, 5], "do": [0, 2, 4, 5, 7], "ll": [0, 2, 3, 4, 5, 7], "interfac": [0, 3, 5], "In": [0, 1, 2, 5, 7], "mean": [0, 5, 7], "time": [0, 1, 2, 3, 5, 7], "chose": [0, 5], "wai": [0, 2, 3, 4, 5, 6, 7], "expect": [0, 2, 3, 5, 7], "unanticip": [0, 5], "option": [0, 1, 3, 4, 5, 6], "argument": [0, 3, 5, 6], "thei": [0, 1, 2, 3, 4, 5, 7], "releas": [0, 1, 5], "find": [0, 2, 3, 5, 7], "better": [0, 2, 4, 5], "most": [0, 2, 3, 5, 6, 7], "advic": [0, 5], "write": [0, 3, 5, 6], "script": [0, 3, 5], "explicit": [0, 1, 3, 5, 7], "where": [0, 2, 3, 4, 5, 7], "matter": [0, 5], "reli": [0, 3, 5, 7], "implicit": [0, 5], "potenti": [0, 5], "improv": [0, 1, 5, 6, 7], "same": [0, 2, 3, 4, 5, 6, 7], "specif": [0, 3, 5, 7], "appli": [0, 2, 3, 5, 7], "produc": [0, 1, 2, 5, 7], "thi": [0, 1, 2, 3, 4, 5, 6, 7], "lead": [0, 5, 7], "about": [0, 1, 3, 4, 5, 6], "allow": [0, 1, 2, 3, 5, 6, 7], "flexibl": [0, 1, 5], "input": [0, 5, 7], "both": [0, 3, 4, 5], "old": [0, 3, 5], "But": [0, 2, 5, 7], "incompat": [0, 5], "To": [0, 2, 3, 4, 5, 7], "solv": [0, 5, 6, 7], "impos": [0, 5], "addit": [0, 2, 5, 7], "constraint": [0, 2, 5], "motiv": [0, 3, 5], "That": [0, 3, 4, 5, 7], "know": [0, 3, 5, 7], "alreadi": [0, 2, 5, 7], "so": [0, 1, 2, 4, 5, 7], "adapt": [0, 1, 5], "break": 1, "renam": [1, 7], "category_correl": 1, "preference_direct": [1, 4, 6, 7], "problem": [1, 2, 4], "file": [1, 2, 3, 4], "grow": 1, "prefer": [1, 6, 7], "direct": [1, 6, 7], "increas": [1, 4, 6, 7], "categori": [1, 2, 4, 6], "attribut": [1, 2, 7], "ordered_categori": [1, 4, 6, 7], "name": [1, 4, 6, 7], "worst": [1, 2, 4, 6], "intermedi": [1, 2, 4, 6, 7], "n": [1, 2], "best": [1, 2, 3, 4, 6, 7], "isoton": [1, 6], "resp": [1, 7], "antiton": [1, 6], "synonym": 1, "decreas": [1, 6, 7], "linc": [1, 2, 3], "describ": [1, 2, 3, 4, 7], "human": [1, 4, 6], "readabl": [1, 4, 6], "descript": [1, 2, 4, 6, 7], "remov": [1, 4], "comment": [1, 6], "termin": [1, 3, 6], "condit": [1, 7], "mrsort": [1, 3, 4, 6, 7], "weight": [1, 2, 3, 4, 6], "profil": [1, 2, 3, 4, 6], "breed": [1, 3, 4, 6], "output": [1, 4, 6, 7], "metadata": [1, 6, 7], "yaml": [1, 2, 4, 6, 7], "data": [1, 3, 4, 6], "previous": [1, 3], "found": [1, 3, 6, 7], "those": [1, 2, 3, 4, 6, 7], "provid": [1, 2, 3, 4, 6], "jupyt": [1, 4], "notebook": [1, 3, 4], "help": [1, 2, 3, 4, 7], "get": [1, 2, 3, 6], "start": [1, 2, 3, 6, 7], "all": [1, 2, 4, 6, 7], "integr": [1, 3], "test": [1, 3, 4], "extern": [1, 4], "error": 1, "ubuntu": [1, 4], "23": 1, "term": 1, "correl": 1, "wa": [1, 2, 3, 4, 6, 7], "instead": [1, 2, 3, 6, 7], "first": [1, 2, 3, 4, 6, 7], "candid": 1, "accept": [1, 6], "valu": [1, 2, 3, 4, 6], "json": [1, 6, 7], "schema": [1, 6, 7], "ucnc": [1, 6, 7], "strategi": [1, 4, 6], "altern": [1, 2, 4], "fix": [1, 3, 6, 7], "end": [1, 4], "visual": [1, 3, 4], "criteria": [1, 2, 4, 6], "min": [1, 2, 6, 7], "max": [1, 2, 3, 4, 6, 7], "valid": [1, 6, 7], "consist": [1, 2, 3, 7], "load": 1, "reproduct": [1, 4, 7], "classifi": [1, 4], "pre": [1, 2, 6], "process": [1, 6, 7], "set": [1, 2, 3, 4, 6, 7], "befor": [1, 2, 3, 6, 7], "algorithm": [1, 2, 3], "possibl": [1, 2, 3], "each": [1, 2, 3, 4, 6, 7], "criterion": [1, 2, 4, 6, 7], "list": [1, 7], "actual": [1, 2, 3, 6, 7], "now": [1, 2, 3, 7], "have": [1, 2, 3, 4, 6, 7], "rang": [1, 2, 7], "integ": [1, 2, 6, 7], "simplif": [1, 2], "implement": [1, 2, 3, 7], "expos": [1, 3], "sufficientcoalit": 1, "upset_root": [1, 6, 7], "imbal": [1, 4, 6, 7], "cleaner": 1, "too": [1, 2, 3, 7], "tight": 1, "print": [1, 6, 7], "number": [1, 2, 3, 4, 6, 7], "iter": [1, 3, 4, 6, 7], "wpb": [1, 2], "displai": [1, 7], "variou": 1, "compil": [1, 3, 6], "openmp": [1, 2], "distribut": 1, "binari": [1, 3, 4, 7], "wheel": [1, 3, 4, 7], "durat": [1, 2, 6, 7], "second": [1, 6, 7], "chrone": [1, 3], "verbos": [1, 6, 7], "mode": 1, "pernici": 1, "memori": [1, 2], "bugfix": 1, "sure": [1, 6, 7], "built": [1, 3, 7], "build": [1, 3, 4], "nvcc": 1, "e": [1, 2, 3, 6, 7], "g": [1, 3, 6, 7], "info": [1, 4, 7], "ha": [1, 2, 3, 4, 7], "classif": [1, 3, 4], "sat": [1, 2, 3, 6], "coalit": [1, 2, 4, 6], "separ": [1, 2, 6, 7], "hopefulli": 1, "correct": [1, 3, 7], "anchor": [1, 7], "alias": 1, "limit": [1, 7], "repetit": [1, 7], "format": [1, 2, 4], "u": [1, 3, 7], "textsf": [1, 7], "specifi": [1, 2, 3, 4, 6, 7], "minimum": [1, 2], "maximum": [1, 2, 6], "synthet": [1, 3, 4, 6], "denorm": [1, 6, 7], "state": 1, "re": [1, 2, 3, 4, 7], "enough": [1, 2, 3, 4], "decim": 1, "store": [1, 2], "float": [1, 7], "point": [1, 7], "avoid": [1, 3, 7], "ani": [1, 3, 4, 7], "loss": 1, "precis": 1, "log": 1, "final": [1, 2, 3, 4, 7], "accuraci": [1, 4], "buggi": 1, "method": [1, 2, 7], "misclassify_altern": 1, "synthes": 1, "nois": [1, 7], "expend": 1, "suffici": [1, 2, 4, 6], "root": [1, 3, 6, 7], "manylinux_2_31": 1, "flow": 1, "arrai": [1, 6], "scalar": 1, "between": [1, 2, 3, 4, 6, 7], "yet": [1, 2, 4, 7], "though": [1, 7], "control": [1, 7], "over": 1, "expans": 1, "except": 1, "fail": [1, 2], "develop": [1, 2], "machin": [1, 3, 7], "never": 1, "properli": 1, "heurist": [1, 2, 4, 6, 7], "introduc": [1, 2, 3, 7], "alglib": [1, 3, 6, 7], "lp": [1, 3], "solver": [1, 4, 6, 7], "docker": [1, 3], "imag": [1, 3, 6], "everywher": [1, 3], "lgplv3": 1, "miss": [1, 4], "header": [1, 6, 7], "mr": [1, 4, 7], "sobri": [1, 2], "sum": [1, 2, 6, 7], "pypi": [1, 3, 4], "websit": 1, "kick": 1, "off": 1, "effort": [1, 7], "quit": [1, 2, 3, 4, 7], "nice": 1, "readm": [1, 3, 7], "initi": [1, 4, 6, 7], "littl": 1, "function": [1, 2], "denot": 2, "interv": 2, "b": 2, "includ": [2, 4, 7], "often": [2, 3, 4, 7], "zero": [2, 7], "choic": [2, 3, 7], "match": 2, "convent": 2, "program": [2, 3, 4, 6, 7], "languag": [2, 3], "close": [2, 4], "For": [2, 3, 4, 6, 7], "4": [2, 4, 7], "2": [2, 4, 6, 7], "contain": [2, 3, 4, 6, 7], "element": [2, 7], "given": [2, 7], "subset": [2, 7], "power": 2, "mathcal": 2, "p": 2, "focus": 2, "task": [2, 3], "possibli": 2, "assign": 2, "base": [2, 3, 4, 6], "itself": [2, 4, 6], "vocabulari": 2, "voluntarili": 2, "abstract": [2, 3], "wide": 2, "applic": 2, "concret": [2, 3], "let": [2, 7], "sai": 2, "scholarship": 2, "student": 2, "fund": 2, "polici": 2, "grade": 2, "And": [2, 3, 4, 7], "favor": [2, 7], "younger": 2, "come": [2, 7], "modest": 2, "background": 2, "differ": [2, 3, 4, 6, 7], "topic": 2, "ag": 2, "famili": 2, "incom": 2, "could": [2, 3, 4, 7], "triag": 2, "patient": 2, "hospit": 2, "vital": 2, "sign": 2, "A": [2, 3, 7], "defin": [2, 3, 7], "mathbb": 2, "geq": 2, "x_i": 2, "_": 2, "total": [2, 7], "preccurlyeq_i": 2, "h": 2, "prec": 2, "confus": 2, "expon": 2, "cartesian": [2, 3], "product": [2, 3], "x": 2, "prod_": 2, "x_0": 2, "x_": 2, "inform": [2, 4, 6], "csv": [2, 4, 6, 7], "autom": 2, "new": [2, 4, 7], "call": [2, 7], "train": [2, 4, 6], "ground": 2, "truth": [2, 6, 7], "phase": 2, "f": 2, "rightarrow": 2, "parametr": 2, "form": [2, 3, 7], "paramet": [2, 3], "fit": [2, 3], "higher": [2, 4, 7], "sometim": 2, "import": [2, 3, 7], "compens": 2, "captur": [2, 7], "idea": [2, 3], "There": [2, 4], "mani": [2, 6, 7], "share": 2, "vari": 2, "were": [2, 7], "deni": 2, "bouyssou": 2, "thierri": 2, "marchant": 2, "articl": 2, "axiomat": 2, "noncompensatori": 2, "mcdm": 2, "ii": 2, "than": [2, 3, 4, 7], "lower": [2, 7], "It": [2, 3, 4, 6, 7], "good": [2, 3, 7], "abov": [2, 3, 7], "sever": [2, 3, 7], "reach": [2, 6, 7], "singl": [2, 3, 4, 6, 7], "addition": 2, "h_0": 2, "h_": 2, "still": [2, 3], "subseteq": 2, "With": [2, 7], "h_i": 2, "_i": 2, "inclus": 2, "imbric": 2, "supseteq": 2, "which": [2, 3, 4, 7], "default": [2, 4, 6, 7], "mapsto": 2, "cup": 2, "succcurlyeq_i": 2, "natur": [2, 3], "simplifi": 2, "mai": [2, 3, 4, 6, 7], "slightli": 2, "equival": 2, "somewhat": [2, 3, 7], "simpl": [2, 7], "well": [2, 3], "ensur": [2, 4, 6, 7], "behav": [2, 4], "intuit": 2, "ness": 2, "few": [2, 3, 4, 7], "upper": [2, 4, 7], "select": [2, 3, 7], "ones": [2, 7], "continu": 2, "three": [2, 7], "partial": [2, 4], "full": [2, 3], "further": 2, "thing": [2, 3], "sacrif": 2, "interest": 2, "four": 2, "math": 2, "m": [2, 4], "physic": [2, 7], "literatur": 2, "l": 2, "histori": 2, "normal": 2, "forget": 2, "clariti": 2, "x_m": 2, "x_p": 2, "x_l": 2, "x_h": 2, "1_m": 2, "1_p": 2, "1_l": 2, "1_h": 2, "6": 2, "55": 2, "7": [2, 7], "5": [2, 4, 6, 7], "2_m": 2, "2_p": 2, "2_l": 2, "2_h": 2, "75": 2, "9": [2, 4, 6, 7], "8": 2, "65": 2, "check": [2, 3, 6, 7], "satisfi": [2, 6], "1_i": 2, "2_i": 2, "look": [2, 3, 4], "like": [2, 3, 4, 7], "repres": [2, 6], "lattic": 2, "arrow": 2, "materi": 2, "relationship": 2, "black": 2, "grei": 2, "here": [2, 3, 7], "els": [2, 3], "ye": 2, "unus": 2, "85": 2, "No": 2, "d": [2, 3], "none": 2, "prose": 2, "formul": 2, "who": 2, "excel": 2, "least": [2, 3, 4, 6, 7], "subject": 2, "scientif": 2, "literari": 2, "back": [2, 4], "common": 2, "less": [2, 3], "computation": [2, 3], "simpler": 2, "previou": [2, 3, 7], "ne": 2, "threshold": [2, 4, 6, 7], "agn\u00e8": 2, "leroi": 2, "et": 2, "al": 2, "multipl": [2, 3, 7], "w_i": 2, "sum_": 2, "again": 2, "answer": 2, "try": [2, 3, 4, 6, 7], "w_m": 2, "w_p": 2, "w_l": 2, "w_h": 2, "give": [2, 3, 6, 7], "16": [2, 4], "equat": 2, "among": [2, 7], "lt": 2, "notin": 2, "ge": 2, "last": [2, 3, 6, 7], "solut": 2, "By": [2, 3, 6, 7], "contrast": 2, "express": 2, "greater": [2, 7], "fewer": 2, "success": [2, 7], "measur": [2, 3, 4], "metric": 2, "quicker": 2, "portion": [2, 4, 6, 7], "real": [2, 4, 6, 7], "world": [2, 4, 6], "noisi": 2, "inconsist": 2, "prevent": 2, "result": [2, 3, 4, 6, 7], "imposs": 2, "100": [2, 4, 7], "summari": 2, "typic": 2, "failur": [2, 3], "quickest": 2, "noth": [2, 3], "goal": 2, "far": [2, 7], "longest": 2, "simpli": [2, 7], "anyth": [2, 3, 6], "configur": [2, 3], "take": [2, 3, 4, 7], "long": [2, 3, 4], "comput": [2, 4, 6], "resourc": 2, "alwai": [2, 7], "longer": [2, 3], "practic": 2, "ali": 2, "tlili": 2, "khale": 2, "belahc\u00e8n": 2, "effici": 2, "maxsat": 2, "conveni": 2, "gather": 2, "place": [2, 3, 4], "olivi": 2, "hi": 2, "ph": 2, "thesi": 2, "originali": 2, "emma": 2, "dixneuf": 2, "thibault": 2, "monsel": 2, "thoma": 2, "vindard": 2, "sequenti": 2, "parallel": [2, 7], "known": [2, 4], "origin": [2, 4, 7], "compar": [2, 3], "evalu": 2, "qualiti": 2, "clean": 2, "haven": [2, 4], "done": [2, 3, 4], "strongli": [3, 7], "familiar": [3, 4], "rest": 3, "project": [3, 4], "also": [3, 4, 7], "exampl": [3, 7], "talk": 3, "pleas": [3, 7], "awar": 3, "progress": [3, 6, 7], "kind": [3, 4, 6, 7], "exercis": 3, "clairvoy": 3, "predict": 3, "got": 3, "wrong": 3, "hesit": 3, "contact": 3, "begin": [3, 7], "scale": [3, 7], "minor": 3, "major": 3, "refactor": 3, "typo": 3, "web": 3, "spare": 3, "clone": 3, "repositori": 3, "think": [3, 4], "entir": [3, 7], "architectur": 3, "deserv": 3, "rewrit": 3, "http": [3, 6], "com": 3, "lab": [3, 6], "don": [3, 4, 6], "spend": 3, "someth": [3, 4], "reject": 3, "reason": [3, 7], "appar": 3, "moment": 3, "yourself": 3, "tell": [3, 4, 7], "report": 3, "everyth": [3, 7], "recogn": 3, "intimid": 3, "everyon": 3, "experi": [3, 7], "fluenci": 3, "tool": [3, 4, 6, 7], "willing": 3, "feedback": [3, 7], "assur": 3, "construct": 3, "manner": [3, 7], "similar": [3, 7], "inspir": 3, "git": 3, "grep": 3, "theoldth": 3, "thenewth": 3, "blame": 3, "identifi": [3, 7], "commit": 3, "next": 3, "recent": [3, 4], "version": [3, 4, 6, 7], "bash": 3, "nvidia": 3, "runtim": 3, "loop": [3, 7], "repeat": [3, 7], "cach": 3, "subsequ": 3, "faster": 3, "unit": 3, "speed": 3, "eventu": 3, "maintain": 3, "pull": 3, "request": 3, "doc": 3, "io": [3, 6], "page": 3, "push": 3, "impact": [3, 7], "save": 3, "submit": 3, "coverag": 3, "stop": [3, 7], "right": 3, "impli": 3, "skip": [3, 7], "cpp": 3, "unchang": 3, "diff": [3, 4], "forbid": [3, 7], "automat": 3, "warn": 3, "doe": [3, 7], "explicitli": [3, 6, 7], "doctest": 3, "doctest_opt": 3, "pass": [3, 7], "verbatim": 3, "patch": 3, "dry": 3, "thin": 3, "wrapper": 3, "basic": [3, 7], "rst": 3, "setup": 3, "py": 3, "manifest": 3, "licenc": 3, "local": 3, "render": 3, "current": [3, 4, 7], "dev": 3, "accompani": 3, "pattern": [3, 7], "inject": 3, "easili": 3, "switch": 3, "particularli": 3, "variant": 3, "benchmark": 3, "perspect": 3, "distinct": 3, "recurs": 3, "piec": 3, "learnmrsortbyweightsprofilesbre": 3, "weightsoptimizationstrategi": 3, "profilesimprovementstrategi": 3, "improveprofileswithaccuracyheuristiconcpu": 3, "improveprofileswithaccuracyheuristicongpu": 3, "costli": 3, "cost": 3, "although": 3, "care": 3, "thousand": 3, "per": [3, 4, 6, 7], "ok": 3, "polymorph": 3, "frequent": 3, "liblinc": 3, "linear": [3, 4, 6, 7], "hpp": 3, "linearprogram": 3, "One": 3, "would": [3, 7], "neg": 3, "consequ": 3, "instanti": 3, "explod": 3, "combinatori": 3, "whole": 3, "great": 3, "mainten": 3, "instanci": 3, "modul": 3, "access": 3, "custom": 3, "side": 3, "happen": 3, "restructuredtext": 3, "sphinx": 3, "extent": 3, "click": 3, "edit": [3, 4], "html": [3, 6], "browser": 3, "anticip": [3, 7], "2024": 3, "famou": 3, "word": 3, "mind": [3, 4], "written": [3, 6, 7], "partli": 3, "usabl": 3, "arguabl": [3, 7], "easier": [3, 4], "core": [3, 7], "intens": 3, "interpret": 3, "multi": 3, "thread": 3, "suggest": [3, 4], "someon": 3, "becom": 3, "counter": 3, "through": 3, "breedingstrategi": 3, "reduc": [3, 7], "high": [3, 7], "optimizeweightsusingglop": 3, "spent": 3, "locat": 3, "rare": 3, "signific": 3, "advertis": 3, "boil": 3, "down": 3, "veri": [3, 7], "effect": [3, 4, 7], "unless": 3, "clear": 3, "bilion": 3, "step": 3, "mimic": 3, "null": 3, "As": [3, 7], "via": 3, "class": 3, "duck": 3, "type": [3, 4, 6, 7], "dockerfil": 3, "foobar": 3, "typedef": 3, "liblincs_modul": 3, "__init__": 3, "command_line_interfac": 3, "txt": 3, "accordingli": 3, "procedur": 3, "0a790ef": 3, "modif": 3, "had": 3, "been": 3, "restructur": 3, "sinc": 3, "besid": 3, "run": 4, "pip": 4, "system": 4, "virtual": 4, "environ": 4, "venv": 4, "directli": 4, "pipx": 4, "enforc": 4, "refus": 4, "platform": 4, "lot": 4, "realli": 4, "go": 4, "rout": 4, "action": 4, "workflow": 4, "probabl": 4, "download": 4, "easiest": 4, "usag": 4, "arg": [4, 6], "mcda": [4, 6], "exit": [4, 6], "messag": 4, "graph": [4, 6, 7], "organ": 4, "sub": 4, "handl": [4, 6], "yml": [4, 7], "11": [4, 7], "seed": [4, 6, 7], "40": 4, "format_vers": [4, 6, 7], "value_typ": [4, 6, 7], "min_valu": [4, 6, 7], "max_valu": [4, 6, 7], "explan": 4, "particular": 4, "Then": [4, 7], "41": 4, "accepted_valu": [4, 6, 7], "255905151": 4, "676961303": 4, "0551739037": 4, "324553937": 4, "162252158": 4, "673279881": 4, "0526000932": 4, "598555863": 4, "sufficient_coalit": [4, 6, 7], "criterion_weight": [4, 6, 7], "147771254": 4, "618687689": 4, "406786472": 4, "0960085914": 4, "png": [4, 6, 7], "evolv": [4, 7], "wether": [4, 7], "uc": [4, 7], "k": 4, "boundari": [4, 7], "associ": [4, 6, 7], "15": [4, 7], "62": 4, "10": [4, 7], "whose": 4, "26": 4, "06": 4, "05": 4, "68": 4, "32": 4, "67": 4, "60": 4, "1000": 4, "split": 4, "interact": 4, "42": 4, "misclassifi": [4, 6, 7], "count": [4, 6, 7], "37454012": 4, "796543002": 4, "95071429": 4, "183434784": 4, "731993914": 4, "779690981": 4, "598658502": 4, "596850157": 4, "156018645": 4, "445832759": 4, "15599452": 4, "0999749228": 4, "0580836125": 4, "4592489": 4, "866176128": 4, "333708614": 4, "601114988": 4, "14286682": 4, "708072603": 4, "650888503": 4, "five": 4, "legend": 4, "structur": [4, 6, 7], "reconstitut": 4, "numer": [4, 7], "43": 4, "maxim": [4, 6], "discrimin": [4, 6], "glop": [4, 6, 7], "reiniti": [4, 6, 7], "accur": [4, 6, 7], "target": [4, 6, 7], "339874953": 4, "421424538": 4, "0556534864": 4, "326433569": 4, "162616938": 4, "67343241": 4, "0878681168": 4, "252649099": 4, "01327896e": 4, "999998987": 4, "howev": 4, "reclassifi": 4, "3000": 4, "522c522": 4, "520": 4, "617141366": 4, "326259822": 4, "901315808": 4, "460642993": 4, "615c615": 4, "613": 4, "547554553": 4, "0552174859": 4, "690436542": 4, "511019647": 4, "2596c2596": 4, "2594": 4, "234433308": 4, "780464768": 4, "162389532": 4, "622178912": 4, "2610c2610": 4, "2608": 4, "881479025": 4, "055544015": 4, "82936728": 4, "853676081": 4, "2996": 4, "demonstr": 4, "comfort": 4, "text": 6, "standard": [6, 7], "object": 6, "properti": 6, "string": 6, "const": 6, "item": [6, 7], "enumer": [6, 7], "enum": 6, "peak": [6, 7], "unknown": [6, 7], "additionalproperti": 6, "fals": 6, "minitem": 6, "determin": [6, 7], "oneof": 6, "lowest": 6, "comma": 6, "ignor": [6, 7], "quot": 6, "whitespac": 6, "column": [6, 7], "Their": 6, "empti": [6, 7], "unclassifi": 6, "testing_set": 6, "output_altern": 6, "output_descript": 6, "output_model": 6, "random_se": 6, "model_typ": 6, "mrsort__fixed_weights_sum": 6, "criteria_count": 6, "categories_count": 6, "output_problem": 6, "alternatives_count": 6, "max_imbal": 6, "balanc": [6, 7], "forc": 6, "size": [6, 7], "perfectli": [6, 7], "fraction": [6, 7], "misclassified_count": 6, "whether": 6, "return": 6, "otherwis": 6, "quiet": 6, "learning_set": 6, "ucncs__strategi": 6, "transform": 6, "mrsort__strategi": 6, "top": [6, 7], "mrsort__weights_profiles_breed__target_accuraci": 6, "mrsort__weights_profiles_breed__max_iter": 6, "mrsort__weights_profiles_breed__max_iterations_without_progress": 6, "mrsort__weights_profiles_breed__max_dur": 6, "mrsort__weights_profiles_breed__max_duration_without_progress": 6, "mrsort__weights_profiles_breed__models_count": 6, "temporari": 6, "mrsort__weights_profiles_breed__initialization_strategi": 6, "mrsort__weights_profiles_breed__weights_strategi": 6, "mrsort__weights_profiles_breed__linear_program__solv": 6, "mrsort__weights_profiles_breed__profiles_strategi": 6, "mrsort__weights_profiles_breed__accuracy_heuristic__random_se": 6, "mrsort__weights_profiles_breed__accuracy_heuristic__processor": 6, "mrsort__weights_profiles_breed__breed_strategi": 6, "mrsort__weights_profiles_breed__reinitialize_least_accurate__port": 6, "stderr": 6, "while": 6, "mrsort__weights_profiles_breed__output_metadata": 6, "establish": 7, "manipul": 7, "conform": 7, "20": 7, "low": 7, "medium": 7, "kei": 7, "exactli": 7, "respect": 7, "third": 7, "correspond": 7, "expert": 7, "knowledg": 7, "absolut": 7, "extrem": 7, "deleg": 7, "fourth": 7, "rel": 7, "fact": 7, "technic": 7, "embed": 7, "unwant": 7, "referenc": 7, "robust": 7, "content": 7, "hash": 7, "respons": 7, "track": 7, "along": 7, "49331188": 7, "9249287": 7, "49812794": 7, "15932083": 7, "938825667": 7, "343733728": 7, "lack": 7, "transpos": 7, "focuss": 7, "enter": 7, "minu": 7, "matrix": 7, "made": 7, "ident": 7, "upset": 7, "anoth": 7, "8156891": 7, "39045048": 7, "25551182": 7, "45864725": 7, "18": 7, "4786396": 7, "31117153": 7, "0154629": 7, "33949804": 7, "30789757": 7, "66963387": 7, "These": 7, "reproduc": 7, "parent": 7, "left": 7, "saw": 7, "tweak": 7, "notabl": 7, "choos": 7, "randomli": 7, "equal": 7, "hard": 7, "600": 7, "200": 7, "160": 7, "240": 7, "significantli": 7, "popul": 7, "lenient": 7, "seen": 7, "own": 7, "goe": 7, "sens": 7, "branch": 7, "realiti": 7, "dot": 7, "scheme": 7, "abil": 7, "collis": 7, "join": 7, "smaller": 7, "softwar": 7, "reus": 7, "directori": 7, "small": 7, "difficult": 7, "Or": 7, "mayb": 7, "took": 7, "met": 7, "exceed": 7, "googl": 7, "OR": 7, "slight": 7, "capabl": 7, "exact": 7, "pick": 7, "Not": 7, "said": 7, "tradeoff": 7, "offer": 7, "highlight": 7, "999706864": 7, "0552680492": 7, "325211823": 7, "161919117": 7, "672662616": 7, "995402098": 7, "996754646": 7, "craft": 7, "similarli": 7, "serv": 7, "correctli": 7, "creat": 7, "graphic": 7, "represent": 7, "pretti": 7, "feel": 7, "free": 7, "out": 7}, "objects": {"./publish.sh": [[3, 0, 1, "cmdoption-.-publish.sh-dry-run", "--dry-run"], [3, 0, 1, "cmdoption-.-publish.sh-arg-LEVEL", "LEVEL"]], "./run-development-cycle.sh": [[3, 0, 1, "cmdoption-.-run-development-cycle.sh-doctest-option", "--doctest-option"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-forbid-chrones", "--forbid-chrones"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-forbid-gpu", "--forbid-gpu"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-single-python-version", "--single-python-version"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-cpp-unit", "--skip-cpp-unit"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-long-unit", "--skip-long-unit"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-notebooks", "--skip-notebooks"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-unchanged-notebooks", "--skip-unchanged-notebooks"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-skip-unit", "--skip-unit"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-unit-coverage", "--unit-coverage"], [3, 0, 1, "cmdoption-.-run-development-cycle.sh-with-docs", "--with-docs"]], "lincs-classification-accuracy": [[6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-PROBLEM", "PROBLEM"], [6, 0, 1, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET", "TESTING_SET"]], "lincs-classify": [[6, 0, 1, "cmdoption-lincs-classify-output-alternatives", "--output-alternatives"], [6, 0, 1, "cmdoption-lincs-classify-arg-ALTERNATIVES", "ALTERNATIVES"], [6, 0, 1, "cmdoption-lincs-classify-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-classify-arg-PROBLEM", "PROBLEM"]], "lincs-describe-classification-model": [[6, 0, 1, "cmdoption-lincs-describe-classification-model-output-description", "--output-description"], [6, 0, 1, "cmdoption-lincs-describe-classification-model-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-describe-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs-describe-classification-problem": [[6, 0, 1, "cmdoption-lincs-describe-classification-problem-output-description", "--output-description"], [6, 0, 1, "cmdoption-lincs-describe-classification-problem-arg-PROBLEM", "PROBLEM"]], "lincs-generate-classification-model": [[6, 0, 1, "cmdoption-lincs-generate-classification-model-model-type", "--model-type"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-output-model", "--output-model"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs-generate-classification-model.--mrsort": [[6, 0, 1, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum", "fixed-weights-sum"]], "lincs-generate-classification-problem": [[6, 0, 1, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria", "--allow-decreasing-criteria"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-denormalized-min-max", "--denormalized-min-max"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-output-problem", "--output-problem"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT", "CATEGORIES_COUNT"], [6, 0, 1, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT", "CRITERIA_COUNT"]], "lincs-generate-classified-alternatives": [[6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-max-imbalance", "--max-imbalance"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-misclassified-count", "--misclassified-count"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-output-alternatives", "--output-alternatives"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-random-seed", "--random-seed"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT", "ALTERNATIVES_COUNT"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM", "PROBLEM"]], "lincs-info-has-gpu": [[6, 0, 1, "cmdoption-lincs-info-has-gpu-quiet", "--quiet"]], "lincs-learn-classification-model": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-model-type", "--model-type"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-output-model", "--output-model"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET", "LEARNING_SET"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs-learn-classification-model.--mrsort": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.strategy", "strategy"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.accuracy-heuristic": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor", "processor"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed", "random-seed"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy", "breed-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy", "initialization-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration", "max-duration"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress", "max-duration-without-progress"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations", "max-iterations"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress", "max-iterations-without-progress"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count", "models-count"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.output-metadata", "output-metadata"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy", "profiles-strategy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy", "target-accuracy"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose", "verbose"], [6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy", "weights-strategy"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.linear-program": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver", "solver"]], "lincs-learn-classification-model.--mrsort.weights-profiles-breed.reinitialize-least-accurate": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion", "portion"]], "lincs-learn-classification-model.--ucncs": [[6, 0, 1, "cmdoption-lincs-learn-classification-model-ucncs.strategy", "strategy"]], "lincs-visualize-classification-model": [[6, 0, 1, "cmdoption-lincs-visualize-classification-model-alternatives", "--alternatives"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-alternatives-count", "--alternatives-count"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-MODEL", "MODEL"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT", "OUTPUT"], [6, 0, 1, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM", "PROBLEM"]], "lincs": [[6, 0, 1, "cmdoption-lincs-version", "--version"]]}, "objtypes": {"0": "std:cmdoption"}, "objnames": {"0": ["std", "cmdoption", "program option"]}, "titleterms": {"contributor": [0, 3, 5], "project": [0, 5], "goal": [0, 5], "provid": [0, 5], "mcda": [0, 5], "tool": [0, 5], "usabl": [0, 5], "out": [0, 5], "box": [0, 5], "base": [0, 5, 7], "develop": [0, 3, 5], "new": [0, 3, 5], "algorithm": [0, 5], "get": [0, 4, 5, 7], "start": [0, 4, 5], "version": [0, 1, 5], "except": [0, 5], "default": [0, 3, 5], "valu": [0, 5, 7], "file": [0, 5, 6, 7], "format": [0, 5, 6, 7], "linc": [0, 4, 5, 6, 7], "itself": [0, 5], "changelog": 1, "0": 1, "11": 1, "10": 1, "3": 1, "9": 1, "2": 1, "8": 1, "7": 1, "5": 1, "6": 1, "4": 1, "1": [1, 2], "conceptu": 2, "overview": 2, "notat": 2, "about": [2, 7], "classif": [2, 6, 7], "formal": 2, "definit": [2, 3], "learn": [2, 6, 7], "classifi": [2, 6, 7], "non": 2, "compensatori": 2, "sort": 2, "nc": [2, 6], "exampl": 2, "particular": 2, "case": 2, "u": 2, "c": [2, 3], "textsf": 2, "k": 2, "mr": 2, "accuraci": [2, 6, 7], "synthet": [2, 7], "data": [2, 7], "next": [2, 7], "guid": [3, 7], "do": 3, "contribut": 3, "depend": 3, "cycl": 3, "run": 3, "sh": 3, "publish": 3, "directori": 3, "structur": 3, "gener": [3, 6, 7], "design": 3, "strategi": [3, 7], "But": 3, "bewar": 3, "virtual": 3, "function": 3, "call": 3, "so": 3, "why": 3, "all": 3, "templat": 3, "how": 3, "tos": 3, "updat": 3, "document": 3, "choos": 3, "python": 3, "your": 3, "chang": 3, "tweak": 3, "an": [3, 7], "exist": 3, "add": 3, "extens": 3, "point": 3, "dynam": 3, "static": 3, "behavior": 3, "backward": 3, "compat": 3, "extern": 3, "solver": 3, "us": [4, 7], "command": [4, 6], "line": [4, 6], "interfac": [4, 6], "what": [4, 7], "now": 4, "readm": 5, "refer": 6, "The": 6, "problem": [6, 7], "model": [6, 7], "altern": [6, 7], "describ": 6, "info": 6, "ha": 6, "gpu": 6, "visual": [6, 7], "user": 7, "criteria": 7, "categori": 7, "accept": 7, "suffici": 7, "coalit": 7, "comment": 7, "random": 7, "whole": 7, "tree": 7, "option": 7, "avail": 7, "sub": 7, "weight": 7, "profil": 7, "breed": 7, "wpb": 7, "termin": 7, "step": 7, "sat": 7, "comput": 7, "human": 7, "readabl": 7, "inform": 7, "": 7}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 58}, "alltitles": {"Contributors": [[0, "contributors"], [5, "contributors"]], "Project goals": [[0, "project-goals"], [5, "project-goals"]], "Provide MCDA tools usable out of the box": [[0, "provide-mcda-tools-usable-out-of-the-box"], [5, "provide-mcda-tools-usable-out-of-the-box"]], "Provide a base for developing new MCDA algorithms": [[0, "provide-a-base-for-developing-new-mcda-algorithms"], [5, "provide-a-base-for-developing-new-mcda-algorithms"]], "Get started": [[0, "get-started"], [4, "get-started"], [5, "get-started"]], "Versioning": [[0, "versioning"], [5, "versioning"]], "Exceptions": [[0, "exceptions"], [5, "exceptions"]], "Default values": [[0, "default-values"], [5, "default-values"]], "File formats": [[0, "file-formats"], [5, "file-formats"], [6, "file-formats"]], "Develop lincs itself": [[0, "develop-lincs-itself"], [5, "develop-lincs-itself"]], "Changelog": [[1, "changelog"]], "Version 0.11.0": [[1, "version-0-11-0"]], "Versions 0.10.0 to 0.10.3": [[1, "versions-0-10-0-to-0-10-3"]], "Versions 0.9.0 to 0.9.2": [[1, "versions-0-9-0-to-0-9-2"]], "Version 0.8.7": [[1, "version-0-8-7"]], "Versions 0.8.5 to 0.8.6": [[1, "versions-0-8-5-to-0-8-6"]], "Versions 0.8.0 to 0.8.4": [[1, "versions-0-8-0-to-0-8-4"]], "Version 0.7.0": [[1, "version-0-7-0"]], "Version 0.6.0": [[1, "version-0-6-0"]], "Version 0.5.1": [[1, "version-0-5-1"]], "Version 0.5.0": [[1, "version-0-5-0"]], "Version 0.4.5": [[1, "version-0-4-5"]], "Versions 0.4.1 to 0.4.4": [[1, "versions-0-4-1-to-0-4-4"]], "Version 0.4.0": [[1, "version-0-4-0"]], "Versions 0.3.4 to 0.3.7": [[1, "versions-0-3-4-to-0-3-7"]], "Version 0.3.3": [[1, "version-0-3-3"]], "Version 0.3.2": [[1, "version-0-3-2"]], "Version 0.3.1": [[1, "version-0-3-1"]], "Version 0.3.0": [[1, "version-0-3-0"]], "Version 0.2.2": [[1, "version-0-2-2"]], "Version 0.2.1": [[1, "version-0-2-1"]], "Version 0.2.0": [[1, "version-0-2-0"]], "Version 0.1.3": [[1, "version-0-1-3"]], "Get lincs": [[4, "get-lincs"]], "Start using lincs\u2019 command-line interface": [[4, "start-using-lincs-command-line-interface"]], "What now?": [[4, "what-now"]], "README": [[5, "readme"]], "Conceptual overview": [[2, "conceptual-overview"]], "Notation": [[2, "notation"]], "About classification": [[2, "about-classification"]], "Formal definition": [[2, null], [2, null], [2, null], [2, null], [2, null]], "Learning and classifying": [[2, "learning-and-classifying"]], "Non-compensatory sorting (NCS)": [[2, "non-compensatory-sorting-ncs"]], "Example": [[2, "example"], [2, "id1"]], "Particular cases": [[2, "particular-cases"]], "U^c \\textsf{-} NCS": [[2, "u-c-textsf-ncs"]], "1 \\textsf{-} U^c \\textsf{-} NCS a.k.a. MR-Sort": [[2, "textsf-u-c-textsf-ncs-a-k-a-mr-sort"]], "Classification accuracy": [[2, "classification-accuracy"]], "Synthetic data": [[2, "synthetic-data"]], "Next": [[2, "next"]], "User Guide": [[7, "user-guide"]], "Formatting data for lincs": [[7, "formatting-data-for-lincs"]], "\u201cProblem\u201d files": [[7, "problem-files"]], "Criteria": [[7, "criteria"]], "Categories": [[7, "categories"]], "\u201cModel\u201d files": [[7, "model-files"]], "Accepted values": [[7, "accepted-values"]], "Sufficient coalitions": [[7, "sufficient-coalitions"]], "\u201cAlternatives\u201d files": [[7, "alternatives-files"]], "Comments in generated files": [[7, "comments-in-generated-files"]], "Generating synthetic data": [[7, "generating-synthetic-data"]], "About randomness": [[7, "about-randomness"]], "Generating a problem": [[7, "generating-a-problem"]], "Generating a model": [[7, "generating-a-model"]], "Generating alternatives": [[7, "generating-alternatives"]], "Learning a model": [[7, "learning-a-model"]], "An whole tree of options": [[7, "an-whole-tree-of-options"]], "Strategies": [[7, "strategies"], [3, "strategies"]], "Available learning (sub-)strategies": [[7, "available-learning-sub-strategies"]], "Weights, profiles, breed (WPB)": [[7, "weights-profiles-breed-wpb"]], "General options": [[7, "general-options"]], "Termination": [[7, "termination"]], "\u201cWeights\u201d step": [[7, "weights-step"]], "\u201cProfiles\u201d step": [[7, "profiles-step"]], "\u201cBreed\u201d step": [[7, "breed-step"]], "SAT-based strategies": [[7, "sat-based-strategies"]], "Using a model": [[7, "using-a-model"]], "Classifying alternatives": [[7, "classifying-alternatives"]], "Computing a classification accuracy": [[7, "computing-a-classification-accuracy"]], "Getting human-readable information about a problem or model": [[7, "getting-human-readable-information-about-a-problem-or-model"]], "Visualizing a model and alternatives": [[7, "visualizing-a-model-and-alternatives"]], "What\u2019s next?": [[7, "what-s-next"]], "Contributor guide": [[3, "contributor-guide"]], "Do contribute!": [[3, "do-contribute"]], "Development dependencies": [[3, "development-dependencies"]], "Development cycle": [[3, "development-cycle"]], "./run-development-cycle.sh": [[3, "run-development-cycle-sh"]], "./publish.sh": [[3, "publish-sh"]], "Directory structure": [[3, "directory-structure"]], "General design": [[3, "general-design"]], "But beware of virtual function calls": [[3, "but-beware-of-virtual-function-calls"]], "So, why not all templates?": [[3, "so-why-not-all-templates"]], "How-tos": [[3, "how-tos"]], "Update the documentation": [[3, "update-the-documentation"]], "Choose Python or C++ for your change": [[3, "choose-python-or-c-for-your-change"]], "Tweak an existing strategy": [[3, "tweak-an-existing-strategy"]], "Add a new strategy": [[3, "add-a-new-strategy"]], "Add a new extension point": [[3, "add-a-new-extension-point"]], "Dynamic or static?": [[3, "dynamic-or-static"]], "Definition of an dynamic extension point": [[3, "definition-of-an-dynamic-extension-point"]], "Definition of an static extension point": [[3, "definition-of-an-static-extension-point"]], "Default behavior for backward compatibility": [[3, "default-behavior-for-backward-compatibility"]], "Add an external solver": [[3, "add-an-external-solver"]], "Reference": [[6, "reference"]], "The problem file": [[6, "the-problem-file"]], "The NCS model file": [[6, "the-ncs-model-file"]], "The alternatives file": [[6, "the-alternatives-file"]], "Command-line interface": [[6, "command-line-interface"]], "lincs": [[6, "lincs"]], "classification-accuracy": [[6, "lincs-classification-accuracy"]], "classify": [[6, "lincs-classify"]], "describe": [[6, "lincs-describe"]], "classification-model": [[6, "lincs-describe-classification-model"], [6, "lincs-generate-classification-model"], [6, "lincs-learn-classification-model"], [6, "lincs-visualize-classification-model"]], "classification-problem": [[6, "lincs-describe-classification-problem"], [6, "lincs-generate-classification-problem"]], "generate": [[6, "lincs-generate"]], "classified-alternatives": [[6, "lincs-generate-classified-alternatives"]], "info": [[6, "lincs-info"]], "has-gpu": [[6, "lincs-info-has-gpu"]], "learn": [[6, "lincs-learn"]], "visualize": [[6, "lincs-visualize"]]}, "indexentries": {"--doctest-option": [[3, "cmdoption-.-run-development-cycle.sh-doctest-option"]], "--dry-run": [[3, "cmdoption-.-publish.sh-dry-run"]], "--forbid-chrones": [[3, "cmdoption-.-run-development-cycle.sh-forbid-chrones"]], "--forbid-gpu": [[3, "cmdoption-.-run-development-cycle.sh-forbid-gpu"]], "--single-python-version": [[3, "cmdoption-.-run-development-cycle.sh-single-python-version"]], "--skip-cpp-unit": [[3, "cmdoption-.-run-development-cycle.sh-skip-cpp-unit"]], "--skip-long-unit": [[3, "cmdoption-.-run-development-cycle.sh-skip-long-unit"]], "--skip-notebooks": [[3, "cmdoption-.-run-development-cycle.sh-skip-notebooks"]], "--skip-unchanged-notebooks": [[3, "cmdoption-.-run-development-cycle.sh-skip-unchanged-notebooks"]], "--skip-unit": [[3, "cmdoption-.-run-development-cycle.sh-skip-unit"]], "--unit-coverage": [[3, "cmdoption-.-run-development-cycle.sh-unit-coverage"]], "--with-docs": [[3, "cmdoption-.-run-development-cycle.sh-with-docs"]], "./publish.sh command line option": [[3, "cmdoption-.-publish.sh-arg-LEVEL"], [3, "cmdoption-.-publish.sh-dry-run"]], "./run-development-cycle.sh command line option": [[3, "cmdoption-.-run-development-cycle.sh-doctest-option"], [3, "cmdoption-.-run-development-cycle.sh-forbid-chrones"], [3, "cmdoption-.-run-development-cycle.sh-forbid-gpu"], [3, "cmdoption-.-run-development-cycle.sh-single-python-version"], [3, "cmdoption-.-run-development-cycle.sh-skip-cpp-unit"], [3, "cmdoption-.-run-development-cycle.sh-skip-long-unit"], [3, "cmdoption-.-run-development-cycle.sh-skip-notebooks"], [3, "cmdoption-.-run-development-cycle.sh-skip-unchanged-notebooks"], [3, "cmdoption-.-run-development-cycle.sh-skip-unit"], [3, "cmdoption-.-run-development-cycle.sh-unit-coverage"], [3, "cmdoption-.-run-development-cycle.sh-with-docs"]], "level": [[3, "cmdoption-.-publish.sh-arg-LEVEL"]], "--allow-decreasing-criteria": [[6, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria"]], "--alternatives": [[6, "cmdoption-lincs-visualize-classification-model-alternatives"]], "--alternatives-count": [[6, "cmdoption-lincs-visualize-classification-model-alternatives-count"]], "--denormalized-min-max": [[6, "cmdoption-lincs-generate-classification-problem-denormalized-min-max"]], "--max-imbalance": [[6, "cmdoption-lincs-generate-classified-alternatives-max-imbalance"]], "--misclassified-count": [[6, "cmdoption-lincs-generate-classified-alternatives-misclassified-count"]], "--model-type": [[6, "cmdoption-lincs-generate-classification-model-model-type"], [6, "cmdoption-lincs-learn-classification-model-model-type"]], "--mrsort.fixed-weights-sum": [[6, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum"]], "--mrsort.strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.strategy"]], "--mrsort.weights-profiles-breed.accuracy-heuristic.processor": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor"]], "--mrsort.weights-profiles-breed.accuracy-heuristic.random-seed": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed"]], "--mrsort.weights-profiles-breed.breed-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy"]], "--mrsort.weights-profiles-breed.initialization-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy"]], "--mrsort.weights-profiles-breed.linear-program.solver": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver"]], "--mrsort.weights-profiles-breed.max-duration": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration"]], "--mrsort.weights-profiles-breed.max-duration-without-progress": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress"]], "--mrsort.weights-profiles-breed.max-iterations": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations"]], "--mrsort.weights-profiles-breed.max-iterations-without-progress": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress"]], "--mrsort.weights-profiles-breed.models-count": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count"]], "--mrsort.weights-profiles-breed.output-metadata": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.output-metadata"]], "--mrsort.weights-profiles-breed.profiles-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy"]], "--mrsort.weights-profiles-breed.reinitialize-least-accurate.portion": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion"]], "--mrsort.weights-profiles-breed.target-accuracy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy"]], "--mrsort.weights-profiles-breed.verbose": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose"]], "--mrsort.weights-profiles-breed.weights-strategy": [[6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy"]], "--output-alternatives": [[6, "cmdoption-lincs-classify-output-alternatives"], [6, "cmdoption-lincs-generate-classified-alternatives-output-alternatives"]], "--output-description": [[6, "cmdoption-lincs-describe-classification-model-output-description"], [6, "cmdoption-lincs-describe-classification-problem-output-description"]], "--output-model": [[6, "cmdoption-lincs-generate-classification-model-output-model"], [6, "cmdoption-lincs-learn-classification-model-output-model"]], "--output-problem": [[6, "cmdoption-lincs-generate-classification-problem-output-problem"]], "--quiet": [[6, "cmdoption-lincs-info-has-gpu-quiet"]], "--random-seed": [[6, "cmdoption-lincs-generate-classification-model-random-seed"], [6, "cmdoption-lincs-generate-classification-problem-random-seed"], [6, "cmdoption-lincs-generate-classified-alternatives-random-seed"]], "--ucncs.strategy": [[6, "cmdoption-lincs-learn-classification-model-ucncs.strategy"]], "--version": [[6, "cmdoption-lincs-version"]], "alternatives": [[6, "cmdoption-lincs-classify-arg-ALTERNATIVES"]], "alternatives_count": [[6, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT"]], "categories_count": [[6, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT"]], "criteria_count": [[6, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT"]], "learning_set": [[6, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET"]], "model": [[6, "cmdoption-lincs-classification-accuracy-arg-MODEL"], [6, "cmdoption-lincs-classify-arg-MODEL"], [6, "cmdoption-lincs-describe-classification-model-arg-MODEL"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL"], [6, "cmdoption-lincs-visualize-classification-model-arg-MODEL"]], "output": [[6, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT"]], "problem": [[6, "cmdoption-lincs-classification-accuracy-arg-PROBLEM"], [6, "cmdoption-lincs-classify-arg-PROBLEM"], [6, "cmdoption-lincs-describe-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-describe-classification-problem-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM"], [6, "cmdoption-lincs-learn-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM"]], "testing_set": [[6, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET"]], "lincs command line option": [[6, "cmdoption-lincs-version"]], "lincs-classification-accuracy command line option": [[6, "cmdoption-lincs-classification-accuracy-arg-MODEL"], [6, "cmdoption-lincs-classification-accuracy-arg-PROBLEM"], [6, "cmdoption-lincs-classification-accuracy-arg-TESTING_SET"]], "lincs-classify command line option": [[6, "cmdoption-lincs-classify-arg-ALTERNATIVES"], [6, "cmdoption-lincs-classify-arg-MODEL"], [6, "cmdoption-lincs-classify-arg-PROBLEM"], [6, "cmdoption-lincs-classify-output-alternatives"]], "lincs-describe-classification-model command line option": [[6, "cmdoption-lincs-describe-classification-model-arg-MODEL"], [6, "cmdoption-lincs-describe-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-describe-classification-model-output-description"]], "lincs-describe-classification-problem command line option": [[6, "cmdoption-lincs-describe-classification-problem-arg-PROBLEM"], [6, "cmdoption-lincs-describe-classification-problem-output-description"]], "lincs-generate-classification-model command line option": [[6, "cmdoption-lincs-generate-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classification-model-model-type"], [6, "cmdoption-lincs-generate-classification-model-mrsort.fixed-weights-sum"], [6, "cmdoption-lincs-generate-classification-model-output-model"], [6, "cmdoption-lincs-generate-classification-model-random-seed"]], "lincs-generate-classification-problem command line option": [[6, "cmdoption-lincs-generate-classification-problem-allow-decreasing-criteria"], [6, "cmdoption-lincs-generate-classification-problem-arg-CATEGORIES_COUNT"], [6, "cmdoption-lincs-generate-classification-problem-arg-CRITERIA_COUNT"], [6, "cmdoption-lincs-generate-classification-problem-denormalized-min-max"], [6, "cmdoption-lincs-generate-classification-problem-output-problem"], [6, "cmdoption-lincs-generate-classification-problem-random-seed"]], "lincs-generate-classified-alternatives command line option": [[6, "cmdoption-lincs-generate-classified-alternatives-arg-ALTERNATIVES_COUNT"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-MODEL"], [6, "cmdoption-lincs-generate-classified-alternatives-arg-PROBLEM"], [6, "cmdoption-lincs-generate-classified-alternatives-max-imbalance"], [6, "cmdoption-lincs-generate-classified-alternatives-misclassified-count"], [6, "cmdoption-lincs-generate-classified-alternatives-output-alternatives"], [6, "cmdoption-lincs-generate-classified-alternatives-random-seed"]], "lincs-info-has-gpu command line option": [[6, "cmdoption-lincs-info-has-gpu-quiet"]], "lincs-learn-classification-model command line option": [[6, "cmdoption-lincs-learn-classification-model-arg-LEARNING_SET"], [6, "cmdoption-lincs-learn-classification-model-arg-PROBLEM"], [6, "cmdoption-lincs-learn-classification-model-model-type"], [6, "cmdoption-lincs-learn-classification-model-mrsort.strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.processor"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.accuracy-heuristic.random-seed"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.breed-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.initialization-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.linear-program.solver"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-duration-without-progress"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.max-iterations-without-progress"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.models-count"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.output-metadata"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.profiles-strategy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.reinitialize-least-accurate.portion"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.target-accuracy"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.verbose"], [6, "cmdoption-lincs-learn-classification-model-mrsort.weights-profiles-breed.weights-strategy"], [6, "cmdoption-lincs-learn-classification-model-output-model"], [6, "cmdoption-lincs-learn-classification-model-ucncs.strategy"]], "lincs-visualize-classification-model command line option": [[6, "cmdoption-lincs-visualize-classification-model-alternatives"], [6, "cmdoption-lincs-visualize-classification-model-alternatives-count"], [6, "cmdoption-lincs-visualize-classification-model-arg-MODEL"], [6, "cmdoption-lincs-visualize-classification-model-arg-OUTPUT"], [6, "cmdoption-lincs-visualize-classification-model-arg-PROBLEM"]]}}) \ No newline at end of file diff --git a/docs/user-guide.html b/docs/user-guide.html index f2b1d177..610b168b 100644 --- a/docs/user-guide.html +++ b/docs/user-guide.html @@ -5,11 +5,11 @@ - User Guide — lincs 0.10.3 documentation + User Guide — lincs 0.11.0 documentation - + @@ -50,15 +50,15 @@

    Formatting data for lincscriteria: - name: Criterion 1 value_type: real - category_correlation: growing + preference_direction: increasing min_value: 0 max_value: 20 - name: Criterion 2 value_type: real - category_correlation: decreasing + preference_direction: decreasing min_value: -5 max_value: 5 -categories: +ordered_categories: - name: Low - name: Medium - name: High @@ -73,13 +73,13 @@

    Criterianame.

    Currently, criteria can only take floating point values, so their value_type is always real. We expect this could evolve to also support criteria with integer or explicitly enumerated values.

    -

    Then, the category_correlation key describe what makes “good values” for this criterion. -If it is growing (resp. decreasing), then higher (resp. lower) numerical values correspond to upper categories. -Note that this correlation comes from expert knowledge about the structure of the problem, +

    Then, the preference_direction key describe what makes “good values” for this criterion. +If it is increasing (resp. decreasing), then higher (resp. lower) numerical values correspond to upper categories. +Note that this preference direction comes from expert knowledge about the structure of the problem, and will be used as an absolute truth when learning a model for this problem. -We expect the supported correlations could evolve to also support criteria with single-peaked correlation, +We expect the supported preference directions could evolve to also support single-peaked criteria, where intermediate numerical value correspond to upper categories, and extreme values to lower categories. -We also expect this could evolve to support criteria with unknown correlation, +We also expect this could evolve to support criteria with unknown preference direction, to support the case where no expert knowledge is available and delegate this choice to the learning process.

    Finally, for criteria with numerical value_type (currently all of them), the min_value and max_value keys describe the range of values the criterion can take.

    @@ -128,23 +128,23 @@

    Accepted valuesgrowing or decreasing correlation), the method is always kind: thresholds, +

    For current criteria (with increasing or decreasing preference direction), the method is always kind: thresholds, and the thresholds attribute lists the successive values required to enter an upper category. It must have as many elements as there are boundaries between categories, i.e. as there are categories minus one. -It’s always sorted, in increasing order for growing criteria and in decreasing order for decreasing criteria.

    +It’s always sorted, in increasing order for increasing criteria and in decreasing order for decreasing criteria.

    Note that this list is not a profile: it does not describe the limits between categories. The matrix made of these lists is the transposed of the matrix made of the profiles.

    -

    When we support criteria with single-peaked or unknown correlation, +

    When we support single-peaked criteria or criteria with unknown preference direction, we’ll introduce other kinds of accepted values with new attributes instead of thresholds.

    - + - + @@ -266,7 +266,7 @@

    Generating a problem
    • --denormalized-min-max generates problems with pseudo-random min_value and max_value for each criterion. By default, they are always set at 0 and 1.

    • -
    • --allow-decreasing-criteria chooses pseudo-randomly the category_corelation of each criterion between growing and decreasing. By default, all criteria have growing correlation.

    • +
    • --allow-decreasing-criteria chooses pseudo-randomly the preference_direction of each criterion between increasing and decreasing. By default, all criteria have increasing preference direction.

    @@ -356,6 +356,8 @@
    General options--mrsort.weights-profiles-breed.verbose option can be used to make lincs display information about the progress of the learning.

    +

    The --mrsort.weights-profiles-breed.output-metadata options can be used to produce a YAML file giving information about the learning process: +the reason it stopped (accuracy reached, time limit, etc.), how many WPB iterations it took, etc.

    Termination
    @@ -423,7 +425,7 @@

    SAT-based strategies

    They produce a different kind of model, with the sufficient coalitions specified explicitly by their roots:

    -

    +
    +

    Getting human-readable information about a problem or model

    +

    You can use lincs describe classification-problem problem.yml to get a human-readable description of a problem, +and lincs describe classification-model problem.yml model.yml to get one for a model, including wether it’s an MR-Sort or Uc-NCS model.

    +

    Visualizing a model and alternatives

    And you can use lincs visualize classification-model problem.yml model.yml to create a graphical representation of a model (a .png file), diff --git a/integration-tests/all-options-of-problem-generation/all-options-of-problem-generation.ipynb b/integration-tests/all-options-of-problem-generation/all-options-of-problem-generation.ipynb index 543d7cd5..309287df 100644 --- a/integration-tests/all-options-of-problem-generation/all-options-of-problem-generation.ipynb +++ b/integration-tests/all-options-of-problem-generation/all-options-of-problem-generation.ipynb @@ -10,7 +10,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 42 --denormalized-min-max --allow-decreasing-criteria\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 42 --denormalized-min-max --allow-decreasing-criteria\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", diff --git a/integration-tests/fail-generating-balanced-alternatives/fail-generating-balanced-alternatives.ipynb b/integration-tests/fail-generating-balanced-alternatives/fail-generating-balanced-alternatives.ipynb index 2803d8ea..ce1e4fb5 100644 --- a/integration-tests/fail-generating-balanced-alternatives/fail-generating-balanced-alternatives.ipynb +++ b/integration-tests/fail-generating-balanced-alternatives/fail-generating-balanced-alternatives.ipynb @@ -22,7 +22,7 @@ "output_type": "stream", "text": [ "ERROR: lincs is unable to generate a balanced set of classified alternatives. Try to increase the allowed imbalance, or use a more lenient model?\n", - "Reproduction command (with lincs version 0.10.4-dev): lincs generate classified-alternatives problem.yml model.yml 100 --random-seed 42 --max-imbalance 0.0 --misclassified-count 0\n" + "Reproduction command (with lincs version 0.11.0): lincs generate classified-alternatives problem.yml model.yml 100 --random-seed 42 --max-imbalance 0.0 --misclassified-count 0\n" ] } ], diff --git a/integration-tests/learning-failure-exception/learning-failure-exception.ipynb b/integration-tests/learning-failure-exception/learning-failure-exception.ipynb index 4729b163..5d071ea8 100644 --- a/integration-tests/learning-failure-exception/learning-failure-exception.ipynb +++ b/integration-tests/learning-failure-exception/learning-failure-exception.ipynb @@ -23,7 +23,7 @@ "output_type": "stream", "text": [ "ERROR: lincs is unable to learn from this learning set using this algorithm and these parameters.\n", - "Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions\n" + "Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type ucncs --ucncs.strategy sat-by-coalitions\n" ] } ], diff --git a/integration-tests/python-module-is-executable/python-module-is-executable.ipynb b/integration-tests/python-module-is-executable/python-module-is-executable.ipynb index 19fb1954..7b557f9e 100644 --- a/integration-tests/python-module-is-executable/python-module-is-executable.ipynb +++ b/integration-tests/python-module-is-executable/python-module-is-executable.ipynb @@ -11,7 +11,7 @@ "output_type": "stream", "text": [ "Python 3.7\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 208978669\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 208978669\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -40,7 +40,7 @@ " - name: Intermediate category 1\n", " - name: Best category\n", "Python 3.8\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 208978669\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 208978669\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -69,7 +69,7 @@ " - name: Intermediate category 1\n", " - name: Best category\n", "Python 3.9\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 208978669\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 208978669\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -98,7 +98,7 @@ " - name: Intermediate category 1\n", " - name: Best category\n", "Python 3.10\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 208978669\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 208978669\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", @@ -127,7 +127,7 @@ " - name: Intermediate category 1\n", " - name: Best category\n", "Python 3.11\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-problem 4 3 --random-seed 208978669\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-problem 4 3 --random-seed 208978669\n", "kind: classification-problem\n", "format_version: 1\n", "criteria:\n", diff --git a/integration-tests/read-from-stdin/read-from-stdin.ipynb b/integration-tests/read-from-stdin/read-from-stdin.ipynb index 600c8562..12515f87 100644 --- a/integration-tests/read-from-stdin/read-from-stdin.ipynb +++ b/integration-tests/read-from-stdin/read-from-stdin.ipynb @@ -10,7 +10,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "# Reproduction command (with lincs version 0.10.4-dev): lincs generate classification-model - --random-seed 45 --model-type mrsort\n", + "# Reproduction command (with lincs version 0.11.0): lincs generate classification-model - --random-seed 45 --model-type mrsort\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/integration-tests/verbose/verbose.ipynb b/integration-tests/verbose/verbose.ipynb index 718fb846..deb43906 100644 --- a/integration-tests/verbose/verbose.ipynb +++ b/integration-tests/verbose/verbose.ipynb @@ -58,7 +58,7 @@ "Best accuracy (after 34 iterations): 198\n", "Best accuracy (after 35 iterations): 198\n", "Final accuracy (after 36 iterations): 200\n", - "# Reproduction command (with lincs version 0.10.4-dev): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 42 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", + "# Reproduction command (with lincs version 0.11.0): lincs learn classification-model problem.yml learning-set.csv --model-type mrsort --mrsort.strategy weights-profiles-breed --mrsort.weights-profiles-breed.models-count 9 --mrsort.weights-profiles-breed.accuracy-heuristic.random-seed 42 --mrsort.weights-profiles-breed.initialization-strategy maximize-discrimination-per-criterion --mrsort.weights-profiles-breed.weights-strategy linear-program --mrsort.weights-profiles-breed.linear-program.solver glop --mrsort.weights-profiles-breed.profiles-strategy accuracy-heuristic --mrsort.weights-profiles-breed.accuracy-heuristic.processor cpu --mrsort.weights-profiles-breed.breed-strategy reinitialize-least-accurate --mrsort.weights-profiles-breed.reinitialize-least-accurate.portion 0.5 --mrsort.weights-profiles-breed.target-accuracy 1.0\n", "kind: ncs-classification-model\n", "format_version: 1\n", "accepted_values:\n", diff --git a/lincs/__init__.py b/lincs/__init__.py index 2d35f782..091f94fb 100644 --- a/lincs/__init__.py +++ b/lincs/__init__.py @@ -1,6 +1,6 @@ # Copyright 2023 Vincent Jacques -__version__ = "0.10.4-dev" +__version__ = "0.11.0" # I/O from liblincs import DataValidationException

    Criterion category_correlation

    Criterion preference_direction

    Accepted values kind

    Accepted values attributes

    growing

    increasing

    thresholds

    thresholds