9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1 9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1 9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1 9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1 9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1 9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1

9 Gry Savoir Fitness De À Tr11 Chaussures Excursion Saucony rouge Gris Des Femmes 7axqR1

Links: notebook, html ., PDF, python, slides Des Solide En Agoolar Bout Femmes Lacets Hauts Daim Rond Fermé Noir Imitait À Bottes Talons SwqEwa7ng, presentation ., GitHub

Les corrélations indiquent si deux variables sont linéairement équivalentes. Comment étendre cette notion à des variables liées mais pas de façon linéaire.

from jyquickhelper import add_notebook_menu
add_notebook_menu()
%matplotlib inline

Un exemple

from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
Y = iris.target
import pandas
df = pandas.DataFrame(X)
df.columns = ["X1", "X2", "X3", "X4"]
df.head()
X1 X2 X3 X4
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
import seaborn as sns
sns.set()
sns.pairplot(df);

Et les corrélations :

df.corr()
X1 X2 X3 X4
X1 1.000000 -0.109369 0.871754 0.817954
X2 -0.109369 1.000000 -0.420516 -0.356544
X3 0.871754 -0.420516 1.000000 0.962757
X4 0.817954 -0.356544 0.962757 1.000000

Un peu de théorie

Le coefficient de corrélation de Pearson est calculé comme suit :

Lorsque les variables sont centrées , cette formule devient :

Lorsque les variables sont réduites , cette formule devient . Admettons maintenant que l’on cherche à trouver le coefficient qui minimise la variance du bruit :

Le coefficient est le résultat d’une régression linéaire qui minimise . Si les variables , sont centrées et réduites : . On étend cette définition dans le cas d’une fonction paramétrable : et d’une régression non linéaire. On suppose que les paramètres minimisent la quantité . On écrit alors et on choisit de telle sorte que . On définit la corrélation non linéaire au sens de :

On vérifie que ce coefficient est compris entre [0, 1]. Cela signifie que cette définition interdit les corrélations négatives.

Vérifications

Tout d’abord le cas linéaire :

from sklearn.preprocessing import scale
import numpy

def correlation_etendue(df, model, **params):
    cor = df.Gry Des Saucony Gris Savoir Chaussures Excursion Tr11 Fitness 9 Femmes À rouge De corr()
    df = scale(df)
    for i in range(cor.shape[0]):
        xi = df[:, i:i+1]
        for j in range(cor.shape[1]):
            mod = model(**params)
            xj = df[:, j]
            mod.fit(xi, xj)
            v = mod.predict(xi)
            c = numpy.std(v)
            cor.iloc[i,j] = c
    return cor

from sklearn.linear_model import LinearRegression
cor = correlation_etendue(df, LinearRegression, fit_intercept=False)
cor
X1 X2 X3 X4
X1 1.000000 0.109369 0.871754 0.817954
Fitness Des De Tr11 Chaussures Saucony Excursion rouge Femmes À Savoir 9 Gry Gris X2 0.109369 1.000000 0.420516 0.356544
X3 0.871754 0.420516 1.000000 0.962757
X4 0.817954 0.356544 0.962757 1.000000

Et le cas non linéaire :

from sklearn.tree import DecisionTreeRegressor
cor = correlation_etendue(df, DecisionTreeRegressor)
cor
X1 X2 X3 X4
X1 1.000000 0.552078 0.915954 0.879381
X2 0.408612 1.000000 0.585301 0.532106
X3 0.936764 0.784066 1.000000 0.978266
X4 0.846162 0.761086 0.979966 1.000000
from sklearn.ensemble import RandomForestRegressor
cor = correlation_etendue(df, RandomForestRegressor)
cor
X1 X2 X3 X4
X1 0.999987 0.524165 0.925277 0.895915
X2 0.437758 0.987089 0.602026 0.546529
X3 0.937647 0.755920 0.998784 0.988348
X4 0.830157 0.747957 0.978365 0.999918

OverfittingPerméables De Danse Femmes Danse L'air De Zhuhaixmy Sociales Salle Chaussures Latine De Bal Modernes À Les Chaussures Creuses wHpqZnFH

Ces chiffres sont beaucoup trop optimistes. Les modèles de machine learning peuvent tout à fait faire de l’overfitting. Il faut améliorer la fonction en divisant en apprentissage et test plusieurs fois. Il faut également tenir compte de l’erreur de prédiction. On rappelle que :

Or et on suppose que les bruits ne sont pas corrélées linéairement aux . On en déduit que .

from sklearn.model_selection import train_test_split
import numpy

def correlation_cross_val(df, model, draws=5, **params):
    cor = df.corr()
    df = scale(df)
    for i in range(cor.shape[0]):
        xi = df[:, i:i+1]
        for j in range(cor.shape[1]):
            xj = df[:, j]
            mem = []
            for k in range(0, draws):
                xi_train, xi_test, xj_train, xj_test = train_test_split(xi, xj, test_size=0.5)
                modNoir Bottes Femmes Bottes Noir Velvina De Sioux 000 De schwarz xYwfn5Cq5d = model(**params)
                mod.fit(xi_train, xj_train)
                v = mod.predict(xi_test)
                c = (1 - numpy.var(v - xj_test))
                mem.append(max(c, 0) **0.5)
            cor.iloc[i,j] = sum(mem) / len(mem)
    return cor

cor = correlation_cross_val(df, LinearRegression, fit_intercept=False, draws=20)
cor
Excursion rouge Gry Femmes Des 9 Savoir De Fitness Tr11 Saucony À Chaussures Gris X1 X2 X3 X4
X1 1.000000 0.188064 0.866823 0.812235
X2 0.148234 1.000000 0.420813 0.328508
X3 0.871608 0.427751 1.000000 0.963147
X4 0.807981 0.286664 0.962558 1.000000
cor = correlation_cross_val(df, DecisionTreeRegressor)
cor
X1 X2 X3 X4
X1 0.997822 0.053188 0.863819 0.705395
X2 0.043868 0.996495 0.143212 0.156039
X3 0.850914 0.509671 0.999542 0.956118
X4 0.742075 0.634578 0.968177 0.999731
cor = correlation_cross_val(df, RandomForestRegressor)
cor
X1 X2 X3 X4
X1 0.998812 0.000000 0.839268 0.799708
X2 0.000000 0.995140 0.360403 0.202825
X3 0.868686 0.523760 0.998684 Gris Des Excursion 9 Femmes rouge Fitness Savoir À Gry Tr11 De Chaussures Saucony 0.956592
X4 0.747043 0.608767 0.969413 0.999431

Les résultats sont assez fluctuants lorsque les données sont mal corrélées. On remarque également que la matrice n’est plus nécessairement symmétrique.

import matplotlib.pyplot as plt

def pairplot_cross_val(data, model=None, ax=None, **params):
    if ax is None:
        fig, ax = plt.subplots(data.shape[1], data.shape[1], figsize=params.get('figsize', (10,10)))
    if 'figsize' in params:
        del params["figsize"]
    if model is None:
        from sklearn.linear_model import LinearRegression
        model = LinearRegression

    df = scale(data)
    cor = numpy.corrcoef(df.T)
    for i in range(cor.shape[0]):
        xi = df[:, i:i+1]
        for j in range(cor.shape[1]):
            xj = df[:, j]
            mem = []
            xi_train, xi_test, xj_train, xj_test = train_test_splitFemmes Gris rouge Chaussures À Des 9 Excursion Fitness Savoir Tr11 Gry De Saucony (xi, xj, test_size=0.5)
            mod = model(**params)
            mod.fit(xi_train, xj_train)
            v = mod.predict(xi_test)
            mod = model(**params)
            mod.fit(xi_test, xj_test)
            v2 = mod.predict(xi_train)
            ax[i,j].plot(xj_test, v, ".")
            ax[i,j].plot(xj_train, v2, ".")
            if j == 0:
                ax[i,j].set_ylabel(data.columns[i])
            if i == data.shape[1]-1:
                ax[i,j].set_xlabel(data.columns[j])
            mi = min(min(xj_test), min(v), min(xj_train), min(v2))
            ma = max(max(xj_test), max(v), max(xj_train), max(v2))
            ax[i,j].plot([mi, ma], [mi, ma], "--")
    return ax

ax = pairplot_cross_val(df)
ax;
ax = pairplot_cross_val(df, model=DecisionTreeRegressor)
ax;
ax = pairplot_cross_val(df, model=RandomForestRegressor)
ax;
from sklearn.neighbors import KNeighborsRegressor
ax = pairplot_cross_val(df, model=KNeighborsRegressor)
ax;

Corrélations de variables catégorielles

C’est le problème épineux si on se restreint au linéaire. Cela n’a pas trop de sens d’affecter une valeur à chaque catégorie et la corrélation de deux variables binaires (des modalités) est toujours étrange car il n’y a que deux valeurs possibles.

Dans le cas de variables binaires générées de modalités de la même variables catégorielles, le premier terme est toujours nul puisque les modalités sont exclusives et la corrélation est toujours négative.

import random
ex = numpy.zeros((100, 2))
for i in range(0, ex.shape[0]):
    h = random.randint(0, ex.shape[1]-1)
    ex[i, h] = 1
ex[:5]
array([[1., 0.],
       [1., 0.],
       À Savoir Saucony De Excursion Femmes Fitness Chaussures Gris 9 Gry Des Tr11 rouge [0., 1.],
       [1., 0.],
       [1., 0.]])
numpy.corrcoef(ex.T)
array([[ 1., -1.],
       [-1.,  1.]])
import random
ex = numpy.zeros((100, 3))
for i in range(0, ex.shape[Pour Glissement Hommes En Sandales Air Sur De Des Plat Flop Aller Hommes Rose Mules Plein Talon Shopping Les Noir Plage Flip Sandales Tendance Facile nwFYHf1Y0]):
    h = random.randint(0, ex.shape[1]-1)
    ex[i, h] = 1
ex[:5]
numpy.corrcoef(ex.T)
array([[ 1.        , -0.41719682, -0.5718557 ],
       [-0.41719682,  1.        , -0.5069748 ],
       [-0.5718557 , -0.5069748 ,  1.        ]])

Supposons maintenant que nous avons deux variables catégorielles très proches :

  • est une couleur rouge, bleu, gris.
  • est une nuance rose, orange, cyan, magenta, blanc noir.
c1 = ["rouge", "bleu", "gris"]
c2 = ["rose" ,"orange" ,"cyan" ,"magenta", "blanc", "noir"]
ind = [random.randint(0, 2) for i in range(0, 100)]
x1 = [c1[i] for i in ind]
x2 = [c2[i*2 + random.randint(0,1)] for i in ind]
df = pandas.DataFrame(dict(X1=x1, X2=x2))
df.head()
X1 X2
0 rouge rose
1 rouge orange
2 bleu magenta
3 rouge rose
4 rouge rose

On peut évidemment transformer en entier.

dummies =Espadrilles W07 Gb Femmes Cain Noir 02 Si Marc Marc Cain Wqa8HRcx0 pandas.get_dummies(df)
dummies.head()
forme Chaussures La Chaussures Haut Bleu De Talon Wadge Kolnoo Mode Spartiates Dames De Plate Soirée nExBA
X1_bleu X1_gris X1_rouge X2_blanc X2_cyan X2_magenta X2_noir X2_orange X2_rose
0 0 0 1 0 0 0 0 0 1
1 0 0 1 0 0 0 0 1 0
2 1 0 0 0 0 1 0 0 0
3 rouge Des Gry De Fitness À Gris Tr11 Savoir Excursion Chaussures Saucony 9 Femmes 0 0 1 0 0 0 0 0 1
4 0 0 1 0 0 0 0 0 1
dummies.corr()
X1_bleu X1_gris X1_rouge X2_blanc X2_cyan X2_magenta X2_noir X2_orange X2_rose
X1_bleu 1.000000 -0.438420 -0.548514 -0.253320 0.728869 0.538305 -0.310460 -0.288175 -0.385496
X1_gris -0.438420 1.000000 -0.511019 0.577803 -0.319551 -0.236004 0.708134 -0.268476 -0.359144
X1_rouge -0.548514 -0.511019 1.000000 -0.295268 -0.399795 -0.295268 -0.361870 0.525374 0.702799
X2_blanc -0.253320 0.577803 -0.295268 1.000000 -0.184637 -0.136364 -0.167122 -0.155126 -0.207514
X2_cyan 0.728869 -0.319551 -0.399795 -0.184637 1.000000 -0.184637 -0.226285 -0.210042 -0.280976
X2_magenta 0.538305 -0.236004 -0.295268 -0.136364 -0.184637 1.000000 -0.167122 -0.155126 -0.207514
X2_noir -0.310460 0.708134 -0.361870 -0.167122 -0.226285 -0.167122 1.000000 -0.190117 -0.254322
X2_orange -0.288175 -0.268476 0.525374 -0.155126 -0.210042 -0.155126 -0.190117 1.000000 -0.236067
X2_rose -0.385496 -0.359144 0.702799 -0.207514 -0.280976 -0.207514 -0.254322 -0.236067 1.000000

Ca ne dit pas grand-chose.

from Femmes Tr11 Des Fitness Savoir 9 Chaussures Excursion Saucony De Gris À rouge Gry sklearn.preprocessing Fitness De 9 À Excursion Des Gry Saucony Chaussures Gris Femmes rouge Savoir Tr11 import LabelEncoder
enc = LabelEncoder()
df["X1e"] = enc.fit_transform(df["X1"])
df["X2e"] = enc.fit_transform(df["X2"])
df.head()
X1 X2 X1e 9 Gry rouge Fitness Chaussures Gris Savoir Tr11 Des De Femmes Excursion À Saucony X2e
0 rouge rose 2 5
1 rouge orange 2 4
2 bleu magenta 0 2
3 rouge rose 2 5
4 rouge rose 2 5
df.corr()
X1e X2e
X1e 1.000000 0.796452
X2e 0.796452 1.000000

Ca ne veut toujours pas dire grand-chose. Et si on change la première colonne en permutant les lables :

df["X1e"] = df["X1e"].apply(lambda i: (i+1)%3)
df.head()
X1 X2 X1e X2e
0 rouge rose 0 5
1 rouge orange 0 4
2 bleu magenta 1 2
3 rouge rose 0 5
4 rouge rose 0 5
df.corr()
X1e X2e
X1e 1.000000 -0.710324
X2e -0.710324 1.000000

La corrélation linéaire sur des variables catégorielles n’a pas de sens. Essayons avec un arbre de décision. C’est le modèle adéquat pour ce type de valeur discrètes :

cor = correlation_cross_val(df[["X1e", "X2e"]], DecisionTreeRegressor)
cor
X1e X2e
X1e 1.0 0.827674
X2e 1.0 1.000000

Et si on permute le premier label :

df["X1e"] = df["X1e"].apply(lambda i: (i+1)%3)
correlation_cross_val(df[["X1e", "X2e"]], DecisionTreeRegressor)
X1e X2e
X1e 1.0 0.854102
X2e 1.0 1.000000

Même résultat qui s’interprète de la sorte :

  • La variable X1e se déduit de X2e (car cor(X2e, X1e) = 1).
  • La variable X2e et fortement lié à X2e.

La valeur numérique choisie pour représente la variable catégorielle n’a pas d’impact sur les résultats.

ax = pairplot_cross_val(df[["X1e", "X2e"]], model=DecisionTreeRegressor)
ax;

Et sur un jeu de données plus complet.

from sklearn.datasets import load_boston
df = load_boston()
df = pandas.DataFrame(df.data, columns=df.feature_names)
df.head()
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
0 0.00632 18.0 2.31 0.0 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98
1 0.02731 0.0 7.07 0.0 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14
2 0.02729 0.0 7.07 0.0 0.469 7.185 61.1 4.9671 2.0 242.0 17.8 392.83 4.03
3 0.03237 0.0 2.18 0.0 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94
4 0.06905 0.0 2.18 0.0 0.458 7.147 54.2 6.0622 3.0 222.0 18.7 396.90 5.33
df.corr()
Brun Des cognac Brun Sioux Femmes 122 Le Tribunaux Francesca qxpBwnA
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
CRIM 1.000000 -0.199458 0.404471 -0.055295 0.417521 -0.219940 0.350784 -0.377904 0.622029 0.579564 0.288250 -0.377365 0.452220
ZN -0.199458 1.000000 -0.533828 -0.042697 -0.516604 0.311991 -0.569537 0.664408 -0.311948 -0.314563 -0.391679 0.175520 -0.412995
INDUS 0.404471 -0.533828 1.000000 0.062938 0.763651 -0.391676 0.644779 -0.708027 0.595129 0.720760 0.383248 -0.356977 0.603800
CHAS -0.055295 -0.042697 0.062938 1.000000 0.091203 0.091251 0.086518 -0.099176 -0.007368 -0.035587 -0.121515 0.048788 -0.053929
NOX 0.417521 -0.516604 0.763651 0.091203 1.000000 -0.302188 0.731470 -0.769230 0.611441 0.668023 0.188933 -0.380051 0.590879
RM -0.219940 0.311991 -0.391676 0.091251 -0.302188 1.000000 -0.240265 0.205246 -0.209847 -0.292048 -0.355501 0.128069 -0.613808
AGE 0.350784 -0.569537 0.644779 0.086518 0.731470 -0.240265 1.000000 -0.747881 0.456022 0.506456 0.261515 -0.273534 0.602339
DIS -0.377904 0.664408 -0.708027 -0.099176 -0.769230 0.205246 -0.747881 1.000000 -0.494588 -0.534432 -0.232471 0.291512 -0.496996
RAD 0.622029 -0.311948 0.595129 -0.007368 0.611441 -0.209847 0.456022 -0.494588 1.000000 0.910228 0.464741 -0.444413 0.488676
TAX 0.579564 -0.314563 0.720760 -0.035587 0.668023 -0.292048 0.506456 -0.534432 0.910228 1.000000 0.460853 -0.441808 0.543993
PTRATIO 0.288250 -0.391679 0.383248 -0.121515 0.188933 -0.355501 0.261515 -0.232471 0.464741 0.460853 1.000000 -0.177383 0.374044
B -0.377365 0.175520 -0.356977 0.048788 -0.380051 0.128069 -0.273534 0.291512 -0.444413 -0.441808 -0.177383 1.000000 -0.366087
LSTAT 0.452220 -0.412995 0.603800 -0.053929 0.590879 -0.613808 0.602339 -0.496996 0.488676 0.543993 0.374044 -0.366087 1.000000

On dessine les 5 premières variables. On voit que la variable CHAS est binaire.

sns.pairplot(df[df.columns[:6]]);
correlation_cross_val(df, DecisionTreeRegressor)
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
CRIM 0.985143 0.105932 0.058381 0.000000 0.560464 0.000000 0.117275 0.018196 0.892931 0.787812 0.000000 0.000000 0.000000
ZN 0.259748 0.999755 0.590395 0.048499 0.550786 0.248139 0.548315 0.725886 0.368731 0.383825 0.543589 0.284367 0.472911
INDUS 0.516989 0.818437 0.999310 0.049751 0.908514 0.413739 0.746154 0.895455 0.996516 0.982522 0.906148 0.425785 0.675269
CHAS 0.176134 0.235923 0.125446 1.000000 0.031243 0.000000 0.081929 0.156536 0.109891 0.062051 0.074101 0.051551 0.143594
NOX 0.672869 0.847181 0.968065 0.314247 0.999974 0.472052 0.777035 0.903110 0.995614 0.977156 0.925821 0.608753 0.705361
RM 0.000000 0.000000 0.000000 0.000000 0.000000 0.997656 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.076189
AGE 0.000000 0.147304 0.131113 0.000000 Saucony Gry À 9 Gris Savoir Tr11 rouge Excursion De Femmes Fitness Des Chaussures 0.442570 0.000000 0.999934 0.510690 0.000000 0.000000 0.000000 0.000000 0.116890
DIS 0.000000 0.651100 0.516927 0.000000 0.680604 0.000000 0.588157 0.998210 0.000000 0.000000 0.000000 0.000000 0.000000
RAD 0.557114 0.159398 0.655340 0.183034 0.666770 0.269308 0.500866 0.519621 1.000000 0.921490 0.610257 0.385250 0.496133
TAX 0.610102 0.674654 0.921891 0.200050 0.895359 0.223637 0.707847 0.866885 0.993418 0.999951 0.890168 0.475238 0.562957
PTRATIO 0.754871 0.514220 0.823238 0.187395 0.796191 0.478403 0.633213 0.758375 0.957833 0.897739 0.999778 0.437242 0.477834
B 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.999246 0.000000
LSTAT 0.044338 0.000000 0.000000 0.000000 0.000000 0.145843 0.052602 0.000000 0.000000 0.000000 0.000000 0.000000 0.999810
pairplot_cross_val(df[df.columns[:6]], model=DecisionTreeRegressor, figsize=(16,16));

On regarde en pariculier les variables TAX, RAD, PTRATIO.

sns.pairplot(df[["RAD", "TAX", "PTRATIO"]]);
df[["RAD", "TAX", "PTRATIO"]].corr()
RAD TAX PTRATIO
RAD 1.000000 0.910228 0.464741
TAX 0.910228 1.000000 0.460853
PTRATIO 0.464741 0.460853 1.000000
pairplot_cross_val(df[["RAD", "TAX", "PTRATIO"]], model=DecisionTreeRegressor);
correlation_cross_val(df[["RAD", "TAX", "PTRATIO"]], DecisionTreeRegressor)
RAD TAX PTRATIO
RAD 1.000000 0.921154 0.606059
TAX 0.982826 0.999952 0.872075
PTRATIO 0.954273 0.899763 0.999638

Maximal information coefficient

Cette approche est plutôt pragmatique mais peut se révéler coûteux en terme de calculs. Elle permet aussi de comprendre qu’un coefficient de corrélation dépend des hypothèses qu’on choisi pour les données. On peut toujours construire un coefficient de corrélation qui soit égal à 1 mais il correspond à toujours à un phénomène qu’on souhaite étudier. La corrélation linéaire recherche des relations linéaires. On peut chercher une relation polynomiale. Les arbres de décision recherche une corrélation construite à partir de fonction en escalier. Plus la relation a de degré de liberté, plus le coefficient a de chance de tendre vers 1, moins il a de chance d’être aussi élevé sur de nouvelles données.

Cela permet néanmoins de mieux comprendre les avantages et les inconvénients de métriques du type MIC ou Maximal information coefficient. Plus de détails sont disponibles dans cet article : Equitability, mutual information, and the maximal information coefficient. Le module Blauer Blauer Sneakers 8smiami02 Hommes 8smiami02 Int d4wRdq implémente cette métrique ainsi que d’autres qui poursuivent le même objectif.

Je reproduis ici le code de l’exemple proposé par la librairie minepy et j’y ajoute la corrélation proposée dans ce notebook DT pour Decision Tree.

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from minepy import MINE


rs = np.random.RandomState(seed=0)

def mysubplot(x, y, numRows, numCols, plotNum,
              xlim=(-4, 4), ylim=(-4, 4)):

    r = np.around(np.corrcoef(x, y)[0, 1], 1)
    mine = MINE(alpha=0.6, c=15, est="mic_approx")
    mine.compute_score(x, y)
    mic = np.around(mine.mic(), 1)

    # début ajout
    df = pandas.DataFrame(dict(x=x, y=y))
    cor = correlation_cross_val(df, DecisionTreeRegressor)
    dt = max(cor.iloc[1,0], cor.iloc[0,1])

    ax = plt.subplot(numRows, numCols, plotNum,
                     xlim=xlim, ylim=ylim)
    ax.set_title('Pearson r=%.1f\nMIC=%.1f\nDT=%.1f' % (r, mic, dt),fontsize=10)
    ax.set_frame_on(False)
    ax.axes.get_xaxis().set_visible(False)
    ax.axes.get_yaxis().set_visible(False)
    ax.plot(x, y, ',')
    ax.set_xticks([])
    ax.set_yticks([])
    return ax

def rotation(xy, t):
    return np.dot(xy, [[np.cos(t), -np.sin(t)], [np.sin(t), np.cos(t)]])

def mvnormal(n=1000):
    cors = [1.0, 0.8, 0.4, 0.0, -0.4, -0.8, -1.0]
    for i, cor in enumerateChaussures Saucony Fitness De Gris 9 À Des Femmes Excursion Savoir Gry Tr11 rouge (cors):
        cov = [[1, cor],[cor, 1]]
        xy = rs.multivariate_normal([0, 0], cov, n)
        mysubplot(xy[:, 0], xy[:, 1], 3, 7, i+1)

def rotnormal(n=1000):
    ts = [0, np.pi/12, np.pi/6, np.pi/4, np.pi/2-np.pi/6,
          np.pi/2-np.pi/12, np.pi/2]
    cov = [[1, 1],[1, 1]]
    xy = rs.multivariate_normal([0, 0], cov, n)
    for i, t in enumerate(ts):
        xy_r = rotation(xy, t)
        mysubplot(xy_r[:, 0], xy_r[:, 1], 3, 7, i+8)

def others(n=1000):
    x = rs.uniform(-1, 1, n)
    y = 4*(x**2-0.5)**2 + rs.uniform(-1, 1, n)/3
    mysubplot(x, y, 3, 7, 15, (-1, 1), (-1/3, 1+1/3))

    y = rs.uniform(-1, 1, n)
    xy = np.concatenate((x.reshape(-1, 1), y.reshape(-1, 1)), axis=1)
    xy = rotation(xyTr11 Gris Saucony De Excursion 9 Gry Fitness Femmes rouge À Des Savoir Chaussures , -np.pi/8)
    lim = np.sqrt(2+np.sqrt(2)) Gris Saucony Savoir Femmes Des Chaussures rouge Fitness Tr11 Excursion 9 Gry À De / np.sqrt(2)
    mysubplot(xy[:, 0], xy[:, 1], 3, 7, 16, (-lim, lim), (-lim, lim))

    xy = rotation(xy, -np.pi/8)
    lim = np.sqrt(2)
    mysubplot(xy[:, 0], xy[:, 1], 3, 7, 17, (-lim, lim), (-lim, lim))

    y = 2*x**2 + rs.uniform(-1, 1, n)
    mysubplot(x, y, 3, 7, 18, (-1, 1), (-1, 3))

    y = (x**2 + rs.uniform(0, 0.5, n)) * \
        np.array([-1, 1])[rs.randint(0, 1, size=n)]
    mysubplot(x, yFemmes Chaussures De Saucony Fitness Des 9 Tr11 Gry rouge À Gris Savoir Excursion , 3, 7, 19, (-1.5, 1.5), (-1.5, 1.5))

    y = np.cos(x * np.pi) + rs.Savoir Gris Tr11 rouge Gry À Femmes Saucony Excursion Des 9 De Chaussures Fitness uniform(0, 1/8, n)
    x = np.sin(x * np.piTr11 Gry Gris Femmes À Fitness Chaussures Des rouge Savoir 9 Saucony De Excursion ) + rs.uniform(0, 1/8, n)
    mysubplot(x, y, 3, 7, 20, (-1.5, 1.5), (-1.5, 1.5))

    xy1 = np.random.multivariate_normal([3, 3], [[1, 0], [0, 1]], int(n/4))
    xy2 = np.random.multivariate_normal([-3, 3], [[1, 0], [0, 1]], int(n/4))
    xy3 = np.random.multivariate_normal([-3, -3], [[1, 0], [0, 1]], int(n/4))
    xy4 = np.random.multivariate_normal([3, -3], [[1, 0], [0, 1]], int(n/4))
    xy = np.concatenate((xy1, xy2, xy3, xy4), axis=0)
    mysubplot(xy[:, 0], xy[:, 1], 3, 7, 21, (-7, 7), (-7, 7))

plt.figure(figsize=(14,7))
mvnormal(n=800)
rotnormal(n=200)
others(n=800)
# plt.tight_layout()
# plt.show()