pico-ml 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pico/__init__.py +3 -0
- pico/__main__.py +3 -0
- pico/cli/__init__.py +2 -0
- pico/cli/main.py +117 -0
- pico/conf/SupportedCV.py +17 -0
- pico/conf/SupportedModels.py +73 -0
- pico/conf/algo_sklearn.json +51 -0
- pico/conf/parameters.py +14 -0
- pico/domain/ClassificationDesign.py +107 -0
- pico/domain/Controller.py +397 -0
- pico/domain/DataMatrix.py +147 -0
- pico/domain/ExperimentDTO.py +17 -0
- pico/domain/MetaData.py +229 -0
- pico/domain/MetaboExperiment.py +696 -0
- pico/domain/MetaboModel.py +53 -0
- pico/domain/ModelFactory.py +45 -0
- pico/domain/Results.py +602 -0
- pico/domain/SplitGroup.py +202 -0
- pico/domain/__init__.py +9 -0
- pico/domain/dumps/metadata/.gitkeep +0 -0
- pico/domain/dumps/splits/.gitkeep +0 -0
- pico/service/DataFormat.py +180 -0
- pico/service/ExperimentDesign.py +30 -0
- pico/service/LoggerConfig.py +150 -0
- pico/service/Plots.py +472 -0
- pico/service/RunMLalgo.py +93 -0
- pico/service/SamplesPairing.py +390 -0
- pico/service/Utils.py +497 -0
- pico/service/__init__.py +7 -0
- pico/ui/__init__.py +1 -0
- pico/ui/app.py +145 -0
- pico/ui/assets/000_Stylesheet.css +464 -0
- pico/ui/assets/DecisionTree.png +0 -0
- pico/ui/assets/Figure_home_wider.png +0 -0
- pico/ui/assets/favicon.ico +0 -0
- pico/ui/assets/help_icon.png +0 -0
- pico/ui/assets/help_icon.svg +15 -0
- pico/ui/assets/update_figure_steps_MeDIC_4.svg +1 -0
- pico/ui/tabs/AggregatedResultsTab.py +394 -0
- pico/ui/tabs/InfoTab.py +440 -0
- pico/ui/tabs/InterpretTab.py +21 -0
- pico/ui/tabs/MLTab.py +487 -0
- pico/ui/tabs/MetaTab.py +23 -0
- pico/ui/tabs/ResultsTab.py +1062 -0
- pico/ui/tabs/SplitsTab.py +1227 -0
- pico/ui/tabs/__init__.py +6 -0
- pico/ui/tabs/utils.py +101 -0
- pico_ml-2.0.0.dist-info/METADATA +86 -0
- pico_ml-2.0.0.dist-info/RECORD +52 -0
- pico_ml-2.0.0.dist-info/WHEEL +4 -0
- pico_ml-2.0.0.dist-info/entry_points.txt +2 -0
- pico_ml-2.0.0.dist-info/licenses/LICENSE +437 -0
pico/ui/tabs/__init__.py
ADDED
pico/ui/tabs/utils.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from ...conf import parameters as cfg
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def update_marks(custom_value: int, add_all_value: bool = False) -> dict:
|
|
7
|
+
"""
|
|
8
|
+
Update the marks of the features slider to include a custom value.
|
|
9
|
+
|
|
10
|
+
If the custom value is already in the default marks, it will be used and
|
|
11
|
+
marked as "(used)".
|
|
12
|
+
|
|
13
|
+
If the custom value is not in the default marks, it will be added to the
|
|
14
|
+
marks at a position that is the closest to its value.
|
|
15
|
+
|
|
16
|
+
If add_all_value is True, the "All" mark will be added to the marks.
|
|
17
|
+
|
|
18
|
+
Returns a tuple containing the updated marks and the location of the custom
|
|
19
|
+
value.
|
|
20
|
+
"""
|
|
21
|
+
locations = [int(l) for l in cfg.default_marks.keys()]
|
|
22
|
+
values = np.array([int(v) for v in cfg.default_marks.values()])
|
|
23
|
+
|
|
24
|
+
# If the custom value is already there, we use it a used feature
|
|
25
|
+
if custom_value in values:
|
|
26
|
+
marks = cfg.default_marks.copy()
|
|
27
|
+
idx = np.where(values == custom_value)[0].item()
|
|
28
|
+
location_key = str(locations[idx])
|
|
29
|
+
marks[location_key] = marks[location_key] + " (used)"
|
|
30
|
+
|
|
31
|
+
if add_all_value:
|
|
32
|
+
marks.update(cfg.all_mark)
|
|
33
|
+
|
|
34
|
+
return marks, location_key
|
|
35
|
+
|
|
36
|
+
greater_indicator = values > custom_value
|
|
37
|
+
if np.all(greater_indicator):
|
|
38
|
+
# The value is on the far left
|
|
39
|
+
custom_location = locations[0] - cfg.custom_mark_offset
|
|
40
|
+
elif not np.any(greater_indicator):
|
|
41
|
+
# The value is on the far right
|
|
42
|
+
custom_location = locations[-1] + cfg.custom_mark_offset
|
|
43
|
+
else:
|
|
44
|
+
greater_idx = np.argmax(greater_indicator)
|
|
45
|
+
distance_from_greater = values[greater_idx] - custom_value
|
|
46
|
+
distance_from_smaller = custom_value - values[greater_idx - 1]
|
|
47
|
+
if distance_from_smaller < distance_from_greater:
|
|
48
|
+
# Closer to the left, we will add the offset on the left mark
|
|
49
|
+
custom_location = locations[greater_idx - 1] + cfg.custom_mark_offset
|
|
50
|
+
elif distance_from_smaller == distance_from_greater:
|
|
51
|
+
# Equal distance
|
|
52
|
+
custom_location = (locations[greater_idx - 1] + locations[greater_idx]) / 2
|
|
53
|
+
else:
|
|
54
|
+
# Closer the the right, we will remove the offset from the right mark
|
|
55
|
+
custom_location = locations[greater_idx] - cfg.custom_mark_offset
|
|
56
|
+
|
|
57
|
+
marks = cfg.default_marks.copy()
|
|
58
|
+
value_label = {
|
|
59
|
+
'label': str(custom_value) + ' (used)',
|
|
60
|
+
'style': {
|
|
61
|
+
"top": "-3em"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
marks[str(custom_location)] = value_label
|
|
65
|
+
|
|
66
|
+
if add_all_value:
|
|
67
|
+
marks = {**marks, **cfg.all_mark}
|
|
68
|
+
|
|
69
|
+
return marks, custom_location
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_index_from_marks(number: float, marks: dict) -> int:
|
|
74
|
+
"""This is really specific to how the results are saved.
|
|
75
|
+
See pico.domain.Results._produce_PCA (or _produce_UMAP).
|
|
76
|
+
|
|
77
|
+
The first results are from cfg.features, then used_features, then all.
|
|
78
|
+
|
|
79
|
+
The result differs when there is "All" features (e.g. strip chart doesnt not include All).
|
|
80
|
+
"""
|
|
81
|
+
contain_all = False
|
|
82
|
+
for v in marks.values():
|
|
83
|
+
if isinstance(v, str) and v == "All":
|
|
84
|
+
contain_all = True
|
|
85
|
+
|
|
86
|
+
match marks[str(number)]:
|
|
87
|
+
case dict(value):
|
|
88
|
+
# We have the used feature case, index is -2 or -1 when
|
|
89
|
+
index = -2 if contain_all else -1
|
|
90
|
+
case "All":
|
|
91
|
+
# We have the "All" case, index is -1
|
|
92
|
+
index = -1
|
|
93
|
+
case str(value) if "used" in value:
|
|
94
|
+
# We have the feature case
|
|
95
|
+
index = -2 if contain_all else -1
|
|
96
|
+
case _:
|
|
97
|
+
# The number is the index
|
|
98
|
+
index = int(number)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
return index
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pico-ml
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Pipeline for Interpretable Classification on Omics
|
|
5
|
+
Project-URL: Homepage, https://elinaff.github.io/PICO/
|
|
6
|
+
Project-URL: Issues, https://github.com/ElinaFF/PICO/issues
|
|
7
|
+
Project-URL: Source, https://github.com/ElinaFF/PICO
|
|
8
|
+
Author-email: Elina Francovic-Fontaine <elina.francovic-fontaine.1@ulaval.ca>
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Requires-Python: <3.13,>=3.8
|
|
14
|
+
Requires-Dist: coloredlogs
|
|
15
|
+
Requires-Dist: dash
|
|
16
|
+
Requires-Dist: dash-bio
|
|
17
|
+
Requires-Dist: dash-bootstrap-components
|
|
18
|
+
Requires-Dist: dash-core-components
|
|
19
|
+
Requires-Dist: dash-cytoscape
|
|
20
|
+
Requires-Dist: dash-html-components
|
|
21
|
+
Requires-Dist: dash-interactive-graphviz
|
|
22
|
+
Requires-Dist: dash-renderer
|
|
23
|
+
Requires-Dist: dash-table
|
|
24
|
+
Requires-Dist: matplotlib
|
|
25
|
+
Requires-Dist: numba
|
|
26
|
+
Requires-Dist: numpy<2
|
|
27
|
+
Requires-Dist: openpyxl
|
|
28
|
+
Requires-Dist: pandas
|
|
29
|
+
Requires-Dist: plotly
|
|
30
|
+
Requires-Dist: pyscm-ml>=1.1.2
|
|
31
|
+
Requires-Dist: randomscm>=0.1.2
|
|
32
|
+
Requires-Dist: rich
|
|
33
|
+
Requires-Dist: scikit-learn>1.4
|
|
34
|
+
Requires-Dist: scipy
|
|
35
|
+
Requires-Dist: typer
|
|
36
|
+
Requires-Dist: umap-learn
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: dash[testing]; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# PICO
|
|
43
|
+
Pipeline for Interpretable Classification on Omics
|
|
44
|
+
|
|
45
|
+
## Description
|
|
46
|
+
The PICO is a tool to apply machine learning algorithms to omics datasets. The goal is to extract the most important features because they are potential novel biomarkers.
|
|
47
|
+
The interface is made to be easy to use and intuitive even for those with small to nonexistant experience in programming and AI.
|
|
48
|
+
|
|
49
|
+
More generally, it is a tool to apply interpretable machine learning algorithms to tabular data. It focuses on analyzing the features selected by the models.
|
|
50
|
+
|
|
51
|
+
## The documentation
|
|
52
|
+
You can find the documentation [here](https://elinaff.github.io/PICO/).
|
|
53
|
+
It explains how to use PICO but also how it works.
|
|
54
|
+
|
|
55
|
+
## Authors and contributors
|
|
56
|
+
- [Élina Francovic-Fontaine](https://github.com/ElinaFF)
|
|
57
|
+
- [Vincent Primpied](https://github.com/le-smog)
|
|
58
|
+
- [Vincent Vilain](https://github.com/VincentVilain)
|
|
59
|
+
- [Gabriel Leclerc](https://github.com/PandaGab)
|
|
60
|
+
- [Thierry Moszkowicz](https://github.com/ThierryAM)
|
|
61
|
+
- [Mathieu Bazinet](https://github.com/MathieuBazinet)
|
|
62
|
+
- [Thibaud Godon](https://github.com/thibgo)
|
|
63
|
+
- [Pier-Luc Plante](https://github.com/plpla)
|
|
64
|
+
- [Baptiste Bauvin](https://github.com/babau1)
|
|
65
|
+
- [Louis-Philippe Vignault](https://scholar.google.com/citations?user=QXye6lEAAAAJ&hl=fr)
|
|
66
|
+
|
|
67
|
+
## Disclaimer
|
|
68
|
+
PICO is still in development. If you encounter any issue or have any suggestion, feel free to contact us at [elina.francovic-fontaine.1@ulaval.ca](mailto:elina.francovic-fontaine.1@ulaval.ca). Or you can leave an issue [here](https://github.com/ElinaFF/PICO/issues) with the tag "bug".
|
|
69
|
+
|
|
70
|
+
## For developers
|
|
71
|
+
|
|
72
|
+
### Setup
|
|
73
|
+
|
|
74
|
+
Clone the project with :
|
|
75
|
+
```shell
|
|
76
|
+
git clone https://github.com/ElinaFF/PICO.git
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It is recommanded to setup a virtual environment. When it's done, use your isolated python and install `pico` package locally and in editable mode with :
|
|
80
|
+
```shell
|
|
81
|
+
python -m pip install -e ".[dev]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
<a href="https://github.com/ElinaFF/PICO">Pipeline for Interpretable Classification on Omics (PICO)</a> © 2025 by <a href="https://creativecommons.org">Elina Francovic-Fontaine</a> is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
|
|
86
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
pico/__init__.py,sha256=PIFwmFSIbz4T6kPrvSr90M8Dj7WCndTv1oph5kCGO_U,43
|
|
2
|
+
pico/__main__.py,sha256=2pEnS7f2JU7U3_GHXrmNWAIzXhPqN27zSHCZT6Ij4KE,33
|
|
3
|
+
pico/cli/__init__.py,sha256=0m1GuS3w88DNt0kc72N_ugOxa5LH4ibYqrw92To5qWg,53
|
|
4
|
+
pico/cli/main.py,sha256=1crrzeupD3Cb6QgW24nbDzMUB6Rt_nVrwq6SvQVSK04,3368
|
|
5
|
+
pico/conf/SupportedCV.py,sha256=jJftCmsXwZWQOfshCcjxHYd1YFgx2z4qvYuDy82Y0pA,402
|
|
6
|
+
pico/conf/SupportedModels.py,sha256=YTVAd8-ltYFqXGQwEIvL-P5gNCr7TkCkZYhDS3cU1cs,2766
|
|
7
|
+
pico/conf/algo_sklearn.json,sha256=gbX8EJ-f7IrpgmbkH0BqwgONn_TFtbMsK4k33Xcxr8E,664
|
|
8
|
+
pico/conf/parameters.py,sha256=s4gqg4rZlb-iVi7GC2yUmSwcYnQQlAWZsqhK-EuupAM,398
|
|
9
|
+
pico/domain/ClassificationDesign.py,sha256=VED0xqONvnxFFl-Y6b6fVclqkIa7eXvpnmwL98xoyCo,4740
|
|
10
|
+
pico/domain/Controller.py,sha256=xoJ1q0C4mWKVIpVhsbSsm6g1aRGyvxRAxbzJCiQT0Yg,16103
|
|
11
|
+
pico/domain/DataMatrix.py,sha256=ABMFbbLnZ2Nj4TCNyHs9kwySBSWm5AW78uzLRVS5jA0,5720
|
|
12
|
+
pico/domain/ExperimentDTO.py,sha256=hkFyBTD7gfkolO-9uGNyqlEi5st2RnT8yrGEflTiqXI,691
|
|
13
|
+
pico/domain/MetaData.py,sha256=cGqdbrCyr2T4tSjfs63CJEa4PL3F_jnig6a1dTa7VhQ,8967
|
|
14
|
+
pico/domain/MetaboExperiment.py,sha256=io0Jeu-Hx5KT_CCpwgo_Xmz5lTaWoTCaEDjeLX_fOHU,30808
|
|
15
|
+
pico/domain/MetaboModel.py,sha256=Re1gffN_it8n2N5i7l-Ag4ZZiyal1LzKoSz6baBsMWc,1784
|
|
16
|
+
pico/domain/ModelFactory.py,sha256=Y2KpeZVEgfhU-1SA9_e3GmwGGhSLrqI50qeKrf_B2yo,1735
|
|
17
|
+
pico/domain/Results.py,sha256=4JY9BaGxIT35cPQkGTCBlXN9jGv_T2rpSuVWWBMGowQ,23988
|
|
18
|
+
pico/domain/SplitGroup.py,sha256=kTjvAZ_Q3osqKO2peq6DNpIHtGEsXNmEhLL_geJXgsM,11388
|
|
19
|
+
pico/domain/__init__.py,sha256=7WLgTGrvDDxiFyRTLXvP707E47rYnz-2VrK_MI8PffQ,343
|
|
20
|
+
pico/domain/dumps/metadata/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
pico/domain/dumps/splits/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
pico/service/DataFormat.py,sha256=nzC_e9OI7ST6WSxVRWOx-rawUikoiYyW24oGIEQuEWo,8136
|
|
23
|
+
pico/service/ExperimentDesign.py,sha256=A81A0gP6Z0WmLEhjwEtAKqjgFWfwHyksw_vdHvqmS6Q,685
|
|
24
|
+
pico/service/LoggerConfig.py,sha256=i3_mutoK9NNj97DePF33YQk7PS2BbsT79zwd7hon86Q,5524
|
|
25
|
+
pico/service/Plots.py,sha256=KHwNhYPe1-zubPI-4BSJ3nCp2B0M6ASyg6sznnBA1XI,16756
|
|
26
|
+
pico/service/RunMLalgo.py,sha256=ujpGYMszxoLvWzCsg0nctKnA7UebPeeg3Re6rm477Ks,3450
|
|
27
|
+
pico/service/SamplesPairing.py,sha256=3_AS1yl90v420wynwxDbw010ziqwGzAwneWmHIYRpzE,16121
|
|
28
|
+
pico/service/Utils.py,sha256=RHGSCB3vfGnvaQXi38WzTtKmPvD_KFnzSd-T66oDudg,18973
|
|
29
|
+
pico/service/__init__.py,sha256=M5R-zD4k2ow1Z8cRJzHFEg6Fu3Aopt8E65wIgWrlf5Y,228
|
|
30
|
+
pico/ui/__init__.py,sha256=8G-rLhbTJsxt8QMNfYPDILcn9K1Psojh3Vq-lntPyS4,21
|
|
31
|
+
pico/ui/app.py,sha256=UqMeDGM6a_UYnQzkEswH8bO2-p0u7kGHVMF_IPXsUz4,5565
|
|
32
|
+
pico/ui/assets/000_Stylesheet.css,sha256=saRlyjSuwxFeE29eATw6cDRruHvlmNfAjl6R_Iwkgls,6530
|
|
33
|
+
pico/ui/assets/DecisionTree.png,sha256=JNVvyvjOuAka4e_ic7njqUrhOZe20RFovUQribFXCAA,203270
|
|
34
|
+
pico/ui/assets/Figure_home_wider.png,sha256=Tv424vLbQ7Fjtw8jO8ffyrLDRnvLyQ-Da_7PeRaoBrA,60314
|
|
35
|
+
pico/ui/assets/favicon.ico,sha256=BwmZGm94ENHB2CPfb4AKTDqH286JLSHPVP04_LTBzo8,8532
|
|
36
|
+
pico/ui/assets/help_icon.png,sha256=jhVapWHX6nZ7qwEdwp9WC7LW-kkWVaWA_08SCbB2s84,10134
|
|
37
|
+
pico/ui/assets/help_icon.svg,sha256=l1z39WE4nG5duOb30Tl89hK520yzrt5E5UOAWJqLvuo,755
|
|
38
|
+
pico/ui/assets/update_figure_steps_MeDIC_4.svg,sha256=2wDhHeM5sBjmBLCD7KTjKmFTVjqV5x6y20vvXSDqBUI,9721
|
|
39
|
+
pico/ui/tabs/AggregatedResultsTab.py,sha256=xiaBhLYToBK72wGaRokOXpj6nmROgElK0whK-ITQo58,15108
|
|
40
|
+
pico/ui/tabs/InfoTab.py,sha256=CWldI9f3Ll2gZ7dW80sz2y8L3ZCslUiXGN_TiRHiC0Q,19786
|
|
41
|
+
pico/ui/tabs/InterpretTab.py,sha256=yJeNDtBOiY2FINVdxkXVKbmVf5b2wJ6E-GchNfShMhw,543
|
|
42
|
+
pico/ui/tabs/MLTab.py,sha256=Oqnc8_4-eu-qQhzcX3uuuqtmovqkGVf83vSgCDV1JII,21106
|
|
43
|
+
pico/ui/tabs/MetaTab.py,sha256=g7fELzDs5VHj_1FfxQX1s6mznI_dKwSmIBY8cTIXM08,537
|
|
44
|
+
pico/ui/tabs/ResultsTab.py,sha256=sJS3w9Kgvqo6rBlYsUl7pvO8ZS3CbMvClDCBhmsZNfk,39867
|
|
45
|
+
pico/ui/tabs/SplitsTab.py,sha256=ybIY09foDoHyR25o6y8iEn5UHyd6SOy0eIXuvsdKh_0,52517
|
|
46
|
+
pico/ui/tabs/__init__.py,sha256=snlgOGrMRN9hgg7jXFM2g7TaoIwA1ufkZxdI9DOLNxY,216
|
|
47
|
+
pico/ui/tabs/utils.py,sha256=BTDgNQV1FqCEKqkeIjr2Zcee6FDHZcHL9EY5NdLqpNo,3606
|
|
48
|
+
pico_ml-2.0.0.dist-info/METADATA,sha256=AmRVytsVhQMpzH7wbvzeGeS2mI5aj4UFhRRghwuoMXc,3503
|
|
49
|
+
pico_ml-2.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
50
|
+
pico_ml-2.0.0.dist-info/entry_points.txt,sha256=uSuwbxFEWXXiwg-TQsAEwcHshBOo-0hj1AWupayX46s,43
|
|
51
|
+
pico_ml-2.0.0.dist-info/licenses/LICENSE,sha256=E0mkthSEkrRPYp5k7tZ2YS4jT-moOeTzsnfBSCyISfE,20849
|
|
52
|
+
pico_ml-2.0.0.dist-info/RECORD,,
|