<jupyter_start><jupyter_text>Classification multi-classeOn cherche à prédire la note d'un vin avec un classifieur multi-classe.<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']
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
from sklearn.linear_model import LogisticRegression
clr = LogisticRegression()
clr.fit(X_train, y_train)
import numpy
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>On regarde la matrice de confusion.<jupyter_code>from sklearn.metrics import confusion_matrix
import pandas
pandas.DataFrame(confusion_matrix(y_test, clr.predict(X_test)))<jupyter_output><empty_output><jupyter_text>On l'affiche différemment avec le nom des classes.<jupyter_code>conf = confusion_matrix(y_test, clr.predict(X_test))
dfconf = pandas.DataFrame(conf)
labels = list(clr.classes_)
if len(labels) < dfconf.shape[1]:
    labels += [9]  # La classe 9 est très représentée, elle est parfois absente en train.
elif len(labels) > dfconf.shape[1]:
    labels = labels[:dfconf.shape[1]] # ou l'inverse
dfconf.columns = labels
dfconf.index = labels
dfconf<jupyter_output><empty_output><jupyter_text>Pas extraordinaire. On applique la stratégie [OneVsRestClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.multiclass.OneVsRestClassifier.html).<jupyter_code>from sklearn.multiclass import OneVsRestClassifier
clr = OneVsRestClassifier(LogisticRegression())
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>Le modèle logistique régression multi-classe est équivalent à la stratégie *OneVsRest*. Voyons l'autre.<jupyter_code>from sklearn.multiclass import OneVsOneClassifier
clr = OneVsOneClassifier(LogisticRegression())
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100
conf = confusion_matrix(y_test, clr.predict(X_test))
dfconf = pandas.DataFrame(conf)
labels = list(clr.classes_)
if len(labels) < dfconf.shape[1]:
    labels += [9]  # La classe 9 est très représentée, elle est parfois absente en train.
elif len(labels) > dfconf.shape[1]:
    labels = labels[:dfconf.shape[1]] # ou l'inverse
dfconf.columns = labels
dfconf.index = labels
dfconf<jupyter_output><empty_output><jupyter_text>A peu près pareil mais sans doute pas de manière significative. Voyons avec un arbre de décision.<jupyter_code>from sklearn.tree import DecisionTreeClassifier
clr = DecisionTreeClassifier()
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>Et avec [OneVsRestClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.multiclass.OneVsRestClassifier.html) :<jupyter_code>clr = OneVsRestClassifier(DecisionTreeClassifier())
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>Et avec [OneVsOneClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.multiclass.OneVsOneClassifier.html)<jupyter_code>clr = OneVsOneClassifier(DecisionTreeClassifier())
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>Mieux.<jupyter_code>from sklearn.ensemble import RandomForestClassifier
clr = RandomForestClassifier()
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100
clr = OneVsRestClassifier(RandomForestClassifier())
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output><jupyter_text>Proche, il faut affiner avec une validation croisée.<jupyter_code>from sklearn.neural_network import MLPClassifier
clr = MLPClassifier(hidden_layer_sizes=30, max_iter=600)
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100
clr = OneVsRestClassifier(MLPClassifier(hidden_layer_sizes=30, max_iter=600))
clr.fit(X_train, y_train)
numpy.mean(clr.predict(X_test).ravel() == y_test.ravel()) * 100<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1250585480093677, 'fraction_numerical': 0.011943793911007026, 'mean_word_length': 8.204741379310345, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, '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': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '432717', 'license': 'MIT', 'n_tokens_mistral': 1644, 'n_tokens_neox': 1565, 'n_words': 263, 'path': '_doc/notebooks/lectures/wines_multi.ipynb', 'repo_name': 'sdpython/papierstat', 'size': '4270'}