<jupyter_start><jupyter_text>Base d'apprentissage et de testLe modèle est estimé sur une base d'apprentissage et évalué sur une base de test.<jupyter_code>%matplotlib inline
from papierstat.datasets import load_wines_dataset
df = load_wines_dataset()
X = df.drop(['quality', 'color'], axis=1)
y = df['quality']<jupyter_output><empty_output><jupyter_text>On divise en base d'apprentissage et de test avec la fonction [train_test_split](http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html).<jupyter_code>from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
from sklearn.neighbors import KNeighborsRegressor
knn = KNeighborsRegressor(n_neighbors=1)
knn.fit(X_train, y_train)
prediction = knn.predict(X_test)
import pandas
res = pandas.DataFrame(dict(expected=y_test, prediction=prediction))
res.head()
from seaborn import jointplot
ax = jointplot("expected", "prediction", res, kind="kde", size=4)
ax.ax_marg_y.set_title('Distribution valeurs attendues\nvaleurs prédites');<jupyter_output><empty_output><jupyter_text>Le résultat paraît acceptable. On enlève les réponses correctes.<jupyter_code>ax = jointplot("expected", "prediction", res[res['expected'] != res['prediction']], kind="kde", size=4)
ax.ax_marg_x.set_title('Distribution valeurs attendues\nvaleurs prédites\n' +
                       'sans les réponses correctes');
res['diff'] = res['prediction'] - res["expected"]
ax = res['diff'].hist(bins=15, figsize=(3,3))
ax.set_title("Répartition des différences");<jupyter_output><empty_output><jupyter_text>Si on fait la moyenne des erreurs en valeur absolue :<jupyter_code>import numpy
numpy.abs(res['diff']).mean()<jupyter_output><empty_output><jupyter_text>Le modèle se trompe en moyenne d'un demi point. Le module *scikit-learn* propose de nombreuses [métriques](http://scikit-learn.org/stable/modules/classes.htmlsklearn-metrics-metrics) pour évaluer les résultats. On s'intéresse plus particulièrement à celle de la [régression](http://scikit-learn.org/stable/modules/classes.htmlregression-metrics). Celle qu'on a utilisée s'appelle [mean_absolute_error](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_absolute_error.htmlsklearn.metrics.mean_absolute_error).<jupyter_code>from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test, prediction)<jupyter_output><empty_output><jupyter_text>Un autre indicateur très utilisé : [R2](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.htmlsklearn.metrics.r2_score).<jupyter_code>from sklearn.metrics import r2_score
r2_score(y_test, prediction)<jupyter_output><empty_output><jupyter_text>Une valeur négative implique que le modèle fait moins bien que si la prédiction était constante et égale à la moyenne des notes sur la base de test. Essayons.<jupyter_code>const = numpy.mean(y_test) * numpy.ones(y_test.shape[0])
r2_score(y_test, const)<jupyter_output><empty_output><jupyter_text>Pour être rigoureux, il faudrait prendre la moyenne des notes sur la base d'apprentissage, celles des vins connus.<jupyter_code>const = numpy.mean(y_train) * numpy.ones(y_test.shape[0])
r2_score(y_test, const)<jupyter_output><empty_output><jupyter_text>Sensiblement pareil et on sait maintenant que le modèle n'est pas bon. On cherche une explication. Une raison possible est que les bases d'apprentissage et de test ne sont pas homogènes : le modèle apprend sur des données et est testé sur d'autres qui n'ont rien à voir. On commence par regarder la distribution des notes.<jupyter_code>ys = pandas.DataFrame(dict(y=y_train))
ys['base'] = 'train'
ys2 = pandas.DataFrame(dict(y=y_test))
ys2['base'] = 'test'
ys = pandas.concat([ys, ys2])
ys['compte'] = 1
piv = ys.groupby(['base', 'y'], as_index=False).count().pivot('y', 'base', 'compte')
piv['ratio'] = piv['test'] / piv['train']
piv<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11992855320234753, 'fraction_numerical': 0.0053585098239346774, 'mean_word_length': 7.466522678185745, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '188606', 'license': 'MIT', 'n_tokens_mistral': 1403, 'n_tokens_neox': 1387, 'n_words': 303, 'path': '_doc/notebooks/lectures/wines_knn_split.ipynb', 'repo_name': 'sdpython/papierstat', 'size': '3919'}