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
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
from collections import Counter
|
|
2
|
+
|
|
3
|
+
import dash_bootstrap_components as dbc
|
|
4
|
+
import numpy as np
|
|
5
|
+
from dash import html, dcc, Output, Input, State, dash, Dash
|
|
6
|
+
|
|
7
|
+
from .MetaTab import MetaTab
|
|
8
|
+
from ...service import Plots, init_logger, log_exceptions
|
|
9
|
+
from ...domain import Controller
|
|
10
|
+
|
|
11
|
+
CONFIG = {
|
|
12
|
+
"toImageButtonOptions": {
|
|
13
|
+
"format": "svg", # one of png, svg, jpeg, webp
|
|
14
|
+
"height": None,
|
|
15
|
+
"width": None,
|
|
16
|
+
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AggregatedResultsTab(MetaTab):
|
|
22
|
+
def __init__(self, app: Dash, metabo_controller: Controller):
|
|
23
|
+
super().__init__(app, metabo_controller)
|
|
24
|
+
self._logger = init_logger()
|
|
25
|
+
self.r = self.metabo_controller.get_all_results()
|
|
26
|
+
self._plots = Plots("blues")
|
|
27
|
+
|
|
28
|
+
def getLayout(self) -> dbc.Tab:
|
|
29
|
+
_resultsMenuDropdowns = dbc.Card(
|
|
30
|
+
className="results_menu_dropdowns",
|
|
31
|
+
children=[
|
|
32
|
+
dbc.CardBody(
|
|
33
|
+
[
|
|
34
|
+
html.Div(
|
|
35
|
+
className="dropdowns",
|
|
36
|
+
children=[
|
|
37
|
+
html.H6("Classification Design : "),
|
|
38
|
+
dbc.Select(
|
|
39
|
+
id="design_dropdown_summary",
|
|
40
|
+
className="form_select",
|
|
41
|
+
options=[{"label": "None", "value": "None"}],
|
|
42
|
+
value="None",
|
|
43
|
+
),
|
|
44
|
+
dcc.Store(id='design_dropdown_summary_store', storage_type='session'),
|
|
45
|
+
],
|
|
46
|
+
),
|
|
47
|
+
dbc.Button(
|
|
48
|
+
"Load",
|
|
49
|
+
color="primary",
|
|
50
|
+
id="load_results_button",
|
|
51
|
+
className="custom_buttons",
|
|
52
|
+
n_clicks=0,
|
|
53
|
+
),
|
|
54
|
+
html.Div(id="output_button_load_results"),
|
|
55
|
+
],
|
|
56
|
+
id="all_algo_results",
|
|
57
|
+
)
|
|
58
|
+
],
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
__currentExperimentInfo = dbc.Card(
|
|
62
|
+
children=[
|
|
63
|
+
dbc.CardBody(
|
|
64
|
+
children=[
|
|
65
|
+
html.H6(
|
|
66
|
+
"Current experiment info"
|
|
67
|
+
),
|
|
68
|
+
dcc.Loading(
|
|
69
|
+
id="loading_expe_table_summary",
|
|
70
|
+
children=html.Div(id="expe_table_summary", children=""),
|
|
71
|
+
type="circle",
|
|
72
|
+
),
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
],
|
|
76
|
+
className="w-25",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
_resultsInfo = html.Div(
|
|
80
|
+
className="Results_info",
|
|
81
|
+
children=[
|
|
82
|
+
_resultsMenuDropdowns,
|
|
83
|
+
__currentExperimentInfo,
|
|
84
|
+
],
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
_heatmapUsedFeatures = html.Div(
|
|
89
|
+
className="umap_plot_and_title",
|
|
90
|
+
children=[
|
|
91
|
+
html.Div(
|
|
92
|
+
className="title_and_help",
|
|
93
|
+
children=[
|
|
94
|
+
html.H6("Features Usage"),
|
|
95
|
+
dbc.Button(
|
|
96
|
+
"[?]",
|
|
97
|
+
className="text-muted btn-secondary popover_btn",
|
|
98
|
+
id="help_heatmapFeatures",
|
|
99
|
+
),
|
|
100
|
+
dbc.Popover(
|
|
101
|
+
children=[dbc.PopoverBody("Blablabla wout wout")],
|
|
102
|
+
id="pop_help_heatmapFeatures",
|
|
103
|
+
is_open=False,
|
|
104
|
+
target="help_hHeatmapFeatures",
|
|
105
|
+
),
|
|
106
|
+
],
|
|
107
|
+
),
|
|
108
|
+
dcc.Loading(
|
|
109
|
+
dcc.Graph(id="heatmapFeatures", config=CONFIG),
|
|
110
|
+
type="dot",
|
|
111
|
+
color="#13BD00",
|
|
112
|
+
),
|
|
113
|
+
dcc.Slider(-3, 0, 0.1,
|
|
114
|
+
id='slider_heatmapFeatures',
|
|
115
|
+
marks={i: '{}'.format(10 ** i) for i in range(-3, 1, 1)},
|
|
116
|
+
value=-2,
|
|
117
|
+
updatemode='drag',
|
|
118
|
+
),
|
|
119
|
+
],
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
_heatmapSamplesAlwaysWrong = html.Div(
|
|
123
|
+
className="umap_plot_and_title",
|
|
124
|
+
children=[
|
|
125
|
+
html.Div(
|
|
126
|
+
className="title_and_help",
|
|
127
|
+
children=[
|
|
128
|
+
html.H6("Errors on samples in test"),
|
|
129
|
+
dbc.Button(
|
|
130
|
+
"[?]",
|
|
131
|
+
className="text-muted btn-secondary popover_btn",
|
|
132
|
+
id="help_heatmapSamples",
|
|
133
|
+
),
|
|
134
|
+
dbc.Popover(
|
|
135
|
+
children=[dbc.PopoverBody("Blablabla wout wout")],
|
|
136
|
+
id="pop_help_heatmapSamples",
|
|
137
|
+
is_open=False,
|
|
138
|
+
target="help_heatmapSamples",
|
|
139
|
+
),
|
|
140
|
+
],
|
|
141
|
+
),
|
|
142
|
+
dcc.Loading(
|
|
143
|
+
dcc.Graph(id="heatmapSamples", config=CONFIG),
|
|
144
|
+
type="dot",
|
|
145
|
+
color="#13BD00",
|
|
146
|
+
),
|
|
147
|
+
# dcc.Slider(min=0, max=3, step=1, value=0, marks={0: "10", 1: "40", 2: "100", 3: "All"},
|
|
148
|
+
# id="features_stripChart_dropdown")
|
|
149
|
+
],
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
_barplotComparaisonAlgo = html.Div(
|
|
153
|
+
className="umap_plot_and_title",
|
|
154
|
+
children=[
|
|
155
|
+
html.Div(
|
|
156
|
+
className="title_and_help",
|
|
157
|
+
children=[
|
|
158
|
+
html.H6("Comparaison of algorithms performances"),
|
|
159
|
+
dbc.Button(
|
|
160
|
+
"[?]",
|
|
161
|
+
className="text-muted btn-secondary popover_btn",
|
|
162
|
+
id="help_barplotAlgo",
|
|
163
|
+
),
|
|
164
|
+
dbc.Popover(
|
|
165
|
+
children=[dbc.PopoverBody("Blablabla wout wout")],
|
|
166
|
+
id="pop_help_barplotAlgo",
|
|
167
|
+
is_open=False,
|
|
168
|
+
target="help_barplotAlgo",
|
|
169
|
+
),
|
|
170
|
+
],
|
|
171
|
+
),
|
|
172
|
+
dcc.Loading(
|
|
173
|
+
dcc.Graph(id="barplotAlgo", config=CONFIG),
|
|
174
|
+
type="dot",
|
|
175
|
+
color="#13BD00",
|
|
176
|
+
),
|
|
177
|
+
],
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return dbc.Tab(
|
|
181
|
+
className="global_tab",
|
|
182
|
+
label="Results aggregated",
|
|
183
|
+
children=[
|
|
184
|
+
_resultsInfo,
|
|
185
|
+
html.Div(
|
|
186
|
+
className="fig_group",
|
|
187
|
+
children=[
|
|
188
|
+
_barplotComparaisonAlgo
|
|
189
|
+
],
|
|
190
|
+
),
|
|
191
|
+
html.Div(className="fig_group", children=[
|
|
192
|
+
_heatmapSamplesAlwaysWrong,
|
|
193
|
+
_heatmapUsedFeatures
|
|
194
|
+
]),
|
|
195
|
+
],
|
|
196
|
+
)
|
|
197
|
+
# html.Div(className="column_content",
|
|
198
|
+
# # WARNING !! : _infoFigure is not with the card, it's in a separate column
|
|
199
|
+
# children=[_heatmapSamplesAlwaysWrong])])])
|
|
200
|
+
|
|
201
|
+
def _registerCallbacks(self) -> None:
|
|
202
|
+
@self.app.callback(
|
|
203
|
+
[
|
|
204
|
+
Output("design_dropdown_summary", "options"),
|
|
205
|
+
Output("design_dropdown_summary", "value"),
|
|
206
|
+
],
|
|
207
|
+
Input("custom_big_tabs", "active_tab"),
|
|
208
|
+
State('design_dropdown_summary_store', 'data'),
|
|
209
|
+
)
|
|
210
|
+
@log_exceptions(self._logger)
|
|
211
|
+
def update_results_dropdown_design(active, stored_value):
|
|
212
|
+
if active == "tab-4":
|
|
213
|
+
try:
|
|
214
|
+
self.r = self.metabo_controller.get_all_results()
|
|
215
|
+
a = list(self.r.keys())
|
|
216
|
+
if stored_value is not None and stored_value in a:
|
|
217
|
+
return [{"label": i, "value": i} for i in a], stored_value
|
|
218
|
+
return [{"label": i, "value": i} for i in a], a[0]
|
|
219
|
+
except: # TODO: wrong practice ???
|
|
220
|
+
return dash.no_update, dash.no_update
|
|
221
|
+
else:
|
|
222
|
+
return dash.no_update, dash.no_update
|
|
223
|
+
|
|
224
|
+
@self.app.callback(
|
|
225
|
+
Output('design_dropdown_summary_store', 'data'),
|
|
226
|
+
Input('load_results_button', 'n_clicks'),
|
|
227
|
+
State('design_dropdown_summary', 'value')
|
|
228
|
+
)
|
|
229
|
+
def save_design_dropdown_summary_value(_, value):
|
|
230
|
+
return value
|
|
231
|
+
|
|
232
|
+
@self.app.callback(
|
|
233
|
+
[
|
|
234
|
+
Output("expe_table_summary", "children")
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
Input("load_results_button", "n_clicks")
|
|
238
|
+
],
|
|
239
|
+
[
|
|
240
|
+
State("design_dropdown_summary", "value")
|
|
241
|
+
],
|
|
242
|
+
)
|
|
243
|
+
@log_exceptions(self._logger)
|
|
244
|
+
def get_experiment_statistics(_, design_name):
|
|
245
|
+
if design_name == "None":
|
|
246
|
+
return dash.no_update
|
|
247
|
+
|
|
248
|
+
df = self.r[design_name][list(self.r[design_name].keys())[0]].results["info_expe"]
|
|
249
|
+
table_body = self._plots.show_exp_info_all(df)
|
|
250
|
+
table = dbc.Table(
|
|
251
|
+
table_body, id="table_exp_info", borderless=True, hover=True
|
|
252
|
+
)
|
|
253
|
+
return [table]
|
|
254
|
+
|
|
255
|
+
@self.app.callback(
|
|
256
|
+
[
|
|
257
|
+
Output("heatmapFeatures", "figure"),
|
|
258
|
+
],
|
|
259
|
+
[Input("load_results_button", "n_clicks"),
|
|
260
|
+
Input("slider_heatmapFeatures", "value")],
|
|
261
|
+
[State("design_dropdown_summary", "value"),
|
|
262
|
+
],
|
|
263
|
+
)
|
|
264
|
+
@log_exceptions(self._logger)
|
|
265
|
+
def show_heatmap_features_usage(n_clicks, log_importance_threshold, design):
|
|
266
|
+
if n_clicks >= 1:
|
|
267
|
+
|
|
268
|
+
importance_threshold = 10 ** log_importance_threshold
|
|
269
|
+
|
|
270
|
+
algos = list(self.r[design].keys())
|
|
271
|
+
global_df = None
|
|
272
|
+
for a in algos:
|
|
273
|
+
if global_df is None:
|
|
274
|
+
self._logger.info("Global df is none")
|
|
275
|
+
global_df = self.r[design][a].results["features_table"]
|
|
276
|
+
global_df = global_df.loc[
|
|
277
|
+
:, ("features", "importance_usage")
|
|
278
|
+
] # reduce dataframe to 2 columns
|
|
279
|
+
global_df.rename(
|
|
280
|
+
columns={"importance_usage": a}, inplace=True
|
|
281
|
+
) # rename column to identify algorithm
|
|
282
|
+
else:
|
|
283
|
+
self._logger.info(f"Global df not none, algo : {a}")
|
|
284
|
+
df = self.r[design][a].results[
|
|
285
|
+
"features_table"
|
|
286
|
+
] # retrieve features table of algo a
|
|
287
|
+
df = df.loc[
|
|
288
|
+
:, ("features", "importance_usage")
|
|
289
|
+
] # reduce dataframe to 2 columns
|
|
290
|
+
df.rename(
|
|
291
|
+
columns={"importance_usage": a}, inplace=True
|
|
292
|
+
) # rename column to identify algorithm
|
|
293
|
+
global_df = global_df.merge(
|
|
294
|
+
df, how="outer", on="features"
|
|
295
|
+
) # join data with global dataset
|
|
296
|
+
|
|
297
|
+
global_df = global_df.set_index("features")
|
|
298
|
+
global_df = global_df.fillna(0)
|
|
299
|
+
|
|
300
|
+
global_df = global_df.loc[global_df.max(axis=1) >= importance_threshold]
|
|
301
|
+
|
|
302
|
+
hm_fig = self._plots.show_heatmap_features_usage(global_df, importance_threshold)
|
|
303
|
+
|
|
304
|
+
return [hm_fig]
|
|
305
|
+
else:
|
|
306
|
+
return dash.no_update
|
|
307
|
+
|
|
308
|
+
@self.app.callback(
|
|
309
|
+
Output("heatmapSamples", "figure"),
|
|
310
|
+
[Input("load_results_button", "n_clicks")],
|
|
311
|
+
State("design_dropdown_summary", "value"),
|
|
312
|
+
)
|
|
313
|
+
@log_exceptions(self._logger)
|
|
314
|
+
def show_heatmap_samples_always_wrong(n_clicks, design):
|
|
315
|
+
if n_clicks >= 1:
|
|
316
|
+
algos = list(self.r[design].keys())
|
|
317
|
+
|
|
318
|
+
data_train = []
|
|
319
|
+
data_test = []
|
|
320
|
+
all_samples = []
|
|
321
|
+
|
|
322
|
+
for i, a in enumerate(algos):
|
|
323
|
+
data_train.append([])
|
|
324
|
+
data_test.append([])
|
|
325
|
+
train = []
|
|
326
|
+
test = []
|
|
327
|
+
for j, s in enumerate(self.r[design][a].splits_number):
|
|
328
|
+
train_d, test_d = self.r[design][a].results[s]["failed_samples"]
|
|
329
|
+
train.append(train_d)
|
|
330
|
+
test.append(test_d)
|
|
331
|
+
|
|
332
|
+
counter_train = Counter()
|
|
333
|
+
for d in train:
|
|
334
|
+
counter_train.update(d)
|
|
335
|
+
|
|
336
|
+
counter_test = Counter()
|
|
337
|
+
for d in test:
|
|
338
|
+
counter_test.update(d)
|
|
339
|
+
|
|
340
|
+
all_samples = list(counter_train.keys()) + list(counter_test.keys())
|
|
341
|
+
for s in all_samples:
|
|
342
|
+
if s in counter_train.keys():
|
|
343
|
+
data_train[i].append(counter_train[s])
|
|
344
|
+
else:
|
|
345
|
+
data_train[i].append(0)
|
|
346
|
+
|
|
347
|
+
if s in counter_test.keys():
|
|
348
|
+
data_test[i].append(counter_test[s])
|
|
349
|
+
else:
|
|
350
|
+
data_test[i].append(0)
|
|
351
|
+
|
|
352
|
+
data_train = np.array(data_train).T
|
|
353
|
+
data_test = np.array(data_test).T
|
|
354
|
+
|
|
355
|
+
fig = self._plots.show_heatmap_wrong_samples(
|
|
356
|
+
data_train, data_test, all_samples, algos
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
return fig
|
|
360
|
+
else:
|
|
361
|
+
return dash.no_update
|
|
362
|
+
|
|
363
|
+
@self.app.callback(
|
|
364
|
+
Output("barplotAlgo", "figure"),
|
|
365
|
+
[Input("load_results_button", "n_clicks")],
|
|
366
|
+
State("design_dropdown_summary", "value"),
|
|
367
|
+
)
|
|
368
|
+
@log_exceptions(self._logger)
|
|
369
|
+
def show_barplot_compare_accuracy_algo(n_clicks, design_name):
|
|
370
|
+
"""
|
|
371
|
+
retrieve balanced accuracy values now
|
|
372
|
+
"""
|
|
373
|
+
if n_clicks >= 1:
|
|
374
|
+
algos = list(self.r[design_name].keys())
|
|
375
|
+
|
|
376
|
+
train_acc = []
|
|
377
|
+
train_std = []
|
|
378
|
+
test_acc = []
|
|
379
|
+
test_std = []
|
|
380
|
+
for a in algos:
|
|
381
|
+
df = self.r[design_name][a].results["metrics_table"]
|
|
382
|
+
train_m, train_s = df["train"][1].split("(")
|
|
383
|
+
train_acc.append(float(train_m))
|
|
384
|
+
train_std.append(float(train_s.split(")")[0]))
|
|
385
|
+
|
|
386
|
+
test_m, test_s = df["test"][1].split("(")
|
|
387
|
+
test_acc.append(float(test_m))
|
|
388
|
+
test_std.append(float(test_s.split(")")[0]))
|
|
389
|
+
|
|
390
|
+
fig = self._plots.show_barplot_comparaison_algo(algos, train_acc, train_std, test_acc, test_std)
|
|
391
|
+
return fig
|
|
392
|
+
else:
|
|
393
|
+
return dash.no_update
|
|
394
|
+
|