From 9829bc59b4a0e7a73eda3238d58e66051b02f8d1 Mon Sep 17 00:00:00 2001 From: Dominique Benielli <dominique.benielli@lis-lab.fr> Date: Wed, 25 Mar 2020 19:06:24 +0100 Subject: [PATCH] copyright + bug fix compute alpha --- VERSION | 2 + copyright.py | 2 +- copyrightstamp.txt | 2 +- examples/usecase/plot_usecase_exampleMKL.py | 2 - license.txt | 2 +- multimodal/__init__.py | 2 +- multimodal/boosting/cumbo.py | 14 +-- multimodal/boosting/mumbo.py | 11 ++- multimodal/kernels/mvml.py | 2 +- multimodal/tests/data/digit.py | 62 ++++++++++++ multimodal/tests/data/digit_y.npy | Bin 14504 -> 0 bytes setup.py | 104 +++++++++++++++++++- 12 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 VERSION create mode 100644 multimodal/tests/data/digit.py delete mode 100644 multimodal/tests/data/digit_y.npy diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..1578b44 --- /dev/null +++ b/VERSION @@ -0,0 +1,2 @@ +multimodal:0.0.dev0 + diff --git a/copyright.py b/copyright.py index dcf2f20..76c97d1 100644 --- a/copyright.py +++ b/copyright.py @@ -50,7 +50,7 @@ def getStamp(date, iw_version): """ Return the corrected formated stamp """ stamp = open("copyrightstamp.txt").read() stamp = stamp.replace("DATE", date) - stamp = stamp.replace("IW_VERSION", iw_version) + stamp = stamp.replace("MULTIMODAL_VERSION", multimodal_version) stamp = stamp.replace('\n', '\n# ') stamp = "# " + stamp stamp = stamp.replace("# \n", "#\n") diff --git a/copyrightstamp.txt b/copyrightstamp.txt index 64f2083..b3d76ec 100644 --- a/copyrightstamp.txt +++ b/copyrightstamp.txt @@ -34,7 +34,7 @@ Version: Licence: ------- -License: LGPLv3+ +License: New BSD License ######### COPYRIGHT ######### diff --git a/examples/usecase/plot_usecase_exampleMKL.py b/examples/usecase/plot_usecase_exampleMKL.py index 27d6fbf..600c566 100644 --- a/examples/usecase/plot_usecase_exampleMKL.py +++ b/examples/usecase/plot_usecase_exampleMKL.py @@ -19,7 +19,6 @@ from sklearn.tree import DecisionTreeClassifier from multimodal.datasets.base import load_dict, save_dict from multimodal.tests.data.get_dataset_path import get_dataset_path from multimodal.datasets.data_sample import MultiModalArray -from multimodal.kernels.mvml import MVML from multimodal.kernels.lpMKL import MKL import numpy as np @@ -50,7 +49,6 @@ if __name__ == '__main__': # file = get_dataset_path("digit_histogram.npy") file = get_dataset_path("digit_col_grad.npy") y = np.load(get_dataset_path("digit_y.npy")) - base_estimator = DecisionTreeClassifier(max_depth=4) dic_digit = load_dict(file) XX =MultiModalArray(dic_digit) X_train, X_test, y_train, y_test = train_test_split(XX, y) diff --git a/license.txt b/license.txt index 1011e46..54ead26 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ New BSD License -Copyright (c) 2020-15-01, The scit-multimodallearn developers. +Copyright (c) 2020-15-01, The scikit-multimodallearn developers. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/multimodal/__init__.py b/multimodal/__init__.py index 1ff9679..e851e58 100644 --- a/multimodal/__init__.py +++ b/multimodal/__init__.py @@ -1 +1 @@ -__version__ = '0.0.dev0' +__version__ = "0.0.dev0" diff --git a/multimodal/boosting/cumbo.py b/multimodal/boosting/cumbo.py index 158c9ca..175a9cf 100644 --- a/multimodal/boosting/cumbo.py +++ b/multimodal/boosting/cumbo.py @@ -311,16 +311,16 @@ class MuCumboClassifier(BaseEnsemble, ClassifierMixin, UBoosting): zeta2 = zeta**2 def F(x=None, z=None): if x is None: - # l'algorithme fonctionne de manière itérative - # il faut choisir un x initial, c'est ce qu'on fait ici + # iteratif algo + # choice x initial return 0, matrix(1.0, (n_view*m, 1)) if min(x) < 0.0: - return None # cas impossible - # ici commence le code qui définit ce qu'est une itération - f = sum(matrix(coef * exp( matrix(zeta * x.T)) )) - Df = matrix(np.sum( zeta * coef * exp(matrix( zeta * x.T ) ), axis=0 )).T # -(x**-1).T + return None # impossible + # begin iteration + f = sum(matrix(coef * exp( matrix(zeta * x.T)))) + Df = matrix(np.sum( zeta * coef * exp(matrix( zeta * x.T)), axis=0)).T # -(x**-1).T if z is None: return f, Df - H = spdiag(z[0] * matrix(np.sum(coef * zeta2 * exp( matrix(zeta* x.T) ), axis= 0))) ## beta**(-2)) + H = spdiag(z[0] * matrix(np.sum(coef * zeta2 * exp( matrix(zeta* x.T)), axis=0))) # beta**(-2)) return f, Df, H try: solver = solvers.cp(F, A=A, b=b, G=G, h=h, dim={'l':2*n_view*m})['x'] diff --git a/multimodal/boosting/mumbo.py b/multimodal/boosting/mumbo.py index 23dacff..29cfe52 100644 --- a/multimodal/boosting/mumbo.py +++ b/multimodal/boosting/mumbo.py @@ -221,12 +221,19 @@ class MumboClassifier(BaseEnsemble, ClassifierMixin, UBoosting): def _compute_alphas(self, edges): """Compute values of confidence rate alpha given edge values.""" + dim = edges.shape[0] np.where(edges > 1.0, edges, 1.0) alphas = 0.5 * np.log((1. + edges) / (1. - edges)) if np.any(np.isinf(alphas)): - alphas[np.where(np.isinf(alphas))[0]] = 1.0 + if isinstance(alphas, float): + alphas = 1.0 + else: + alphas[np.where(np.isinf(alphas))[0]] = 1.0 if np.any(np.isnan(alphas)): - alphas[np.where(np.isnan(alphas))[0]] = 1.0 + if isinstance(alphas, float): + alphas = 1.0 + else: + alphas[np.where(np.isnan(alphas))[0]] = 1.0 return alphas def _compute_cost_global(self, label_score_global, best_predicted_classes, diff --git a/multimodal/kernels/mvml.py b/multimodal/kernels/mvml.py index d2ce3e9..3365f2c 100644 --- a/multimodal/kernels/mvml.py +++ b/multimodal/kernels/mvml.py @@ -613,7 +613,7 @@ class MVML(MKernel, BaseEstimator, ClassifierMixin, RegressorMixin): return A_new - def score(self, X, y=None): + def score(self, X, y): """Return the mean accuracy on the given test data and labels. Parameters diff --git a/multimodal/tests/data/digit.py b/multimodal/tests/data/digit.py new file mode 100644 index 0000000..00f69a3 --- /dev/null +++ b/multimodal/tests/data/digit.py @@ -0,0 +1,62 @@ +from sklearn import datasets +import numpy as np +import PIL +import matplotlib.pyplot as plt +import os +import matplotlib.pyplot as plt +from multimodal.datasets.base import load_dict, save_dict +from multimodal.tests.data.get_dataset_path import get_dataset_path +from multimodal.datasets.data_sample import MultiModalArray +from multimodal.kernels.mvml import MVML +#Load the digits dataset +digits = datasets.load_digits() + +#Display the first digit +plt.figure(1, figsize=(3, 3)) +plt.imshow(digits.images[-1], cmap=plt.cm.gray_r, interpolation='nearest') +plt.show() +colors = digits.data +gradiant = np.gradient(digits.images, axis=[1,2]) +print(gradiant[0].shape) +gradiant0 = gradiant[0].reshape(colors.shape[0], colors.shape[1]) +gradiant1 = gradiant[1].reshape(colors.shape[0], colors.shape[1]) +for ind in range(digits.images.shape[0]): + ima0 = digits.images[ind, :,:] + ima1 = gradiant[0][ind, :,:] + ima2 = gradiant[1][ind, :,:] + ama_pil0 = PIL.Image.fromarray(ima0, mode=None) + ama_pil1 = PIL.Image.fromarray(ima1, mode=None) + ama_pil2 = PIL.Image.fromarray(ima2, mode=None) + histo_color = np.asarray(ama_pil0.histogram()) + histo_gradiant0 = np.asarray(ama_pil1.histogram()) + histo_gradiant1 = np.asarray(ama_pil2.histogram()) + if ind==0: + list_histogram_color = histo_color + list_histogram_gradiant0 = histo_gradiant0 + list_histogram_gradiant1 = histo_gradiant1 + else: + list_histogram_color = np.vstack((list_histogram_color, histo_color)) + list_histogram_gradiant0 = np.vstack((list_histogram_gradiant0, histo_gradiant0)) + list_histogram_gradiant1 = np.vstack((list_histogram_gradiant1, histo_gradiant1)) + +dict_digit = {0: list_histogram_color, 1: list_histogram_gradiant0, 2: list_histogram_gradiant1} + + +print(list_histogram_color.shape) +print(list_histogram_gradiant0.shape) +print(list_histogram_gradiant1.shape) +file = get_dataset_path("digit_histogram.npy") +save_dict(dict_digit, file) + +d2 = load_dict(file) + +figure = plt.figure(figsize=(27, 9)) +ax = plt.subplot(2,1,1) + +ax.scatter(list_histogram_color[:,3], list_histogram_color[:,4], c=digits.target, edgecolors='k') +ax = plt.subplot(2,1,2) +ax.scatter(list_histogram_color[:,0], list_histogram_color[:,1], c=digits.target, edgecolors='k') +plt.show() + +mvml = MVML(lmbda=0.1, eta=1, nystrom_param=0.2) +mvml.fit(d2, digits.target) diff --git a/multimodal/tests/data/digit_y.npy b/multimodal/tests/data/digit_y.npy deleted file mode 100644 index b5588884574d1c89a5d34ece3993af4b532b7191..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14504 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 HaTp%}0<=3U diff --git a/setup.py b/setup.py index 5ec883a..4819398 100644 --- a/setup.py +++ b/setup.py @@ -1,15 +1,111 @@ -import os +import os, re +import shutil from setuptools import setup, find_packages - +from distutils.command.clean import clean as _clean +from distutils.dir_util import remove_tree +from distutils.command.sdist import sdist import multimodal +try: + import numpy +except: + raise 'Cannot build iw without numpy' + sys.exit() + +# -------------------------------------------------------------------- +# Clean target redefinition - force clean everything supprimer de la liste '^core\.*$', +relist = ['^.*~$', '^#.*#$', '^.*\.aux$', '^.*\.pyc$', '^.*\.o$'] +reclean = [] +USE_COPYRIGHT = True +try: + from copyright import writeStamp, eraseStamp +except ImportError: + USE_COPYRIGHT = False + +################### +# Get Multimodal version +#################### +def get_version(): + v_text = open('VERSION').read().strip() + v_text_formted = '{"' + v_text.replace('\n', '","').replace(':', '":"') + v_text_formted += '"}' + v_dict = eval(v_text_formted) + return v_dict["multimodal"] + +######################## +# Set Multimodal __version__ +######################## +def set_version(multimodal_dir, version): + filename = os.path.join(multimodal_dir, '__init__.py') + buf = "" + for line in open(filename, "rb"): + if not line.decode("utf8").startswith("__version__ ="): + buf += line.decode("utf8") + f = open(filename, "wb") + f.write(buf.encode("utf8")) + f.write(('__version__ = "%s"\n' % version).encode("utf8")) + +for restring in relist: + reclean.append(re.compile(restring)) + + +def wselect(args, dirname, names): + for n in names: + for rev in reclean: + if (rev.match(n)): + os.remove("%s/%s" %(dirname, n)) + break + + +###################### +# Custom clean command +###################### +class clean(_clean): + def walkAndClean(self): + os.walk("..", wselect, []) + pass + + def run(self): + clean.run(self) + if os.path.exists('build'): + shutil.rmtree('build') + for dirpath, dirnames, filenames in os.walk('iw'): + for filename in filenames: + if (filename.endswith('.so') or + filename.endswith('.pyd') or + filename.endswith('.dll') or + filename.endswith('.pyc')): + os.unlink(os.path.join(dirpath, filename)) + for dirname in dirnames: + if dirname == '__pycache__': + shutil.rmtree(os.path.join(dirpath, dirname)) + + +############################## +# Custom sdist command +############################## +class m_sdist(sdist): + """ Build source package + + WARNING : The stamping must be done on an default utf8 machine ! + """ + + def run(self): + if USE_COPYRIGHT: + writeStamp() + sdist.run(self) + # eraseStamp() + else: + sdist.run(self) def setup_package(): """Setup function""" name = 'scikit-multimodallearn' - version = multimodal.__version__ + version = get_version() + multimodal_dir = 'multimodal' + set_version(multimodal_dir, version) description = 'A scikit-learn compatible package for multimodal Classifiers' here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'README.rst'), encoding='utf-8') as readme: @@ -21,7 +117,7 @@ def setup_package(): 'Source': url, 'Tracker': '{}/issues'.format(url)} author = 'Dominique Benielli and Sokol Koço and Florent Jaillet and Riikka Huusari ' \ - 'and Cécile Capponi and Hachem Kadri' + 'and Baptiste Bauvin and Cécile Capponi and Hachem Kadri' author_email = 'contact.dev@lis-lab.fr' license = 'newBSD' classifiers = [ -- GitLab