robert 1.2.1__tar.gz → 2.0.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 (90) hide show
  1. {robert-1.2.1 → robert-2.0.1}/LICENSE +0 -0
  2. {robert-1.2.1 → robert-2.0.1}/PKG-INFO +38 -36
  3. {robert-1.2.1 → robert-2.0.1}/README.md +12 -8
  4. {robert-1.2.1 → robert-2.0.1}/robert/__init__.py +0 -0
  5. {robert-1.2.1 → robert-2.0.1}/robert/__main__.py +0 -0
  6. {robert-1.2.1 → robert-2.0.1}/robert/aqme.py +10 -18
  7. {robert-1.2.1 → robert-2.0.1}/robert/argument_parser.py +13 -13
  8. robert-2.0.1/robert/curate.py +160 -0
  9. {robert-1.2.1 → robert-2.0.1}/robert/evaluate.py +12 -10
  10. robert-2.0.1/robert/generate.py +184 -0
  11. robert-2.0.1/robert/generate_utils.py +223 -0
  12. robert-2.0.1/robert/icons/Robert_icon.png +0 -0
  13. {robert-1.2.1/robert/report → robert-2.0.1/robert/icons}/Robert_logo.jpg +0 -0
  14. robert-2.0.1/robert/icons/Robert_logo_transparent.png +0 -0
  15. robert-2.0.1/robert/icons/info_icon.png +0 -0
  16. robert-2.0.1/robert/icons/pdf_icon.png +0 -0
  17. robert-2.0.1/robert/icons/play_icon.png +0 -0
  18. robert-2.0.1/robert/icons/stop_icon.png +0 -0
  19. {robert-1.2.1 → robert-2.0.1}/robert/model_params/ADAB_params.yaml +1 -4
  20. {robert-1.2.1 → robert-2.0.1}/robert/model_params/GB_params.yaml +10 -10
  21. robert-2.0.1/robert/model_params/GP_params.yaml +2 -0
  22. robert-2.0.1/robert/model_params/MVL_params.yaml +2 -0
  23. robert-2.0.1/robert/model_params/NN_params.yaml +11 -0
  24. {robert-1.2.1 → robert-2.0.1}/robert/model_params/RF_params.yaml +8 -8
  25. robert-2.0.1/robert/model_params/VR_params.yaml +28 -0
  26. {robert-1.2.1 → robert-2.0.1}/robert/predict.py +20 -30
  27. robert-2.0.1/robert/predict_utils.py +227 -0
  28. {robert-1.2.1 → robert-2.0.1}/robert/report/Robert_icon.ico +0 -0
  29. robert-2.0.1/robert/report/Robert_logo.jpg +0 -0
  30. {robert-1.2.1 → robert-2.0.1}/robert/report/Robert_logo1.jpg +0 -0
  31. {robert-1.2.1 → robert-2.0.1}/robert/report/abbrev.png +0 -0
  32. {robert-1.2.1 → robert-2.0.1}/robert/report/adv_anal.png +0 -0
  33. {robert-1.2.1 → robert-2.0.1}/robert/report/features.png +0 -0
  34. robert-1.2.1/robert/report/GENERATE.png → robert-2.0.1/robert/report/generate.png +0 -0
  35. {robert-1.2.1 → robert-2.0.1}/robert/report/outliers.png +0 -0
  36. {robert-1.2.1 → robert-2.0.1}/robert/report/pred.png +0 -0
  37. {robert-1.2.1 → robert-2.0.1}/robert/report/repro.png +0 -0
  38. {robert-1.2.1 → robert-2.0.1}/robert/report/score.png +0 -0
  39. {robert-1.2.1 → robert-2.0.1}/robert/report/score_0.jpg +0 -0
  40. {robert-1.2.1 → robert-2.0.1}/robert/report/score_1.jpg +0 -0
  41. {robert-1.2.1 → robert-2.0.1}/robert/report/score_10.jpg +0 -0
  42. {robert-1.2.1 → robert-2.0.1}/robert/report/score_2.jpg +0 -0
  43. {robert-1.2.1 → robert-2.0.1}/robert/report/score_3.jpg +0 -0
  44. {robert-1.2.1 → robert-2.0.1}/robert/report/score_4.jpg +0 -0
  45. {robert-1.2.1 → robert-2.0.1}/robert/report/score_5.jpg +0 -0
  46. {robert-1.2.1 → robert-2.0.1}/robert/report/score_6.jpg +0 -0
  47. {robert-1.2.1 → robert-2.0.1}/robert/report/score_7.jpg +0 -0
  48. {robert-1.2.1 → robert-2.0.1}/robert/report/score_8.jpg +0 -0
  49. {robert-1.2.1 → robert-2.0.1}/robert/report/score_9.jpg +0 -0
  50. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_1_0.jpg +0 -0
  51. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_1_1.jpg +0 -0
  52. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_2_0.jpg +0 -0
  53. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_2_1.jpg +0 -0
  54. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_2_2.jpg +0 -0
  55. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_3_0.jpg +0 -0
  56. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_3_1.jpg +0 -0
  57. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_3_2.jpg +0 -0
  58. {robert-1.2.1 → robert-2.0.1}/robert/report/score_w_3_3.jpg +0 -0
  59. {robert-1.2.1 → robert-2.0.1}/robert/report/transpa.png +0 -0
  60. {robert-1.2.1 → robert-2.0.1}/robert/report/y_distrib.png +0 -0
  61. {robert-1.2.1 → robert-2.0.1}/robert/report.py +48 -54
  62. {robert-1.2.1 → robert-2.0.1}/robert/report_utils.py +403 -243
  63. {robert-1.2.1 → robert-2.0.1}/robert/robert.py +4 -0
  64. robert-2.0.1/robert/utils.py +2907 -0
  65. robert-2.0.1/robert/verify.py +271 -0
  66. {robert-1.2.1 → robert-2.0.1}/robert.egg-info/PKG-INFO +38 -36
  67. {robert-1.2.1 → robert-2.0.1}/robert.egg-info/SOURCES.txt +9 -2
  68. {robert-1.2.1 → robert-2.0.1}/robert.egg-info/dependency_links.txt +0 -0
  69. robert-2.0.1/robert.egg-info/requires.txt +15 -0
  70. {robert-1.2.1 → robert-2.0.1}/robert.egg-info/top_level.txt +0 -0
  71. {robert-1.2.1 → robert-2.0.1}/setup.cfg +10 -10
  72. {robert-1.2.1 → robert-2.0.1}/setup.py +13 -11
  73. {robert-1.2.1 → robert-2.0.1}/tests/test_1curate.py +50 -9
  74. robert-2.0.1/tests/test_2generate.py +248 -0
  75. {robert-1.2.1 → robert-2.0.1}/tests/test_3verify.py +22 -20
  76. {robert-1.2.1 → robert-2.0.1}/tests/test_4predict.py +22 -11
  77. {robert-1.2.1 → robert-2.0.1}/tests/test_5aqme_n_full.py +141 -101
  78. robert-1.2.1/robert/curate.py +0 -311
  79. robert-1.2.1/robert/generate.py +0 -327
  80. robert-1.2.1/robert/generate_utils.py +0 -759
  81. robert-1.2.1/robert/model_params/GP_params.yaml +0 -2
  82. robert-1.2.1/robert/model_params/MVL_params.yaml +0 -2
  83. robert-1.2.1/robert/model_params/NN_params.yaml +0 -35
  84. robert-1.2.1/robert/model_params/VR_params.yaml +0 -28
  85. robert-1.2.1/robert/predict_utils.py +0 -1048
  86. robert-1.2.1/robert/utils.py +0 -1390
  87. robert-1.2.1/robert/verify.py +0 -467
  88. robert-1.2.1/robert.egg-info/requires.txt +0 -13
  89. robert-1.2.1/tests/test_2generate.py +0 -243
  90. robert-1.2.1/tests/test_6evaluate.py +0 -276
File without changes
@@ -1,36 +1,38 @@
1
- Metadata-Version: 2.1
2
- Name: robert
3
- Version: 1.2.1
4
- Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
- Home-page: https://github.com/jvalegre/robert
6
- Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/1.2.1.tar.gz
7
- Author: Juan V. Alegre Requena, David Dalmau
8
- Author-email: jv.alegre@csic.es
9
- License: MIT
10
- Keywords: workflows,machine learning,cheminformatics,data curation,prediction,automated
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Software Development :: Build Tools
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Requires-Python: >=3.10
20
- Description-Content-Type: text/markdown
21
- License-File: LICENSE
22
- Requires-Dist: PyYAML==6.0.1
23
- Requires-Dist: matplotlib==3.9.2
24
- Requires-Dist: pandas==2.2.2
25
- Requires-Dist: numpy==1.26.4
26
- Requires-Dist: progress==1.6
27
- Requires-Dist: seaborn==0.13.2
28
- Requires-Dist: scipy==1.14.0
29
- Requires-Dist: scikit-learn==1.5.1
30
- Requires-Dist: hyperopt==0.2.7
31
- Requires-Dist: numba==0.60.0
32
- Requires-Dist: shap==0.45.1
33
- Requires-Dist: mapie==0.8.6
34
- Requires-Dist: weasyprint==62.3
35
-
36
- Documentation in Read The Docs: https://robert.readthedocs.io
1
+ Metadata-Version: 2.1
2
+ Name: robert
3
+ Version: 2.0.1
4
+ Summary: Refiner and Optimizer of a Bunch of Existing Regression Tools
5
+ Home-page: https://github.com/jvalegre/robert
6
+ Download-URL: https://github.com/jvalegre/robert/archive/refs/tags/2.0.1.tar.gz
7
+ Author: Juan V. Alegre Requena, David Dalmau
8
+ Author-email: jv.alegre@csic.es
9
+ License: MIT
10
+ Keywords: workflows,machine learning,cheminformatics,data curation,prediction,automated
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Build Tools
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: PyYAML==6.0.2
23
+ Requires-Dist: matplotlib==3.10.0
24
+ Requires-Dist: pandas==2.2.3
25
+ Requires-Dist: numpy==1.26.4
26
+ Requires-Dist: progress==1.6
27
+ Requires-Dist: seaborn==0.13.2
28
+ Requires-Dist: scipy==1.15.0
29
+ Requires-Dist: scikit-learn==1.6.0
30
+ Requires-Dist: bayesian-optimization==3.0.0b1
31
+ Requires-Dist: numba==0.60.0
32
+ Requires-Dist: shap==0.46.0
33
+ Requires-Dist: weasyprint==63.1
34
+ Requires-Dist: PySide6
35
+ Requires-Dist: PyMuPDF
36
+ Requires-Dist: ansi2html
37
+
38
+ Documentation in Read The Docs: https://robert.readthedocs.io
@@ -17,17 +17,20 @@ Don't miss out the latest hands-on tutorials from our [YouTube channel](https://
17
17
  ## Recommended installation
18
18
  1. (Only once) Create new conda environment: `conda create -n robert python=3.10`
19
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`
20
+ 3. Install ROBERT using pip: `pip install robert`
21
+ 4. Install RDKit (only if you plan to use easyROB): `pip install rdkit`
22
+ 5. Install libraries for the PDF report `conda install -y -c conda-forge glib gtk3 pango mscorefonts`
23
+ 6. (Only for compatible devices) Install Intelex accelerator: `pip install scikit-learn-intelex==2025.2.0`
23
24
  * Inexperienced users should visit the *Users with no Python experience* section in [Read the Docs](https://robert.readthedocs.io).
24
25
  ## Update the program
25
- 1. Update to the latest version: `pip install robert --upgrade`
26
+ 1. Update to the latest version: `pip install robert --upgrade`
26
27
 
27
28
  ## Developers and help desk
28
29
  List of main developers and contact emails:
29
30
  - [ ] [Juan V. Alegre-Requena](https://orcid.org/0000-0002-0769-7168). Contact: [jv.alegre@csic.es](mailto:jv.alegre@csic.es)
30
- - [ ] [David Dalmau Ginesta](https://orcid.org/0000-0002-2506-6546). Contact: [ddalmau@unizar.es](mailto:ddalmau@unizar.es)
31
+ - [ ] [David Dalmau Ginesta](https://orcid.org/0000-0002-2506-6546). Contact: [ddalmau@unizar.es](mailto:ddalmau@unizar.es)
32
+ - [ ] [Miguel Martinez Fernandez](https://orcid.org/0009-0002-8538-7250). Contact [miguel.martinez@csic.es](mailto:miguel.martinez@csic.es)
33
+ - [ ] [Luis Giner Tendero](https://github.com/LlGinerT/). Contact [lginertendero@gmail.com](mailto:lginertendero@gmail.com)
31
34
 
32
35
  For suggestions and improvements of the code (greatly appreciated!), please reach out through the issues and pull requests options of Github.
33
36
 
@@ -53,11 +56,12 @@ We really THANK all the testers for their feedback and for participating in the
53
56
 
54
57
  ## How to cite ROBERT
55
58
  If you use any of the ROBERT modules, please include this citation:
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.
59
+ * Dalmau, D.; Alegre Requena, J. V. ROBERT: Bridging the Gap between Machine Learning and Chemistry. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2024**, *14*, e1733.
57
60
 
58
61
  If you use the AQME module, please include this citation:
59
62
  * Alegre-Requena et al., AQME: Automated Quantum Mechanical Environments for Researchers and Educators. *Wiley Interdiscip. Rev. Comput. Mol. Sci.* **2023**, *13*, e1663.
60
63
 
61
- Additionally, please include the corresponding reference for Scikit-learn and SHAP:
64
+ Additionally, please include the corresponding reference for Scikit-learn, SHAP and BayesianOptimization:
62
65
  * 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.
66
+ * Lundberg et al., From local explanations to global understanding with explainable AI for trees. *Nat. Mach. Intell.* **2020**, *2*, 56–67.
67
+ * Fernando Nogueira, {Bayesian Optimization}: Open source constrained global optimization tool for {Python}, **2014**, https://github.com/bayesian-optimization/BayesianOptimization
File without changes
File without changes
@@ -12,9 +12,6 @@ Parameters
12
12
  Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
13
13
  qdescp_keywords : str, default=''
14
14
  Add extra keywords to the AQME-QDESCP run (i.e. qdescp_keywords="--qdescp_atoms ['Ir']")
15
- csearch_keywords : str, default='--sample 50'
16
- Add extra keywords to the AQME-CSEARCH run (i.e. csearch_keywords='--sample 10'). CREST can be
17
- used instead of RDKit by adding "--program crest".
18
15
  descp_lvl : str, default='interpret'
19
16
  Type of descriptor to be used in the AQME-ROBERT workflow. Options are 'interpret', 'denovo' or 'full'.
20
17
 
@@ -98,7 +95,14 @@ class aqme:
98
95
  shutil.move(sdf_file, new_sdf)
99
96
 
100
97
  # Load database
101
- csv_df = load_database(self,csv_target,job_type)
98
+ csv_df,_,_ = load_database(self,csv_target,job_type,print_info=False)
99
+
100
+ # avoid running calcs with special signs (i.e. *)
101
+ for name_csv_indiv in csv_df['code_name']:
102
+ if '*' in f'{name_csv_indiv}':
103
+ self.args.log.write(f"\nx WARNING! The names provided in the CSV contain * (i.e. {name_csv_indiv}). Please, remove all the * characters.")
104
+ self.args.log.finalize()
105
+ sys.exit()
102
106
 
103
107
  # find if there is more than one SMILES column in the CSV file
104
108
  for column in csv_df.columns:
@@ -120,20 +124,8 @@ class aqme:
120
124
  csv_temp.to_csv(f'AQME_indiv_{smi_suffix}.csv', index=False)
121
125
  aqme_indv_name = f'AQME_indiv_{smi_suffix}'
122
126
 
123
- # run the initial AQME-CSEARCH conformational search with RDKit (default) or CREST
124
- if '--program crest' not in self.args.csearch_keywords.lower():
125
- cmd_csearch = ['python', '-m', 'aqme', '--csearch', '--program', 'rdkit', '--input', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}']
126
- else:
127
- self.args.log.write(f"\no CREST detected in the csearch_keywords option, it will be used for conformer sampling")
128
- cmd_csearch = ['python', '-m', 'aqme', '--csearch', '--input', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}']
129
- _ = self.run_aqme(cmd_csearch, self.args.csearch_keywords)
130
-
131
- sdf_files = 'CSEARCH/*.sdf'
132
- if smi_suffix is not None:
133
- sdf_files = f'CSEARCH/*_{smi_suffix}_*.sdf'
134
-
135
- # run QDESCP to generate descriptors
136
- cmd_qdescp = ['python', '-m', 'aqme', '--qdescp', '--files', sdf_files, '--program', 'xtb', '--csv_name', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}', '--robert']
127
+ # run AQME-QDESCP to generate descriptors
128
+ cmd_qdescp = ['python', '-m', 'aqme', '--qdescp', '--input', f'{aqme_indv_name}.csv', '--program', 'xtb', '--csv_name', f'{aqme_indv_name}.csv', '--nprocs', f'{self.args.nprocs}', '--robert']
137
129
  _ = self.run_aqme(cmd_qdescp, self.args.qdescp_keywords)
138
130
 
139
131
  if smi_suffix is not None:
@@ -16,8 +16,7 @@ var_dict = {
16
16
  "report": False,
17
17
  "cheers": False,
18
18
  "evaluate": False,
19
- "seed": [],
20
- "generate_acc": 'mid',
19
+ "seed": 0,
21
20
  "destination": None,
22
21
  "csv_name" : '',
23
22
  "csv_train": '',
@@ -27,29 +26,31 @@ var_dict = {
27
26
  "discard" : [],
28
27
  "ignore" : [],
29
28
  "categorical" : "onehot",
30
- "corr_filter" : True,
29
+ "corr_filter_x" : True,
30
+ "corr_filter_y" : False,
31
+ "std" : True,
31
32
  "desc_thres" : 25,
32
33
  "thres_y" : 0.001,
33
34
  "thres_x" : 0.7,
34
- "test_set" : 0.1,
35
+ "test_set" : 0.2,
35
36
  "auto_test" : True,
36
- "train" : [60,70,80,90],
37
- "auto_kn" : True,
38
37
  "auto_type": True,
39
- "filter_train" : True,
40
- "split" : "RND",
41
38
  "model" : ['RF','GB','NN','MVL'],
42
39
  "eval_model" : 'MVL',
43
40
  "custom_params" : None,
44
41
  "type" : "reg",
45
- "epochs" : 0,
42
+ "split" : "even",
46
43
  "nprocs": 8,
47
44
  "error_type" : "rmse",
48
45
  "pfi_epochs" : 5,
49
- "pfi_threshold" : 0.04,
46
+ "pfi_threshold" : 0.2,
50
47
  "pfi_filter" : True,
51
48
  "pfi_max" : 0,
52
- "kfold" : 'auto',
49
+ "init_points" : 10,
50
+ "n_iter" : 10,
51
+ "expect_improv" : 0.05,
52
+ "kfold" : 5,
53
+ "repeat_kfolds" : 10,
53
54
  "alpha" : 0.05,
54
55
  "params_dir" : '',
55
56
  "csv_test" : '',
@@ -59,7 +60,6 @@ var_dict = {
59
60
  "names" : '',
60
61
  "qdescp_keywords" : '',
61
62
  "descp_lvl": "interpret",
62
- "csearch_keywords": '--sample 10',
63
63
  "report_modules" : ['AQME','CURATE','GENERATE','VERIFY','PREDICT'],
64
64
  "debug_report": False
65
65
  }
@@ -84,5 +84,5 @@ def set_options(kwargs):
84
84
  else:
85
85
  print("Warning! Option: [", key,":",kwargs[key],"] provided but no option exists, try the online documentation to see available options for each module.",)
86
86
  sys.exit()
87
-
87
+
88
88
  return options
@@ -0,0 +1,160 @@
1
+ """
2
+ Parameters
3
+ ----------
4
+
5
+ csv_name : str, default=''
6
+ Name of the CSV file containing the database. A path can be provided (i.e. 'C:/Users/FOLDER/FILE.csv').
7
+ y : str, default=''
8
+ Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
9
+ discard : list, default=[]
10
+ List containing the columns of the input CSV file that will not be included as descriptors
11
+ in the curated CSV file (i.e. ['name','SMILES']).
12
+ ignore : list, default=[]
13
+ List containing the columns of the input CSV file that will be ignored during the curation process
14
+ (i.e. ['name','SMILES']). The descriptors will be included in the curated CSV file. The y value
15
+ is automatically ignored.
16
+ names : str, default=''
17
+ Column of the names for each datapoint. Names are used to print outliers.
18
+ destination : str, default=None,
19
+ Directory to create the output file(s).
20
+ varfile : str, default=None
21
+ Option to parse the variables using a yaml file (specify the filename, i.e. varfile=FILE.yaml).
22
+ categorical : str, default='onehot'
23
+ Mode to convert data from columns with categorical variables. As an example, a variable containing 4
24
+ types of C atoms (i.e. primary, secondary, tertiary, quaternary) will be converted into categorical
25
+ variables. Options:
26
+ 1. 'onehot' (for one-hot encoding, ROBERT will create a descriptor for each type of
27
+ C atom using 0s and 1s to indicate whether the C type is present)
28
+ 2. 'numbers' (to describe the C atoms with numbers: 1, 2, 3, 4).
29
+ corr_filter_x : bool, default=True
30
+ Activate the correlation filters of descriptors, based on the correlation
31
+ of the descriptors with other descriptors (x filter).
32
+ corr_filter_y : bool, default=False
33
+ Activate the correlation filters of descriptors, based on the correlation
34
+ of the descriptors with the y values (y filter, for noise). This filter is only
35
+ suggested for MVL.
36
+ desc_thres : float, default=25
37
+ Threshold for the descriptor-to-datapoints ratio to loose the correlation filter. By default,
38
+ the correlation filter is loosen if there are 25 times more datapoints than descriptors.
39
+ thres_x : float, default=0.7
40
+ Thresolhold to discard descriptors based on high R**2 correlation with other descriptors (i.e.
41
+ if thres_x=0.7, variables that show R**2 > 0.7 will be discarded).
42
+ thres_y : float, default=0.001
43
+ Thresolhold to discard descriptors with poor correlation with the y values based on R**2 (i.e.
44
+ if thres_y=0.001, variables that show R**2 < 0.001 will be discarded).
45
+ seed : int, default=0
46
+ Random seed used in RFECV feature selector and other protocols.
47
+ kfold : int, default=5
48
+ Number of random data splits for the cross-validation of the RFECV feature selector.
49
+ repeat_kfolds : int, default=10
50
+ Number of repetitions for the k-fold cross-validation of the RFECV feature selector.
51
+ auto_type : bool, default=True
52
+ If there are only two y values, the program automatically changes the type of problem to classification.
53
+
54
+
55
+ """
56
+ #####################################################.
57
+ # This file stores the CURATE class #
58
+ # used in data curation #
59
+ #####################################################.
60
+
61
+ import time
62
+ import os
63
+ import pandas as pd
64
+ from robert.utils import (load_variables, finish_print, load_database, pearson_map,
65
+ check_clas_problem, categorical_transform, correlation_filter)
66
+
67
+
68
+ class curate:
69
+ """
70
+ Class containing all the functions from the CURATE module.
71
+
72
+ Parameters
73
+ ----------
74
+ kwargs : argument class
75
+ Specify any arguments from the CURATE module (for a complete list of variables, visit the ROBERT documentation)
76
+ """
77
+
78
+ def __init__(self, **kwargs):
79
+
80
+ start_time = time.time()
81
+
82
+ # load default and user-specified variables
83
+ self.args = load_variables(kwargs, "curate")
84
+
85
+ # load database, discard user-defined descriptors and perform data checks
86
+ csv_df,_,_ = load_database(self,self.args.csv_name,"curate")
87
+
88
+ # adjust options of classification problems and detects whether the right type of problem was used
89
+ self = check_clas_problem(self,csv_df)
90
+
91
+ if not self.args.evaluate:
92
+ # transform categorical descriptors
93
+ csv_df = categorical_transform(self,csv_df,'curate')
94
+
95
+ # apply duplicate filters (i.e., duplication of datapoints or descriptors)
96
+ csv_df = self.dup_filter(csv_df)
97
+
98
+ # apply the correlation filters and returns the database without correlated descriptors
99
+ if self.args.corr_filter_x or self.args.corr_filter_y:
100
+ csv_df = correlation_filter(self,csv_df)
101
+
102
+ # save the curated CSV
103
+ _ = self.save_curate(csv_df)
104
+
105
+ # create Pearson heatmap
106
+ _ = pearson_map(self,csv_df,'curate')
107
+
108
+ # finish the printing of the CURATE info file
109
+ _ = finish_print(self,start_time,'CURATE')
110
+
111
+
112
+ def dup_filter(self,csv_df_dup):
113
+ '''
114
+ Removes duplicated datapoints and descriptors
115
+ '''
116
+
117
+ txt_dup = f'\no Duplication filters activated'
118
+ txt_dup += f'\n Excluded datapoints:'
119
+
120
+ # remove duplicated entries
121
+ datapoint_drop = []
122
+ for i,datapoint in enumerate(csv_df_dup.duplicated()):
123
+ if datapoint:
124
+ datapoint_drop.append(i)
125
+ for datapoint in datapoint_drop:
126
+ txt_dup += f'\n - Datapoint number {datapoint}'
127
+
128
+ if len(datapoint_drop) == 0:
129
+ txt_dup += f'\n - No datapoints were removed'
130
+
131
+ csv_df_dup = csv_df_dup.drop(datapoint_drop, axis=0)
132
+
133
+ csv_df_dup.reset_index(drop=True)
134
+ self.args.log.write(txt_dup)
135
+
136
+ return csv_df_dup
137
+
138
+
139
+ def save_curate(self,csv_df):
140
+ '''
141
+ Saves the curated database and options used in CURATE
142
+ '''
143
+
144
+ # saves curated database
145
+ csv_basename = os.path.basename(f'{self.args.csv_name}').split('.')[0]
146
+ csv_curate_name = f'{csv_basename}_CURATE.csv'
147
+ csv_curate_name = self.args.destination.joinpath(csv_curate_name)
148
+ _ = csv_df.to_csv(f'{csv_curate_name}', index = None, header=True)
149
+ path_reduced = '/'.join(f'{csv_curate_name}'.replace('\\','/').split('/')[-2:])
150
+ self.args.log.write(f'\no The curated database was stored in {path_reduced}.')
151
+
152
+ # saves important options used in CURATE
153
+ options_name = f'CURATE_options.csv'
154
+ options_name = self.args.destination.joinpath(options_name)
155
+ options_df = pd.DataFrame()
156
+ options_df['y'] = [self.args.y]
157
+ options_df['ignore'] = [self.args.ignore]
158
+ options_df['names'] = [self.args.names]
159
+ options_df['csv_name'] = [csv_curate_name]
160
+ _ = options_df.to_csv(f'{options_name}', index = None, header=True)
@@ -22,6 +22,8 @@ GENERAL
22
22
  Type of the pedictions. Options:
23
23
  1. 'reg' (Regressor)
24
24
  2. 'clas' (Classifier)
25
+ seed : int, default=0
26
+ Random seed used in the ML predictor models and other protocols.
25
27
  destination : str, default=None,
26
28
  Directory to create the output file(s).
27
29
 
@@ -58,9 +60,10 @@ Affect PREDICT
58
60
  Affect VERIFY and PREDICT
59
61
  +++++++++++++++++++++++++
60
62
 
61
- kfold : int, default='auto',
62
- Number of folds for the k-fold cross-validation. If 'auto', the program does
63
- a LOOCV for databases with less than 50 points, and 5-fold CV for larger databases
63
+ kfold : int, default=5
64
+ Number of random data splits for the cross-validation of the models.
65
+ repeat_kfolds : int, default=10
66
+ Number of repetitions for the k-fold cross-validation of the models.
64
67
 
65
68
  """
66
69
  #####################################################.
@@ -109,12 +112,12 @@ class evaluate:
109
112
  Load databases, merge them and save CSV (tracking the test types using the Set column)
110
113
  '''
111
114
 
112
- csv_df_train = load_database(self,self.args.csv_train,"evaluate")
115
+ csv_df_train,_,_ = load_database(self,self.args.csv_train,"evaluate",print_info=False)
113
116
  csv_df_train['Set'] = ['Training'] * len(csv_df_train[self.args.y])
114
- csv_df_valid = load_database(self,self.args.csv_valid,"evaluate")
117
+ csv_df_valid,_,_ = load_database(self,self.args.csv_valid,"evaluate",print_info=False)
115
118
  csv_df_valid['Set'] = ['Validation'] * len(csv_df_valid[self.args.y])
116
119
  if self.args.csv_test != '':
117
- csv_df_test = load_database(self,self.args.csv_test,"evaluate")
120
+ csv_df_test,_,_ = load_database(self,self.args.csv_test,"evaluate",print_info=False)
118
121
  csv_df_test['Set'] = ['Test'] * len(csv_df_test[self.args.y])
119
122
 
120
123
  self.args.ignore.append('Set')
@@ -163,12 +166,11 @@ class evaluate:
163
166
  train_points = len(csv_df_train[self.args.y])
164
167
  valid_points = len(csv_df_valid[self.args.y])
165
168
  df_params['train'] = [train_proportion]
166
- df_params['split'] = ['user-defined']
169
+ df_params['kfold'] = [self.args.kfold]
170
+ df_params['repeat_kfolds'] = [self.args.repeat_kfolds]
167
171
  df_params['model'] = [self.args.eval_model]
168
172
  df_params['type'] = [self.args.type]
169
- if self.args.seed == []:
170
- self.args.seed = [0]
171
- df_params['seed'] = [self.args.seed[0]]
173
+ df_params['seed'] = [self.args.seed]
172
174
  df_params['y'] = [self.args.y]
173
175
  df_params['names'] = [self.args.names]
174
176
  df_params['error_type'] = [self.args.error_type]
@@ -0,0 +1,184 @@
1
+ """
2
+ Parameters
3
+ ----------
4
+
5
+ csv_name : str, default=''
6
+ Name of the CSV file containing the database. A path can be provided (i.e. 'C:/Users/FOLDER/FILE.csv').
7
+ y : str, default=''
8
+ Name of the column containing the response variable in the input CSV file (i.e. 'solubility').
9
+ discard : list, default=[]
10
+ List containing the columns of the input CSV file that will not be included as descriptors
11
+ in the curated CSV file (i.e. ['name','SMILES']).
12
+ ignore : list, default=[]
13
+ List containing the columns of the input CSV file that will be ignored during the curation process
14
+ (i.e. ['name','SMILES']). The descriptors will be included in the curated CSV file. The y value
15
+ is automatically ignored.
16
+ destination : str, default=None
17
+ Directory to create the output file(s).
18
+ varfile : str, default=None
19
+ Option to parse the variables using a yaml file (specify the filename, i.e. varfile=FILE.yaml).
20
+ auto_type : bool, default=True
21
+ If there are only two y values, the program automatically changes the type of problem to classification.
22
+ model : list, default=['RF','GB','NN','MVL'] (regression) and default=['RF','GB','NN','AdaB'] (classification)
23
+ ML models available:
24
+ 1. 'RF' (Random forest)
25
+ 2. 'MVL' (Multivariate lineal models)
26
+ 3. 'GB' (Gradient boosting)
27
+ 4. 'NN' (MLP neural network)
28
+ 5. 'GP' (Gaussian Process)
29
+ 6. 'AdaB' (AdaBoost)
30
+ custom_params : str, default=None
31
+ Define new parameters for the ML models used in the hyperoptimization workflow. The path
32
+ to the folder containing all the yaml files should be specified (i.e. custom_params='YAML_FOLDER')
33
+ type : str, default='reg'
34
+ Type of the pedictions. Options:
35
+ 1. 'reg' (Regressor)
36
+ 2. 'clas' (Classifier)
37
+ seed : int, default=0
38
+ Random seed used in the ML predictor models and other protocols.
39
+ error_type : str, default: rmse (regression), mcc (classification)
40
+ Target value used during the hyperopt optimization. Options:
41
+ Regression:
42
+ 1. rmse (root-mean-square error)
43
+ 2. mae (mean absolute error)
44
+ 3. r2 (R-squared, not recommended since R2 might be good even with high errors in small datasets)
45
+ Classification:
46
+ 1. mcc (Matthew's correlation coefficient)
47
+ 2. f1 (F1 score)
48
+ 3. acc (accuracy, fraction of correct predictions)
49
+ init_points : int, default=10
50
+ Number of initial points for Bayesian optimization (exploration)
51
+ n_iter : int, default=10
52
+ Number of iterations for Bayesian optimization (exploitation)
53
+ expect_improv : int, default=0.05
54
+ Expected improvement for Bayesian optimization
55
+ pfi_filter : bool, default=True
56
+ Activate the PFI filter of descriptors.
57
+ pfi_epochs : int, default=5
58
+ Sets the number of times a feature is randomly shuffled during the PFI analysis
59
+ (standard from sklearn webpage: 5).
60
+ pfi_threshold : float, default=0.2
61
+ The PFI filter is X% of the model's score (% adjusted, 0.2 = 20% of the total score during PFI).
62
+ pfi_max : int, default=0
63
+ Number of features to keep after the PFI filter. If pfi_max is 0, all the features that pass the PFI
64
+ filter are used.
65
+ auto_test : bool, default=True
66
+ Raises % of test points to 20% if test_set is lower than that.
67
+ test_set : float, default=0.2
68
+ Amount of datapoints to separate as external test set (0.2 = 20%). These points will not be used during the
69
+ hyperoptimization, and PREDICT will use the points as test set during ROBERT workflows. Select
70
+ --test_set 0 to use only training and validation.
71
+ kfold : int, default=5
72
+ Number of random data splits for the cross-validation of the models.
73
+ repeat_kfolds : int, default=10
74
+ Number of repetitions for the k-fold cross-validation of the models.
75
+ split : str, default='even'
76
+ Specifies how the data is split into training and test sets. Options:
77
+ 1. 'even': splits the data evenly into training and test sets.
78
+ 2. 'RND': randomly splits the data.
79
+ 3. 'stratified': splits the data while preserving the distribution of the target variable.
80
+ 4. 'KN': uses a k-means approach to select representative samples.
81
+ 5. 'EXTRA_Q1': selects the 10% lowest values.
82
+ 6. 'EXTRA_Q5': selects the 10% highest values.
83
+
84
+ """
85
+ #####################################################.
86
+ # This file stores the GENERATE class #
87
+ # used in model generation #
88
+ #####################################################.
89
+
90
+ import time
91
+ from robert.utils import (
92
+ load_variables,
93
+ finish_print,
94
+ load_database,
95
+ check_clas_problem,
96
+ prepare_sets
97
+ )
98
+ from robert.generate_utils import (
99
+ BO_workflow,
100
+ PFI_workflow,
101
+ heatmap_workflow,
102
+ detect_best
103
+ )
104
+
105
+
106
+ class generate:
107
+ """
108
+ Class containing all the functions from the GENERATE module.
109
+
110
+ Parameters
111
+ ----------
112
+ kwargs : argument class
113
+ Specify any arguments from the GENERATE module (for a complete list of variables, visit the ROBERT documentation)
114
+ """
115
+
116
+ def __init__(self, **kwargs):
117
+
118
+ start_time = time.time()
119
+
120
+ # load default and user-specified variables
121
+ self.args = load_variables(kwargs, "generate")
122
+
123
+ # load database, discard user-defined descriptors and perform data checks
124
+ csv_df, _, _ = load_database(self,self.args.csv_name,"generate")
125
+
126
+ # changes type to classification if there are only two different y values
127
+ if self.args.type.lower() == 'reg' and self.args.auto_type:
128
+ self = check_clas_problem(self,csv_df)
129
+
130
+ # scan different ML models
131
+ txt_heatmap = f"\no Starting heatmap scan with {len(self.args.model)} ML models ({self.args.model})."
132
+
133
+ # scan different training partition sizes
134
+ cycle = 1
135
+ txt_heatmap += f'\n Heatmap generation:'
136
+ self.args.log.write(txt_heatmap)
137
+
138
+ # scan different ML models
139
+ self.args.log.write(f''' o Starting BO-based hyperoptimization using the combined target:
140
+ \n 1. 50% = {self.args.error_type.upper()} from a {self.args.repeat_kfolds}x repeated {self.args.kfold}-fold CV (interpoplation)
141
+ \n 2. 50% = {self.args.error_type.upper()} from the bottom or top (worst performing) fold in a sorted {self.args.kfold}-fold CV (extrapolation)
142
+ \n''')
143
+
144
+ for ML_model in self.args.model:
145
+
146
+ self.args.log.write(f' - {cycle}/{len(self.args.model)} - ML model: {ML_model} ')
147
+
148
+ # load database, discard user-defined descriptors and perform data checks
149
+ csv_df, csv_X, csv_y = load_database(self,self.args.csv_name,"generate",print_info=False)
150
+
151
+ # standardizes and separates an external test set
152
+ Xy_data = prepare_sets(self,csv_df,csv_X,csv_y,None,self.args.names,None,None,None,BO_opt=True)
153
+
154
+ # hyperopt process for ML models
155
+ _ = BO_workflow(self, Xy_data, csv_df, ML_model)
156
+
157
+ # apply the PFI descriptor filter if it's activated
158
+ if self.args.pfi_filter:
159
+ # load database, discard user-defined descriptors and perform data checks
160
+ csv_df, csv_X, csv_y = load_database(self,self.args.csv_name,"generate",print_info=False)
161
+
162
+ # standardizes and separates an external test set
163
+ Xy_data = prepare_sets(self,csv_df,csv_X,csv_y,None,self.args.names,None,None,None,BO_opt=True)
164
+
165
+ _ = PFI_workflow(self, csv_df, ML_model, Xy_data)
166
+
167
+ cycle += 1
168
+
169
+ # detects best combinations
170
+ dir_csv = self.args.destination.joinpath(f"Raw_data")
171
+ _ = detect_best(f'{dir_csv}/No_PFI')
172
+
173
+ # create heatmap plot(s)
174
+ _ = heatmap_workflow(self,"No_PFI")
175
+
176
+ # detect best and create heatmap for PFI models
177
+ if self.args.pfi_filter:
178
+ try: # if no models were found
179
+ _ = detect_best(f'{dir_csv}/PFI')
180
+ _ = heatmap_workflow(self,"PFI")
181
+ except UnboundLocalError:
182
+ pass
183
+
184
+ _ = finish_print(self,start_time,'GENERATE')