robert 1.2.0__tar.gz → 1.2.1__tar.gz

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.
Files changed (71) hide show
  1. {robert-1.2.0 → robert-1.2.1}/PKG-INFO +2 -2
  2. {robert-1.2.0 → robert-1.2.1}/README.md +18 -9
  3. {robert-1.2.0 → robert-1.2.1}/robert/__main__.py +1 -1
  4. {robert-1.2.0 → robert-1.2.1}/robert/aqme.py +13 -11
  5. {robert-1.2.0 → robert-1.2.1}/robert/argument_parser.py +2 -1
  6. {robert-1.2.0 → robert-1.2.1}/robert/curate.py +2 -2
  7. {robert-1.2.0 → robert-1.2.1}/robert/predict_utils.py +6 -6
  8. {robert-1.2.0 → robert-1.2.1}/robert/report.py +25 -6
  9. {robert-1.2.0 → robert-1.2.1}/robert/report_utils.py +1 -0
  10. {robert-1.2.0 → robert-1.2.1}/robert/robert.py +2 -2
  11. {robert-1.2.0 → robert-1.2.1}/robert/utils.py +20 -6
  12. {robert-1.2.0 → robert-1.2.1}/robert.egg-info/PKG-INFO +2 -2
  13. {robert-1.2.0 → robert-1.2.1}/setup.py +1 -1
  14. {robert-1.2.0 → robert-1.2.1}/tests/test_1curate.py +6 -6
  15. {robert-1.2.0 → robert-1.2.1}/tests/test_2generate.py +7 -7
  16. {robert-1.2.0 → robert-1.2.1}/tests/test_4predict.py +1 -1
  17. {robert-1.2.0 → robert-1.2.1}/tests/test_5aqme_n_full.py +31 -31
  18. {robert-1.2.0 → robert-1.2.1}/tests/test_6evaluate.py +2 -2
  19. {robert-1.2.0 → robert-1.2.1}/LICENSE +0 -0
  20. {robert-1.2.0 → robert-1.2.1}/robert/__init__.py +0 -0
  21. {robert-1.2.0 → robert-1.2.1}/robert/evaluate.py +0 -0
  22. {robert-1.2.0 → robert-1.2.1}/robert/generate.py +0 -0
  23. {robert-1.2.0 → robert-1.2.1}/robert/generate_utils.py +0 -0
  24. {robert-1.2.0 → robert-1.2.1}/robert/model_params/ADAB_params.yaml +0 -0
  25. {robert-1.2.0 → robert-1.2.1}/robert/model_params/GB_params.yaml +0 -0
  26. {robert-1.2.0 → robert-1.2.1}/robert/model_params/GP_params.yaml +0 -0
  27. {robert-1.2.0 → robert-1.2.1}/robert/model_params/MVL_params.yaml +0 -0
  28. {robert-1.2.0 → robert-1.2.1}/robert/model_params/NN_params.yaml +0 -0
  29. {robert-1.2.0 → robert-1.2.1}/robert/model_params/RF_params.yaml +0 -0
  30. {robert-1.2.0 → robert-1.2.1}/robert/model_params/VR_params.yaml +0 -0
  31. {robert-1.2.0 → robert-1.2.1}/robert/predict.py +0 -0
  32. {robert-1.2.0 → robert-1.2.1}/robert/report/GENERATE.png +0 -0
  33. {robert-1.2.0 → robert-1.2.1}/robert/report/Robert_icon.ico +0 -0
  34. {robert-1.2.0 → robert-1.2.1}/robert/report/Robert_logo.jpg +0 -0
  35. {robert-1.2.0 → robert-1.2.1}/robert/report/Robert_logo1.jpg +0 -0
  36. {robert-1.2.0 → robert-1.2.1}/robert/report/abbrev.png +0 -0
  37. {robert-1.2.0 → robert-1.2.1}/robert/report/adv_anal.png +0 -0
  38. {robert-1.2.0 → robert-1.2.1}/robert/report/features.png +0 -0
  39. {robert-1.2.0 → robert-1.2.1}/robert/report/outliers.png +0 -0
  40. {robert-1.2.0 → robert-1.2.1}/robert/report/pred.png +0 -0
  41. {robert-1.2.0 → robert-1.2.1}/robert/report/repro.png +0 -0
  42. {robert-1.2.0 → robert-1.2.1}/robert/report/score.png +0 -0
  43. {robert-1.2.0 → robert-1.2.1}/robert/report/score_0.jpg +0 -0
  44. {robert-1.2.0 → robert-1.2.1}/robert/report/score_1.jpg +0 -0
  45. {robert-1.2.0 → robert-1.2.1}/robert/report/score_10.jpg +0 -0
  46. {robert-1.2.0 → robert-1.2.1}/robert/report/score_2.jpg +0 -0
  47. {robert-1.2.0 → robert-1.2.1}/robert/report/score_3.jpg +0 -0
  48. {robert-1.2.0 → robert-1.2.1}/robert/report/score_4.jpg +0 -0
  49. {robert-1.2.0 → robert-1.2.1}/robert/report/score_5.jpg +0 -0
  50. {robert-1.2.0 → robert-1.2.1}/robert/report/score_6.jpg +0 -0
  51. {robert-1.2.0 → robert-1.2.1}/robert/report/score_7.jpg +0 -0
  52. {robert-1.2.0 → robert-1.2.1}/robert/report/score_8.jpg +0 -0
  53. {robert-1.2.0 → robert-1.2.1}/robert/report/score_9.jpg +0 -0
  54. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_1_0.jpg +0 -0
  55. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_1_1.jpg +0 -0
  56. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_2_0.jpg +0 -0
  57. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_2_1.jpg +0 -0
  58. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_2_2.jpg +0 -0
  59. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_3_0.jpg +0 -0
  60. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_3_1.jpg +0 -0
  61. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_3_2.jpg +0 -0
  62. {robert-1.2.0 → robert-1.2.1}/robert/report/score_w_3_3.jpg +0 -0
  63. {robert-1.2.0 → robert-1.2.1}/robert/report/transpa.png +0 -0
  64. {robert-1.2.0 → robert-1.2.1}/robert/report/y_distrib.png +0 -0
  65. {robert-1.2.0 → robert-1.2.1}/robert/verify.py +0 -0
  66. {robert-1.2.0 → robert-1.2.1}/robert.egg-info/SOURCES.txt +0 -0
  67. {robert-1.2.0 → robert-1.2.1}/robert.egg-info/dependency_links.txt +0 -0
  68. {robert-1.2.0 → robert-1.2.1}/robert.egg-info/requires.txt +0 -0
  69. {robert-1.2.0 → robert-1.2.1}/robert.egg-info/top_level.txt +0 -0
  70. {robert-1.2.0 → robert-1.2.1}/setup.cfg +0 -0
  71. {robert-1.2.0 → robert-1.2.1}/tests/test_3verify.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robert
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
5
  Home-page: https://github.com/jvalegre/robert
6
- Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.0.tar.gz
6
+ Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.1.tar.gz
7
7
  Author: Juan V. Alegre Requena, David Dalmau
8
8
  Author-email: jv.alegre@csic.es
9
9
  License: MIT
@@ -7,15 +7,22 @@
7
7
  [![Codecov](https://img.shields.io/codecov/c/github/jvalegre/robert?label=Codecov&logo=codecov)](https://codecov.io/gh/jvalegre/robert)
8
8
  [![Downloads](https://img.shields.io/pepy/dt/robert?label=Downloads&logo=pypi)](https://www.pepy.tech/projects/robert)
9
9
  [![Read the Docs](https://img.shields.io/readthedocs/robert?label=Read%20the%20Docs&logo=readthedocs)](https://robert.readthedocs.io/)
10
-
11
- ROBERT is an ensemble of automated machine learning protocols that can be run sequentially
12
- through a single command line or a graphical user interface. The program works for **regression and classification problems**.
13
- Comprehensive workflows have been designed to meet state-of-the-art standards for cheminformatics studies, including:
10
+ [![PyPI](https://img.shields.io/pypi/v/robert)](https://pypi.org/project/robert/)
14
11
 
15
12
  ## Documentation
16
13
  Full documentation with installation instructions, technical details and examples can be found in [Read the Docs](https://robert.readthedocs.io).
17
14
 
18
- Don't miss out the latest hands-on tutorials from our [YouTube channel](https://www.youtube.com/channel/UCHRqI8N61bYxWV9BjbUI4Xw)!
15
+ Don't miss out the latest hands-on tutorials from our [YouTube channel](https://www.youtube.com/channel/UCHRqI8N61bYxWV9BjbUI4Xw)!
16
+
17
+ ## Recommended installation
18
+ 1. (Only once) Create new conda environment: `conda create -n robert python=3.10`
19
+ 2. Activate conda environment: `conda activate robert`
20
+ 3. Install ROBERT using pip: `pip install robert`
21
+ 4. Install libraries for the PDF report `conda install -y -c conda-forge glib gtk3 pango mscorefonts`
22
+ 5. (Only for compatible devices) Install Intelex accelerator: `pip install scikit-learn-intelex`
23
+ * Inexperienced users should visit the *Users with no Python experience* section in [Read the Docs](https://robert.readthedocs.io).
24
+ ## Update the program
25
+ 1. Update to the latest version: `pip install robert --upgrade`
19
26
 
20
27
  ## Developers and help desk
21
28
  List of main developers and contact emails:
@@ -32,6 +39,8 @@ J.V.A.R. - The acronym ROBERT is dedicated to **ROBERT Paton**, who was a mentor
32
39
 
33
40
  D.D.G. - The style of the ROBERT_report.pdf file was created with the help of **Oliver Lee** (2023, Zysman-Colman group at University of St Andrews).
34
41
 
42
+ J.V.A.R. and D.D.G. - The improvements from v1.0 to v1.2 are largely the result of insightful discussions with **Matthew Sigman** and his students, **Jamie Cadge** and **Simone Gallarati** (2024, University of Utah).
43
+
35
44
  We really THANK all the testers for their feedback and for participating in the reproducibility tests, including:
36
45
 
37
46
  * **David Valiente** (2022-2023, Universidad Miguel Hernández)
@@ -44,11 +53,11 @@ We really THANK all the testers for their feedback and for participating in the
44
53
 
45
54
  ## How to cite ROBERT
46
55
  If you use any of the ROBERT modules, please include this citation:
47
- * Dalmau, D.; Alegre Requena, J. V. ChemRxiv, 2023, DOI: 10.26434/chemrxiv-2023-k994h.
56
+ * Dalmau, D.; Alegre Requena, J. V. ROBERT: Bridging the Gap between Machine Learning and Chemistry. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2024**, *accepted*. DOI: 10.1002/WCMS.1733.
48
57
 
49
58
  If you use the AQME module, please include this citation:
50
- * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. Wiley Interdiscip. Rev. Comput. Mol. Sci. 2023, 13, e1663.
59
+ * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2023**, *13*, e1663.
51
60
 
52
61
  Additionally, please include the corresponding reference for Scikit-learn and SHAP:
53
- * Pedregosa et al., Scikit-learn: Machine Learning in Python, J. Mach. Learn. Res. 2011, 12, 2825-2830.
54
- * Lundberg et al., From local explanations to global understanding with explainable AI for trees, Nat. Mach. Intell. 2020, 2, 56–67.
62
+ * Pedregosa et al., Scikit-learn: Machine Learning in Python. *J. Mach. Learn. Res.* **2011**, *12*, 2825-2830.
63
+ * Lundberg et al., From local explanations to global understanding with explainable AI for trees. *Nat. Mach. Intell.* **2020**, *2*, 56–67.
@@ -13,7 +13,7 @@ from robert import robert
13
13
  # This allows the usage python pip-*.whl/pip install pip-*.whl
14
14
 
15
15
  if __package__ != 'robert':
16
- print('ROBERT is not installed! Use: pip install robert or conda install -c conda-forge robert.')
16
+ print('ROBERT is not installed! Use: pip install robert or conda install -y -c conda-forge robert.')
17
17
 
18
18
  if __name__ == '__main__':
19
19
  robert.main()
@@ -15,6 +15,8 @@ Parameters
15
15
  csearch_keywords : str, default='--sample 50'
16
16
  Add extra keywords to the AQME-CSEARCH run (i.e. csearch_keywords='--sample 10'). CREST can be
17
17
  used instead of RDKit by adding "--program crest".
18
+ descp_lvl : str, default='interpret'
19
+ Type of descriptor to be used in the AQME-ROBERT workflow. Options are 'interpret', 'denovo' or 'full'.
18
20
 
19
21
  """
20
22
  #####################################################.
@@ -95,7 +97,7 @@ class aqme:
95
97
  os.remove(new_sdf)
96
98
  shutil.move(sdf_file, new_sdf)
97
99
 
98
- #Load database
100
+ # Load database
99
101
  csv_df = load_database(self,csv_target,job_type)
100
102
 
101
103
  # find if there is more than one SMILES column in the CSV file
@@ -137,29 +139,29 @@ class aqme:
137
139
  if smi_suffix is not None:
138
140
  # Change column names by adding suffix
139
141
  try:
140
- df_temp = pd.read_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', encoding='utf-8')
142
+ df_temp = pd.read_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', encoding='utf-8')
141
143
  except FileNotFoundError:
142
144
  self.args.log.write("x WARNING! ROBERT stopped due to a problem with the AQME job. Please, check the previous AQME warnings.")
143
145
  sys.exit()
144
146
  df_temp.columns = [f'{col}_{smi_suffix}' if col not in ['code_name','SMILES'] and col not in aqme_args else col for col in df_temp.columns]
145
- df_temp.to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', index=False)
147
+ df_temp.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', index=False)
146
148
 
147
149
  # Check if there are missing rows in the AQME-ROBERT_{aqme_indv_name}.csv
148
150
  if len(df_temp) < len(csv_temp):
149
151
  missing_rows = csv_temp.loc[~csv_temp['code_name'].isin(df_temp['code_name'])]
150
- missing_rows[['code_name', 'SMILES']].to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', mode='a', header=False, index=False)
152
+ missing_rows[['code_name', 'SMILES']].to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', mode='a', header=False, index=False)
151
153
 
152
154
  # Get the order of code_name in aqme_indv_name
153
155
  order = csv_temp['code_name'].tolist()
154
156
 
155
157
  # Sort the rows in 'AQME-ROBERT_{aqme_indv_name}.csv' based on the order
156
- df_temp = pd.read_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', encoding='utf-8')
158
+ df_temp = pd.read_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', encoding='utf-8')
157
159
  df_temp = df_temp.sort_values(by='code_name', key=lambda x: x.map({v: i for i, v in enumerate(order)}))
158
160
 
159
161
  # Fill missing values with corresponding SMILES row
160
162
  df_temp = df_temp.fillna(df_temp.groupby('SMILES').transform('first'))
161
163
 
162
- df_temp.to_csv(f'AQME-ROBERT_{aqme_indv_name}.csv', index=False)
164
+ df_temp.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{aqme_indv_name}.csv', index=False)
163
165
 
164
166
  # return SDF files after csv_test
165
167
  if aqme_test:
@@ -169,23 +171,23 @@ class aqme:
169
171
  shutil.rmtree(path_sdf)
170
172
 
171
173
  # if AQME-ROBERT_AQME_indiv_n.csv >0 in folder:
172
- if len(glob.glob('AQME-ROBERT_AQME_indiv*.csv')) > 0:
174
+ if len(glob.glob(f'AQME-ROBERT_{self.args.descp_lvl}_AQME_indiv*.csv')) > 0:
173
175
 
174
176
  df_concat = pd.DataFrame()
175
177
 
176
178
  # Read and concatenate CSV files
177
- for file in sorted(glob.glob('AQME-ROBERT_AQME_indiv*.csv'), key=os.path.getmtime,reverse=True):
179
+ for file in sorted(glob.glob(f'AQME-ROBERT_{self.args.descp_lvl}_AQME_indiv*.csv'), key=os.path.getmtime,reverse=True):
178
180
  columns_to_drop = ['code_name', 'SMILES'] + aqme_args
179
181
  df_temp = pd.read_csv(file, encoding='utf-8')
180
182
  columns_to_drop = [col for col in columns_to_drop if col in df_temp.columns]
181
183
  df_temp = df_temp.drop(columns=columns_to_drop)
182
184
  df_concat = pd.concat([df_temp, df_concat], axis=1)
183
185
  df_concat = pd.concat([csv_df, df_concat], axis=1)
184
- df_concat.to_csv(f'AQME-ROBERT_{csv_target}', index=False)
186
+ df_concat.to_csv(f'AQME-ROBERT_{self.args.descp_lvl}_{csv_target}', index=False)
185
187
 
186
188
 
187
189
  # if no qdesc_atom is set, only keep molecular properties and discard atomic properties
188
- aqme_db = f'AQME-ROBERT_{csv_target}'
190
+ aqme_db = f'AQME-ROBERT_{self.args.descp_lvl}_{csv_target}'
189
191
 
190
192
  # ensure that the AQME database was successfully created
191
193
  if not os.path.exists(aqme_db):
@@ -226,7 +228,7 @@ class aqme:
226
228
  try:
227
229
  from aqme.qprep import qprep
228
230
  except ModuleNotFoundError:
229
- self.args.log.write("x AQME is not installed (required for the --aqme option)! You can install the program with 'conda install -c conda-forge aqme'")
231
+ self.args.log.write("x AQME is not installed (required for the --aqme option)! The program is typically installed within 2-5 minutes (https://aqme.readthedocs.io, see the Installation section)")
230
232
  sys.exit()
231
233
 
232
234
 
@@ -30,7 +30,7 @@ var_dict = {
30
30
  "corr_filter" : True,
31
31
  "desc_thres" : 25,
32
32
  "thres_y" : 0.001,
33
- "thres_x" : 0.9,
33
+ "thres_x" : 0.7,
34
34
  "test_set" : 0.1,
35
35
  "auto_test" : True,
36
36
  "train" : [60,70,80,90],
@@ -58,6 +58,7 @@ var_dict = {
58
58
  "pfi_show" : 10,
59
59
  "names" : '',
60
60
  "qdescp_keywords" : '',
61
+ "descp_lvl": "interpret",
61
62
  "csearch_keywords": '--sample 10',
62
63
  "report_modules" : ['AQME','CURATE','GENERATE','VERIFY','PREDICT'],
63
64
  "debug_report": False
@@ -32,9 +32,9 @@ Parameters
32
32
  desc_thres : float, default=25
33
33
  Threshold for the descriptor-to-datapoints ratio to loose the correlation filter. By default,
34
34
  the correlation filter is loosen if there are 25 times more datapoints than descriptors.
35
- thres_x : float, default=0.9
35
+ thres_x : float, default=0.7
36
36
  Thresolhold to discard descriptors based on high R**2 correlation with other descriptors (i.e.
37
- if thres_x=0.9, variables that show R**2 > 0.9 will be discarded).
37
+ if thres_x=0.7, variables that show R**2 > 0.7 will be discarded).
38
38
  thres_y : float, default=0.001
39
39
  Thresolhold to discard descriptors with poor correlation with the y values based on R**2 (i.e.
40
40
  if thres_y=0.001, variables that show R**2 < 0.001 will be discarded).
@@ -503,15 +503,15 @@ def print_predict(self,Xy_data,params_dict,path_n_suffix,loaded_model):
503
503
  if 'y_pred_csv_test' in Xy_data and not Xy_data['y_csv_test'].isnull().values.any() and len(Xy_data['y_csv_test']) > 0:
504
504
  print_results += f"\n - csv_test : R2 = {Xy_data['r2_csv_test']:.2}, MAE = {Xy_data['mae_csv_test']:.2}, RMSE = {Xy_data['rmse_csv_test']:.2}"
505
505
  # add equation for linear models
506
- if params_dict['model'].upper() == 'MVL':
506
+ if params_dict['model'].upper() == 'MVL' or self.args.evaluate == 'True':
507
507
  desc_mvl = ast.literal_eval(params_dict['X_descriptors'])
508
508
  print_results += f"\n\n o Linear model equation, with coefficients obtained using standardized data (coefficient values/importances can be compared):"
509
509
  print_results += f"\n - {params_dict['y']} = {loaded_model.intercept_:.2} "
510
- for i,coeff in enumerate(loaded_model.coef_):
510
+ for i, coeff in enumerate(loaded_model.coef_):
511
511
  if float(coeff) >= 0:
512
- print_results += f"+ {coeff:.2}·{desc_mvl[i]} "
512
+ print_results += f"+ ({coeff:.2} * {desc_mvl[i]}) "
513
513
  else:
514
- print_results += f"- {np.abs(coeff):.2}·{desc_mvl[i]} "
514
+ print_results += f"- ({np.abs(coeff):.2} * {desc_mvl[i]}) "
515
515
 
516
516
  elif params_dict['type'].lower() == 'clas':
517
517
  print_results += f"\n - Train : Accuracy = {Xy_data['acc_train']:.2}, F1 score = {Xy_data['f1_train']:.2}, MCC = {Xy_data['mcc_train']:.2}"
@@ -1040,9 +1040,9 @@ def pearson_map_predict(self,Xy_data,params_dir):
1040
1040
  max_r = corr_dict['r'][abs_r_list.index(abs_max_r)]
1041
1041
  max_descp_1 = corr_dict['descp_1'][abs_r_list.index(abs_max_r)]
1042
1042
  max_descp_2 = corr_dict['descp_2'][abs_r_list.index(abs_max_r)]
1043
- if abs_max_r > 0.95:
1043
+ if abs_max_r > 0.84:
1044
1044
  print_corr += f"\n x WARNING! High correlations observed (up to r = {round(max_r,2)} or R2 = {round(max_r*max_r,2)}, for {max_descp_1} and {max_descp_2})"
1045
- elif abs_max_r > 0.8:
1045
+ elif abs_max_r > 0.71:
1046
1046
  print_corr += f"\n x WARNING! Noticeable correlations observed (up to r = {round(max_r,2)} or R2 = {round(max_r*max_r,2)}, for {max_descp_1} and {max_descp_2})"
1047
1047
 
1048
1048
  self.args.log.write(print_corr)
@@ -68,7 +68,7 @@ class report:
68
68
  try:
69
69
  from weasyprint import HTML
70
70
  except (OSError, ModuleNotFoundError):
71
- print(f"\n x The REPORT module requires weasyprint but this module is missing, the PDF with the summary of the results has not been created. Try installing ROBERT with 'conda install -c conda-forge robert'")
71
+ print(f"\n x The REPORT module requires weasyprint but this module is missing, the PDF with the summary of the results has not been created. Try installing ROBERT with 'conda install -y -c conda-forge robert'")
72
72
  sys.exit()
73
73
 
74
74
  # load default and user-specified variables
@@ -676,8 +676,27 @@ class report:
676
676
 
677
677
  # starts with the icon of feature importances
678
678
  feature_dat = ''
679
- feature_dat = self.module_lines('features',feature_dat)
679
+ feature_dat = self.module_lines('features',feature_dat)
680
680
 
681
+ # Add linear model equations
682
+ spacing = get_spacing_col('PFI',spacing_PFI)
683
+ with open(f'{os.getcwd()}/PREDICT/PREDICT_data.dat', 'r') as file:
684
+ lines = file.readlines()
685
+ linear_model_eqs = [lines[i + 1].strip().lstrip('- ') for i, line in enumerate(lines) if 'o Linear model equation' in line]
686
+
687
+ if linear_model_eqs:
688
+ feature_dat += "<p style='margin-top:-5px; margin-bottom:-6px'><span style='font-weight:bold;'>Linear model equation_No_PFI</span></p>"
689
+ if len(linear_model_eqs) == 1:
690
+ feature_dat += f"<p style='margin-top:10px; margin-bottom:35px'>{linear_model_eqs[0]}</p>"
691
+ else:
692
+ columns_eq = []
693
+ for i, eq in enumerate(linear_model_eqs):
694
+ if i == 0:
695
+ columns_eq.append(f"<p style='margin-top:10px; margin-bottom:35px'>{eq}</p>")
696
+ else:
697
+ columns_eq.append(f"<p style='margin-top:-5px; margin-bottom:-6px'><span style='font-weight:bold;'>{spacing*3}Linear model equation_PFI</span></p><p style='margin-top:10px; margin-bottom:35px'>{spacing*3}{eq}</p>")
698
+ feature_dat += combine_cols(columns_eq)
699
+
681
700
  # add corresponding images
682
701
  module_path = Path(f'{os.getcwd()}/PREDICT')
683
702
 
@@ -855,7 +874,7 @@ class report:
855
874
  repro_dat += f"""<p style="text-align: justify; margin-top: -44px;"><br><strong>2. Install and adjust the versions of the following Python modules:</strong></p>"""
856
875
  else:
857
876
  repro_dat += f"""{first_line}<br><strong>2. Install and adjust the versions of the following Python modules:</strong></p>"""
858
- repro_dat += f"""{reduced_line}{space}- Install ROBERT and its dependencies: conda install -c conda-forge robert</p>"""
877
+ repro_dat += f"""{reduced_line}{space}- Install ROBERT and its dependencies: conda install -y -c conda-forge robert</p>"""
859
878
  repro_dat += f"""{reduced_line}{space}- Adjust ROBERT version: pip install robert=={robert_version}</p>"""
860
879
 
861
880
  if intelex_version != 'not installed':
@@ -868,7 +887,7 @@ class report:
868
887
  if aqme_workflow:
869
888
  if not find_aqme:
870
889
  repro_dat += f"""{reduced_line}{space}- AQME is required, but no version was found:</p>"""
871
- repro_dat += f"""{reduced_line}{space}- Install AQME and its dependencies: conda install -c conda-forge aqme</p>"""
890
+ repro_dat += f"""{reduced_line}{space}- Install AQME and its dependencies: conda install -y -c conda-forge aqme</p>"""
872
891
  if find_aqme:
873
892
  repro_dat += f"""{reduced_line}{space}- Adjust AQME version: pip install aqme=={aqme_version}</p>"""
874
893
 
@@ -884,9 +903,9 @@ class report:
884
903
  find_xtb = False
885
904
  if not find_xtb:
886
905
  repro_dat += f"""{reduced_line}{space}- xTB is required, but no version was found:</p>"""
887
- repro_dat += f"""{reduced_line}{space}- Install xTB: conda install -c conda-forge xtb</p>"""
906
+ repro_dat += f"""{reduced_line}{space}- Install xTB: conda install -y -c conda-forge xtb</p>"""
888
907
  if find_xtb:
889
- repro_dat += f"""{reduced_line}{space}- Adjust xTB version (if possible): conda install -c conda-forge xtb={xtb_version}</p>"""
908
+ repro_dat += f"""{reduced_line}{space}- Adjust xTB version (if possible): conda install -y -c conda-forge xtb={xtb_version}</p>"""
890
909
 
891
910
  if crest_workflow:
892
911
  try:
@@ -434,6 +434,7 @@ def get_col_score(score_info,data_score,suffix,spacing,eval_only):
434
434
  column = f"""<p style="margin-top:-18px;"><span style="font-weight:bold;">{title_line}</span></p>
435
435
  {ML_line_format}Model = {data_score['ML_model']}&nbsp;&nbsp;·&nbsp;&nbsp;{partitions_ratio}</p>
436
436
  {part_line_format}Points(train+valid.):descriptors = {data_score[f'points_descp_ratio_{suffix}']}</p>
437
+ {part_line_format}Score = {data_score[f'robert_score_{suffix}']} / 10</p>
437
438
  <p style="margin-top: 4px;">{score_info}
438
439
  <p style="margin-bottom: 18px;"></p>
439
440
  """
@@ -73,9 +73,9 @@ def main(exe_type='command',sys_args=None):
73
73
  if args.aqme:
74
74
  aqme(**vars(args))
75
75
  # set the path to the database created by AQME to continue in the full_workflow
76
- args.csv_name = Path(os.path.dirname(args.csv_name)).joinpath(f'AQME-ROBERT_{os.path.basename(args.csv_name)}')
76
+ args.csv_name = Path(os.path.dirname(args.csv_name)).joinpath(f'AQME-ROBERT_{args.descp_lvl}_{os.path.basename(args.csv_name)}')
77
77
  if args.csv_test != '':
78
- args.csv_test = Path(os.path.dirname(args.csv_test)).joinpath(f'AQME-ROBERT_{os.path.basename(args.csv_test)}')
78
+ args.csv_test = Path(os.path.dirname(args.csv_test)).joinpath(f'AQME-ROBERT_{args.descp_lvl}_{os.path.basename(args.csv_test)}')
79
79
 
80
80
  # CURATE
81
81
  if args.curate or full_workflow:
@@ -39,14 +39,15 @@ from sklearn.ensemble import (
39
39
  from sklearn.gaussian_process import GaussianProcessRegressor, GaussianProcessClassifier
40
40
  from sklearn.neural_network import MLPRegressor, MLPClassifier
41
41
  from sklearn.linear_model import LinearRegression
42
+ from sklearn.impute import KNNImputer
42
43
  from mapie.regression import MapieRegressor
43
44
  from mapie.conformity_scores import AbsoluteConformityScore
44
45
  import warnings # this avoids warnings from sklearn
45
46
  warnings.filterwarnings("ignore")
46
47
 
47
- robert_version = "1.2.0"
48
+ robert_version = "1.2.1"
48
49
  time_run = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
49
- robert_ref = "Dalmau, D.; Alegre Requena, J. V. ChemRxiv, 2023, DOI: 10.26434/chemrxiv-2023-k994h"
50
+ robert_ref = "Dalmau, D.; Alegre Requena, J. V. WIREs Comput Mol Sci. 2024, DOI: 10.1002/WCMS.1733"
50
51
 
51
52
 
52
53
  # load paramters from yaml file
@@ -128,7 +129,7 @@ def command_line_args(exe_type,sys_args):
128
129
  "aqme",
129
130
  "report",
130
131
  "cheers",
131
- "evaluate"
132
+ "evaluate",
132
133
  ]
133
134
  list_args = [
134
135
  "discard",
@@ -136,7 +137,7 @@ def command_line_args(exe_type,sys_args):
136
137
  "train",
137
138
  "model",
138
139
  "report_modules",
139
- "seed"
140
+ "seed",
140
141
  ]
141
142
  int_args = [
142
143
  'pfi_epochs',
@@ -229,6 +230,7 @@ o Other common options:
229
230
  * Affecting SMILES workflows, AQME:
230
231
  --qdescp_keywords STR (default="") : extra keywords in QDESCP (i.e. "--qdescp_atoms [Ir] --alpb h2o")
231
232
  --csearch_keywords STR (default="--sample 50") : extra keywords in CSEARCH
233
+ --descp_lvl (default="interpret") "interpret", "denovo" or "full" : type of descriptor calculation
232
234
 
233
235
 
234
236
  o How to cite ROBERT:
@@ -304,6 +306,10 @@ def load_variables(kwargs, robert_module):
304
306
  if not os.path.exists(f"{self.csv_name}") and os.path.exists(f'{self.csv_name}.csv'):
305
307
  self.csv_name = f'{self.csv_name}.csv'
306
308
 
309
+ # check if user used .csv in csv_test
310
+ if self.csv_test and not os.path.exists(f"{self.csv_test}") and os.path.exists(f'{self.csv_test}.csv'):
311
+ self.csv_test = f'{self.csv_test}.csv'
312
+
307
313
  if robert_module != "command":
308
314
  self.initial_dir = Path(os.getcwd())
309
315
 
@@ -789,8 +795,14 @@ def load_database(self,csv_load,module):
789
795
  txt_load += f'\nx WARNING! The original database was not a valid CSV (i.e., formatting issues from Microsoft Excel?). A new database using commas as separators was created and used instead, and the original database was stored as {new_csv_name}. To prevent this issue from happening again, you should use commas as separators: https://support.edapp.com/change-csv-separator.\n\n'
790
796
 
791
797
  csv_df = pd.read_csv(csv_load, encoding='utf-8')
792
- # Fill missing values with zeros
793
- csv_df = csv_df.fillna(0)
798
+ # Fill missing values using KNN imputer
799
+ csv_df = csv_df.dropna(axis=1, thresh=int(0.7 * len(csv_df))) # Remove columns with less than 70% of the data
800
+ int_columns = csv_df.select_dtypes(include=['int']).columns
801
+ numeric_columns = csv_df.select_dtypes(include=['float']).columns
802
+ imputer = KNNImputer(n_neighbors=5)
803
+ if csv_df[numeric_columns].isna().any().any():
804
+ csv_df[numeric_columns] = pd.DataFrame(imputer.fit_transform(csv_df[numeric_columns]), columns=numeric_columns)
805
+ csv_df[int_columns] = csv_df[int_columns]
794
806
 
795
807
  if module.lower() not in ['verify','no_print','evaluate']:
796
808
  sanity_checks(self.args,'csv_db',module,csv_df.columns)
@@ -901,6 +913,7 @@ def load_model_reg(params):
901
913
  params = correct_hidden_layers(params)
902
914
 
903
915
  loaded_model = MLPRegressor(batch_size=params['batch_size'],
916
+ solver='lbfgs',
904
917
  hidden_layer_sizes=params['hidden_layer_sizes'],
905
918
  learning_rate_init=params['learning_rate_init'],
906
919
  max_iter=params['max_iter'],
@@ -980,6 +993,7 @@ def load_model_clas(params):
980
993
  params = correct_hidden_layers(params)
981
994
 
982
995
  loaded_model = MLPClassifier(batch_size=params['batch_size'],
996
+ solver='lbfgs',
983
997
  hidden_layer_sizes=params['hidden_layer_sizes'],
984
998
  learning_rate_init=params['learning_rate_init'],
985
999
  max_iter=params['max_iter'],
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robert
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
5
  Home-page: https://github.com/jvalegre/robert
6
- Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.0.tar.gz
6
+ Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.1.tar.gz
7
7
  Author: Juan V. Alegre Requena, David Dalmau
8
8
  Author-email: jv.alegre@csic.es
9
9
  License: MIT
@@ -1,5 +1,5 @@
1
1
  from setuptools import setup, find_packages
2
- version="1.2.0"
2
+ version="1.2.1"
3
3
  setup(
4
4
  name="robert",
5
5
  packages=find_packages(exclude=["tests"]),
@@ -86,7 +86,7 @@ def test_CURATE(test_job):
86
86
  # 1. Duplicate entries are removed
87
87
  assert len(db_final['Name']) == 37
88
88
  # 2. Correlated variables with X and noise (low R2 with y) are removed
89
- discard_vars = ['x1','x3','ynoise']
89
+ discard_vars = ['x1','x3','x5', 'x6','ynoise']
90
90
  for var in discard_vars:
91
91
  assert var not in db_final.columns
92
92
  # 3. Ignored variables and y are kept
@@ -95,12 +95,12 @@ def test_CURATE(test_job):
95
95
  # 4. Discarded variables are removed
96
96
  assert 'xtest' not in db_final.columns
97
97
  # 5. The rest of the variables are kept
98
- final_vars = ['x2','x5','x6','x7','x8','x9','x10','x11']
98
+ final_vars = ['x2','x7','x8','x9','x10','x11']
99
99
  for var in final_vars:
100
100
  assert var in db_final.columns
101
101
 
102
102
  # check that categorical variables are converted with one-hot encoding
103
- categ_vars = ['Csub-H','Csub-Csub','H-O','Csub-O']
103
+ categ_vars = ['Csub-H','Csub-Csub','H-O']
104
104
  for var in categ_vars:
105
105
  assert var in db_final.columns
106
106
  assert 'x4' not in db_final.columns
@@ -144,11 +144,11 @@ def test_CURATE(test_job):
144
144
  ]
145
145
  subprocess.run(cmd_robert)
146
146
 
147
- # check that all the missing values were filled with 0s
147
+ # check that all the missing values were filled
148
148
  db_final = pd.read_csv(f"{path_curate}/Robert_example_NaNs_CURATE.csv")
149
149
  # 1. Duplicate entries are removed
150
- assert db_final['x3'][0] == 0
151
- assert db_final['x3'][8] == 0
150
+ assert isinstance(db_final['x2'][4], (int, float))
151
+ assert isinstance(db_final['x2'][0], (int, float))
152
152
 
153
153
  elif test_job == 'corr_filter':
154
154
  cmd_robert = [
@@ -143,7 +143,7 @@ def test_GENERATE(test_job):
143
143
  assert "ROBERT v" in outlines[0]
144
144
  assert "- 37 datapoints" in outlines[9]
145
145
  if test_job != 'reduced_clas':
146
- assert "- 12 accepted descriptors" in outlines[10]
146
+ assert "- 9 accepted descriptors" in outlines[10]
147
147
  else:
148
148
  assert "- 9 accepted descriptors" in outlines[10]
149
149
  assert "- 1 ignored descriptors" in outlines[11]
@@ -185,26 +185,26 @@ def test_GENERATE(test_job):
185
185
  if test_job in ['reduced','reduced_PFImax','reduced_rnd']:
186
186
  if folder == 'No_PFI':
187
187
  if test_job != 'reduced_clas':
188
- desc_list = ['x2', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10', 'x11', 'Csub-Csub', 'Csub-H', 'Csub-O', 'H-O']
188
+ desc_list = ['x2', 'x7', 'x8', 'x9', 'x10', 'x11', 'Csub-Csub', 'Csub-H', 'H-O']
189
189
  else:
190
190
  desc_list = ['x1', 'x2', 'x3', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10']
191
191
  elif folder == 'PFI':
192
192
  if test_job == 'reduced':
193
- desc_list = ['x6', 'x7', 'x10']
193
+ desc_list = ['x7', 'x9', 'x10']
194
194
  elif test_job == 'reduced_rnd':
195
- desc_list = ['x6', 'x7', 'x9', 'x10']
195
+ desc_list = ['x7', 'x9', 'x10']
196
196
  elif test_job =='reduced_PFImax':
197
- desc_list = ['x6', 'x7']
197
+ desc_list = ['x7', 'x9']
198
198
 
199
199
  if test_job in ['reduced','reduced_rnd']:
200
200
  sum_split = 0
201
201
  if db_best['Set'][0] == 'Training':
202
202
  sum_split += 1
203
- if db_best['Set'][1] == 'Training':
203
+ if db_best['Set'][1] == 'Validation':
204
204
  sum_split += 1
205
205
  if db_best['Set'][2] == 'Training':
206
206
  sum_split += 1
207
- if db_best['Set'][3] == 'Validation':
207
+ if db_best['Set'][3] == 'Training':
208
208
  sum_split += 1
209
209
  if test_job == 'reduced':
210
210
  assert sum_split == 4
@@ -106,7 +106,7 @@ def test_PREDICT(test_job):
106
106
  if 'x WARNING! High correlations observed (up to r = 1.0 or R2 = 1.0, for x1 and x3)' in line:
107
107
  pearson_found = True
108
108
  else:
109
- if 'x WARNING! Noticeable correlations observed (up to r = -0.92 or R2 = 0.85, for x6 and x10)' in line:
109
+ if 'o Correlations between variables are acceptable' in line:
110
110
  pearson_found = True
111
111
  if test_job == "clas":
112
112
  if 'o Your data seems quite uniform' in line:
@@ -80,7 +80,7 @@ def test_AQME(test_job):
80
80
  "--epochs", "5",
81
81
  "--seed", "[0]",
82
82
  "--model", "['RF']",
83
- "--train", "[60]",
83
+ "--train", "[70]",
84
84
  "--pfi_epochs", "1",
85
85
  "--debug_report", "True"
86
86
  ]
@@ -150,9 +150,9 @@ def test_AQME(test_job):
150
150
  assert len(glob.glob(f'{path_main}/PREDICT/*.csv')) == 4
151
151
 
152
152
  if test_job == 'aqme':
153
- assert os.path.exists(f'{path_main}/AQME-ROBERT_solubility.csv')
154
- db_aqme = pd.read_csv(f'{path_main}/AQME-ROBERT_solubility.csv')
155
- descps = ['code_name','solub','C_FUKUI+','MolLogP']
153
+ assert os.path.exists(f'{path_main}/AQME-ROBERT_interpret_solubility.csv')
154
+ db_aqme = pd.read_csv(f'{path_main}/AQME-ROBERT_interpret_solubility.csv')
155
+ descps = ['code_name','solub','HOMO','Total charge']
156
156
  for descp in descps:
157
157
  assert descp in db_aqme.columns
158
158
  assert 'smiles' in db_aqme.columns
@@ -164,12 +164,12 @@ def test_AQME(test_job):
164
164
  assert "ROBERT v" in outlines[0]
165
165
  assert os.path.exists(f'{path_aqme}/CSEARCH')
166
166
  assert os.path.exists(f'{path_aqme}/QDESCP')
167
- assert len(glob.glob(f'{path_aqme}/*.csv')) == 1
167
+ assert len(glob.glob(f'{path_aqme}/*.csv')) == 0
168
168
  assert len(glob.glob(f'{path_aqme}/*.dat')) == 3
169
169
 
170
170
  if test_job == '2smiles_columns':
171
- assert os.path.exists(f'{path_main}/AQME-ROBERT_solubility_solvent.csv')
172
- db_aqme = pd.read_csv(f'{path_main}/AQME-ROBERT_solubility_solvent.csv')
171
+ assert os.path.exists(f'{path_main}/AQME-ROBERT_interpret_solubility_solvent.csv')
172
+ db_aqme = pd.read_csv(f'{path_main}/AQME-ROBERT_interpret_solubility_solvent.csv')
173
173
  assert 'smiles_sub' and 'smiles_solvent' in db_aqme.columns
174
174
 
175
175
  # find important parts in ROBERT_report
@@ -185,19 +185,19 @@ def test_AQME(test_job):
185
185
  for line in outlines:
186
186
  if 'Heatmap_ML_models_No_PFI.png' in line:
187
187
  find_heatmap += 1
188
- if 'VERIFY_tests_RF_60_PFI.png' in line:
188
+ if 'VERIFY_tests_RF_70_PFI.png' in line:
189
189
  find_verify += 1
190
- if 'SHAP_RF_60_PFI.png' in line:
190
+ if 'SHAP_RF_70_PFI.png' in line:
191
191
  find_shap += 1
192
- if 'PFI_RF_60_PFI.png' in line:
192
+ if 'PFI_RF_70_PFI.png' in line:
193
193
  find_pfi += 1
194
- if 'Outliers_RF_60_No_PFI.png' in line:
194
+ if 'Outliers_RF_70_No_PFI.png' in line:
195
195
  find_outliers += 1
196
- if 'Results_RF_60_No_PFI.png' in line:
196
+ if 'Results_RF_70_No_PFI.png' in line:
197
197
  find_results_reg += 1
198
- if 'Results_RF_60_No_PFI_valid.png' in line:
198
+ if 'Results_RF_70_No_PFI_valid.png' in line:
199
199
  find_results_valid_clas += 1
200
- if 'Results_RF_60_No_PFI_csv_test.png' in line:
200
+ if 'Results_RF_70_No_PFI_csv_test.png' in line:
201
201
  find_results_test_clas += 1
202
202
  if 'csv_test :' in line:
203
203
  find_test += 1
@@ -210,7 +210,7 @@ def test_AQME(test_job):
210
210
  predict_graphs,flawed_image,cv_r2_image,cv_sd_image = False,False,False,False
211
211
  y_distrib_image,pearson_pred_image = False,False
212
212
  find_severe_red,find_severe_blue = False,False
213
- find_moder_pred,find_moder_y_dist,find_moder_corr = False,False,False
213
+ find_moder_pred,find_moder_y_dist,unclear_test = False,False,False
214
214
  find_assess_yellow,find_assess_red = False,False
215
215
 
216
216
  for i,line in enumerate(outlines):
@@ -218,31 +218,31 @@ def test_AQME(test_job):
218
218
  robert_score.append(line.split('robert/report/score_')[1][0])
219
219
  if 'Model = RF' in line:
220
220
  ml_model_count += 1
221
- if 'Train:Validation = 59:41' in line:
221
+ if 'Train:Validation = 68:32' in line:
222
222
  partition_count += 1
223
223
  if 'Points(train+valid.):descriptors = ' in line:
224
224
  points_desc.append(line.split('Points(train+valid.):descriptors = ')[1].split('</p>')[0])
225
- if 'Results_RF_60_No_PFI.png' in line:
225
+ if 'Results_RF_70_No_PFI.png' in line:
226
226
  predict_graphs = True
227
227
  if 'Train : R<sup>2</sup> = ' in line:
228
228
  metrics_count += 1
229
229
  if '1. Model vs "flawed" models' in line:
230
230
  flawed_models.append(line)
231
- if 'VERIFY/VERIFY_tests_RF_60_No_PFI.png' in line:
231
+ if 'VERIFY/VERIFY_tests_RF_70_No_PFI.png' in line:
232
232
  flawed_image = True
233
233
  if '2. Predictive ability of the model' in line:
234
234
  pred_ability.append(line)
235
235
  if '3a. CV predictions train + valid.' in line:
236
236
  cv_r2_models.append(line)
237
- if 'VERIFY/CV_train_valid_predict_RF_60_No_PFI.png' in line:
237
+ if 'VERIFY/CV_train_valid_predict_RF_70_No_PFI.png' in line:
238
238
  cv_r2_image = True
239
239
  if '3b. Avg. standard deviation (SD)' in line:
240
240
  cv_sd_models.append(line)
241
- if 'PREDICT/CV_variability_RF_60_No_PFI.png' in line:
241
+ if 'PREDICT/CV_variability_RF_70_No_PFI.png' in line:
242
242
  cv_sd_image = True
243
243
  if '4. Points(train+valid.):descriptors' in line:
244
244
  points_descp.append(line)
245
- if 'y_distribution_RF_60_No_PFI.png' in line:
245
+ if 'y_distribution_RF_70_No_PFI.png' in line:
246
246
  y_distrib_image = True
247
247
  if 'Pearson_heatmap_No_PFI.png' in line:
248
248
  pearson_pred_image = True
@@ -254,8 +254,8 @@ def test_AQME(test_job):
254
254
  find_moder_pred = True
255
255
  if 'Slightly uneven y distribution (Section C)' in line and 'color: #c5c57d' in outlines[i-1]:
256
256
  find_moder_y_dist = True
257
- if 'Moderately correlated features (Section D)' in line and 'color: #c5c57d' in outlines[i-1]:
258
- find_moder_corr = True
257
+ if 'Some tests are unclear (Section B.1)' in line and 'color: #c5c57d' in outlines[i-1]:
258
+ unclear_test = True
259
259
  if 'Decent model, but it has limitations' in line and 'color: #c5c57d' in outlines[i-1]:
260
260
  find_assess_yellow = True
261
261
  if 'The model is unreliable' in line and 'color: #c56666' in outlines[i-1]:
@@ -264,23 +264,23 @@ def test_AQME(test_job):
264
264
  break
265
265
 
266
266
  # model summary, robert score, predict graphs and model metrics
267
- assert robert_score[0] == '3'
268
- assert robert_score[1] == '8'
267
+ assert robert_score[0] == '4'
268
+ assert robert_score[1] == '7'
269
269
  assert ml_model_count == 2
270
270
  assert partition_count == 2
271
- assert points_desc[0] == '37:12'
271
+ assert points_desc[0] == '37:9'
272
272
  assert points_desc[1] == '37:3'
273
273
  assert predict_graphs
274
274
  assert metrics_count == 2
275
275
  # advanced analysis, flawed models section 1
276
276
  assert '1 / 3' in flawed_models[0]
277
277
  assert 'robert/report/score_w_3_1.jpg' in flawed_models[0]
278
- assert '3 / 3' in flawed_models[1]
279
- assert 'robert/report/score_w_3_3.jpg' in flawed_models[1]
278
+ assert '2 / 3' in flawed_models[1]
279
+ assert 'robert/report/score_w_3_2.jpg' in flawed_models[1]
280
280
  assert flawed_image
281
281
  # advanced analysis, predictive ability section 2
282
- assert '1 / 2' in pred_ability[0]
283
- assert 'robert/report/score_w_2_1.jpg' in pred_ability[0]
282
+ assert '2 / 2' in pred_ability[0]
283
+ assert 'robert/report/score_w_2_2.jpg' in pred_ability[0]
284
284
  assert '2 / 2' in pred_ability[1]
285
285
  assert 'robert/report/score_w_2_2.jpg' in pred_ability[1]
286
286
  # advanced analysis, CV predictive ability section 3a
@@ -308,7 +308,7 @@ def test_AQME(test_job):
308
308
  assert find_severe_blue
309
309
  assert find_moder_pred
310
310
  assert find_moder_y_dist
311
- assert find_moder_corr
311
+ assert unclear_test
312
312
  assert find_assess_yellow
313
313
  assert find_assess_red
314
314
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
 
3
3
  ######################################################.
4
- # Testing AQME with pytest #
4
+ # Testing EVALUATE with pytest #
5
5
  ######################################################.
6
6
 
7
7
  import os
@@ -32,7 +32,7 @@ path_tests = os.getcwd() + "/tests"
32
32
  ), # test that if the --csv_train or --csv_valid options are empty, a prompt pops up and asks for them
33
33
  ],
34
34
  )
35
- def test_eval(test_job):
35
+ def test_EVALUATE(test_job):
36
36
 
37
37
  # reset the folders (to avoid interferences with previous failed tests)
38
38
  folders = ['CURATE','GENERATE','GENERATE_reg','GENERATE_clas','PREDICT','VERIFY','AQME','EVALUATE']
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes