diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cdfcf30ba53ea9841566f0b198075f4baf8baa15..a96994623980ccc49e66e8d1d8ed4208a8d32d31 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,8 @@ tests: script: - export LC_ALL=$(locale -a | grep en_US) - export LANG=$(locale -a | grep en_US) + - pip3 install --upgrade pip + - pip3 -V - pip3 install -e . - pytest-3 coverage: '/^TOTAL.+?(\d+\%)$/' @@ -24,6 +26,7 @@ doc: script: - export LC_ALL=$(locale -a | grep en_US) - export LANG=$(locale -a | grep en_US) + - pip3 install --upgrade pip - pip3 install -e .[doc] - sphinx-apidoc -o docs/source summit - cd docs/source @@ -45,6 +48,7 @@ pages: script: - export LC_ALL=$(locale -a | grep en_US) - export LANG=$(locale -a | grep en_US) + - pip3 install --upgrade pip - pip3 install -e .[doc] - pytest-3 - sphinx-apidoc -o docs/source summit diff --git a/README.rst b/README.rst index cd6a3590e048de01a9e3ba8000789338c0d1f4bb..1330ac06499b253acc31feb8659317f24e2888c2 100644 --- a/README.rst +++ b/README.rst @@ -57,7 +57,9 @@ And the following python modules will be automatically installed : * `pyyaml <https://pypi.org/project/PyYAML/>`_ - Used to read the config files, * `plotly <https://plot.ly/>`_ - Used to generate interactive HTML visuals, * `tabulate <https://pypi.org/project/tabulate/>`_ - Used to generated the confusion matrix. -* `pyscm-ml <https://pypi.org/project/pyscm-ml/>`_ - +* `pyscm-ml <https://pypi.org/project/pyscm-ml/>`_ - SCM python implementation +* `randomscm <https://github.com/thibgo/randomscm>`_ - Random SCM python implementation +* `imbalance-bagging <https://imbalanced-learn.org/stable>`_ - Imbalanced learning library Installing diff --git a/requirements.txt b/requirements.txt index ed308353300ddc13fc59db4ded504ec9d26ea2a4..058b876c7f2ffae6f597006f4d7333a6f4b43f53 100755 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,6 @@ pyyaml>=3.12 plotly>=4.2.1 matplotlib>=3.1.1 tabulate>=0.8.6 -pyscm-ml>=1.0.0 \ No newline at end of file +pyscm-ml>=1.0.0 +git+https://github.com/thibgo/randomscm/archive/refs/tags/v0.0.0-alpha.zip + diff --git a/setup.py b/setup.py index 8f774ddfe5cfdbf51e69dd924a69ea1453dfba24..0d2563131253f2939de2db758ee2903ea7ce18ef 100644 --- a/setup.py +++ b/setup.py @@ -1,73 +1,36 @@ # -*- coding: utf-8 -*- #Extracting requrements from requirements.txt -with open('requirements.txt') as f: - requirements = f.read().splitlines() +# with open('requirements.txt') as f: +# requirements = f.read().splitlines() # from Cython.Build import cythonize from setuptools import setup, find_packages -# Ceci n'est qu'un appel de fonction. Mais il est trèèèèèèèèèèès long -# et il comporte beaucoup de paramètres def setup_package(): setup( - # le nom de votre bibliothèque, tel qu'il apparaitre sur pypi name='summit', - - # la version du code version=0.0, python_requires = '>=3.5', - # Liste les packages à insérer dans la distribution - # plutôt que de le faire à la main, on utilise la foncton - # find_packages() de setuptools qui va cherche tous les packages - # python recursivement dans le dossier courant. - # C'est pour cette raison que l'on a tout mis dans un seul dossier: - # on peut ainsi utiliser cette fonction facilement packages=find_packages(), - - # votre pti nom author="Baptiste Bauvin", - - # Votre email, sachant qu'il sera publique visible, avec tous les risques - # que ça implique. author_email="baptiste.bauvin@lis-lab.fr", - - # Une description courte description="Supervised MultiModal Integration Tool", - - # Une description longue, sera affichée pour présenter la lib - # Généralement on dump le README ici long_description=open('README.rst').read(), - - # Vous pouvez rajouter une liste de dépendances pour votre lib - # et même préciser une version. A l'installation, Python essayera de - # les télécharger et les installer. - # - # Ex: ["gunicorn", "docutils >= 0.3", "lxml==0.5a7"] - # - # Dans notre cas on en a pas besoin, donc je le commente, mais je le - # laisse pour que vous sachiez que ça existe car c'est très utile. - # install_requires= , - - # Active la prise en compte du fichier MANIFEST.in include_package_data=True, - # dependency_links=['https://github.com/aldro61/pyscm.git#egg=pyscm'], - # Une url qui pointe vers la page officielle de votre lib url='http://gitlab.lis-lab.fr/baptiste.bauvin/summit/', - install_requires=requirements, + install_requires=['h5py>=2.9.0', 'joblib>=0.13.2', 'numpy>=1.16.4', + 'pyparsing>=2.4.0', 'python-dateutil>=2.8.0', + 'scikit-learn>=0.19.0', 'scipy>=1.3.0', 'six>=1.12.0', + 'pandas>=0.23.3', 'pyyaml>=3.12', 'plotly>=4.2.1', + 'matplotlib>=3.1.1', 'tabulate>=0.8.6', 'pyscm-ml>=1.0.0', + "randomscm @ git+https://github.com/thibgo/randomscm.git#egg=randomscm", + "imbalanced-learn"], extras_require={ 'dev': ['pytest', 'pytest-cov'], 'doc': ['sphinx >= 3.0.2', 'numpydoc', 'docutils', 'sphinx-autoapi', 'sphinx_rtd_theme']}, - - # Il est d'usage de mettre quelques metadata à propos de sa lib - # Pour que les robots puissent facilement la classer. - # La liste des marqueurs autorisées est longue: - # https://pypi.python.org/pypi?%3Aaction=list_classifiers. - # - # Il n'y a pas vraiment de règle pour le contenu. Chacun fait un peu - # comme il le sent. Il y en a qui ne mettent rien. classifiers=[ "Programming Language :: Python", "Development Status :: 1 - Planning", @@ -77,28 +40,8 @@ def setup_package(): "Programming Language :: Python :: 2/3", "Topic :: Machine Learning", ], - - # C'est un système de plugin, mais on s'en sert presque exclusivement - # Pour créer des commandes, comme "django-admin". - # Par exemple, si on veut créer la fabuleuse commande "proclame-sm", on - # va faire pointer ce nom vers la fonction proclamer(). La commande sera - # créé automatiquement. - # La syntaxe est "nom-de-commande-a-creer = package.module:fonction". - # entry_points={ - # 'console_scripts': [ - # 'exec_multiview = summit.execute:exec', - # ], - # }, - - # A fournir uniquement si votre licence n'est pas listée dans "classifiers" - # ce qui est notre cas license="GNUGPL", - - # Il y a encore une chiée de paramètres possibles, mais avec ça vous - # couvrez 90% des besoins - # ext_modules=cythonize( - # "summit/multiview_platform/monoview/additions/_custom_criterion.pyx"), ) if __name__ == "__main__": diff --git a/summit/multiview_platform/utils/dataset.py b/summit/multiview_platform/utils/dataset.py index 2a33b34bac58766b39049efa68614ddde26b9522..151759765792fe5920a7289eed5207ce5aa74aef 100644 --- a/summit/multiview_platform/utils/dataset.py +++ b/summit/multiview_platform/utils/dataset.py @@ -14,7 +14,7 @@ from .organization import secure_file_path of SuMMIT''' -class Dataset(): +class Dataset: """ This is the base class for all the type of multiview datasets of SuMMIT. """ @@ -165,11 +165,9 @@ class Dataset(): return selected_label_names - def gen_feat_id(self): - self.feature_ids = [["ID_" + str(i) for i in + def gen_feat_id(self, view_ind): + self.feature_ids[view_ind] = ["ID_" + str(i) for i in range(self.get_v(view_ind).shape[1])] - for view_ind in self.view_dict.values()] - class RAMDataset(Dataset): @@ -193,13 +191,14 @@ class RAMDataset(Dataset): self.name = name self.nb_view = len(self.views) self.is_temp = False - if feature_ids is not None: - feature_ids = [[feature_id if not is_just_number(feature_id) - else "ID_" + feature_id for feature_id in - feat_ids] for feat_ids in feature_ids] - self.feature_ids = feature_ids - else: - self.gen_feat_id() + self.feature_ids = [_ for _ in range(self.nb_view)] + for view_ind in range(self.nb_view): + if feature_ids is not None: + self.feature_ids[view_ind] = [feature_id if not is_just_number(feature_id) + else "ID_" + feature_id for feature_id in + feature_ids[view_ind]] + else: + self.gen_feat_id(view_ind) def get_view_name(self, view_idx): return self.view_names[view_idx] @@ -377,14 +376,15 @@ class HDF5Dataset(Dataset): else: self.sample_ids = ["ID_" + str(i) for i in range(labels.shape[0])] - if feature_ids is not None: - feature_ids = [[feature_id if not is_just_number(feature_id) - else "ID_" + feature_id for feature_id in - feat_ids] for feat_ids in feature_ids] - self.feature_ids = feature_ids - else: - self.gen_feat_id() - + self.feature_ids = [_ for _ in range(self.nb_view)] + for view_index in range(self.nb_view): + if feature_ids is not None: + feat_ids = [feature_id if not is_just_number(feature_id) + else "ID_" + feature_id for feature_id in + feature_ids[view_index]] + self.feature_ids = feat_ids + else: + self.gen_feat_id(view_index) def get_v(self, view_index, sample_indices=None): """ Extract the view and returns a numpy.ndarray containing the description @@ -443,6 +443,7 @@ class HDF5Dataset(Dataset): """ self.nb_view = self.dataset["Metadata"].attrs["nbView"] + self.feature_ids = [_ for _ in range(self.nb_view)] self.view_dict = self.get_view_dict() self.view_names = [self.dataset["View{}".format(ind)].attrs['name'] for ind in range(self.nb_view)] if "sample_ids" in self.dataset["Metadata"].keys(): @@ -454,14 +455,14 @@ class HDF5Dataset(Dataset): else: self.sample_ids = ["ID_" + str(i) for i in range(self.dataset["Labels"].shape[0])] - if "feature_ids" in self.dataset["Metadata"].keys(): - self.feature_ids = [[feature_id.decode() - if not is_just_number(feature_id.decode()) - else "ID_" + feature_id.decode() - for feature_id in feature_ids] for feature_ids in - self.dataset["Metadata"]["feature_ids"]] - else: - self.gen_feat_id() + for view_index in range(self.nb_view): + if "feature_ids-View{}".format(view_index) in self.dataset["Metadata"].keys(): + self.feature_ids[view_index] = [feature_id.decode() + if not is_just_number(feature_id.decode()) + else "ID_" + feature_id.decode() + for feature_id in self.dataset["Metadata"]["feature_ids-View{}".format(view_index)]] + else: + self.gen_feat_id(view_index) def get_nb_samples(self): """ diff --git a/summit/tests/test_multi_view/test_multiview_utils.py b/summit/tests/test_multi_view/test_multiview_utils.py index 99d725253c7a0341719913856259c00d65fba3a9..3fca7672456e440a7cf6739f13841135177af68e 100644 --- a/summit/tests/test_multi_view/test_multiview_utils.py +++ b/summit/tests/test_multi_view/test_multiview_utils.py @@ -76,9 +76,11 @@ class TestFunctions(unittest.TestCase): self.assertEqual(avail, ['adaboost', 'decision_tree', 'gradient_boosting', + 'imbalance_bagging', 'knn', 'lasso', 'random_forest', + "random_scm", 'scm', 'sgd', 'svm_linear', @@ -89,8 +91,10 @@ class TestFunctions(unittest.TestCase): self.assertEqual(avail, ['adaboost', 'decision_tree', 'gradient_boosting', + 'imbalance_bagging', 'knn', 'random_forest', + "random_scm", 'scm', 'svm_linear', 'svm_poly',