"Apprentissage automatique appris" pour trouver la fonction $ f $ telle que $ y = f (X) $ lorsque la variable objective correspondante $ y $ est connue pour une variable explicative $ X_n $ Est appelé. Les plus simples sont la «régression linéaire simple» et la «régression multiple linéaire».
A titre d'exemple, nous utiliserons les données "Pima Indian Diabetes Diagnosis"
#Importez une bibliothèque qui permet d'accéder aux ressources par URL.
import urllib.request
#Spécifier les ressources sur le Web
url = 'https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/pima-indians-diabetes.txt'
#Téléchargez la ressource à partir de l'URL spécifiée et donnez-lui un nom.
urllib.request.urlretrieve(url, 'pima-indians-diabetes.txt')
('pima-indians-diabetes.txt', <http.client.HTTPMessage at 0x7fd16c201550>)
#Importer une bibliothèque pour traiter des données qui ressemblent à un calcul de table
import pandas as pd
#Lire les données et enregistrer au format de trame de données
df = pd.read_csv('pima-indians-diabetes.txt', delimiter="\t", index_col=0)
#Vérifiez le contenu
df
NumTimePreg | OralGluTol | BloodPres | SkinThick | SerumInsulin | BMI | PedigreeFunc | Age | Class | |
---|---|---|---|---|---|---|---|---|---|
0 | 6 | 148 | 72 | 35 | 0 | 33.6 | 0.627 | 50 | 1 |
1 | 1 | 85 | 66 | 29 | 0 | 26.6 | 0.351 | 31 | 0 |
2 | 8 | 183 | 64 | 0 | 0 | 23.3 | 0.672 | 32 | 1 |
3 | 1 | 89 | 66 | 23 | 94 | 28.1 | 0.167 | 21 | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
765 | 5 | 121 | 72 | 23 | 112 | 26.2 | 0.245 | 30 | 0 |
766 | 1 | 126 | 60 | 0 | 0 | 30.1 | 0.349 | 47 | 1 |
767 | 1 | 93 | 70 | 31 | 0 | 30.4 | 0.315 | 23 | 0 |
768 rows × 9 columns
Si la «classe» ci-dessus est la variable objective $ y $, 1 signifie diabète et 0 signifie pas diabète. Créons un modèle qui le prédit.
#Variable explicative
X = df.iloc[:, :8]
#Normalisation telle que la valeur maximale soit 1 et la valeur minimale 0.
# axis=Si 1, il normalise par ligne au lieu de colonne.
X = X.apply(lambda x: (x-x.min())/(x.max() - x.min()), axis=0)
#Variable objectif
y = df.iloc[:, 8]
Dans l'apprentissage automatique, afin d'évaluer ses performances, les données connues sont divisées en données d'entraînement (également appelées données d'enseignant et ensemble d'enseignants) et données de test (également appelées ensemble de test). Un modèle de prédiction est construit par apprentissage (apprentissage) à l'aide des données d'apprentissage, et une évaluation des performances est effectuée en fonction de la précision avec laquelle les données de test qui n'ont pas été utilisées dans la construction du modèle de prédiction peuvent être prédites. Une telle méthode d'évaluation est appelée «validation croisée». ici,
Données d'entraînement (60% de toutes les données)
X_train: variables explicatives des données d'entraînement
y_train: variable objective des données d'entraînement
Données de test (40% de toutes les données)
X_test: variable explicative pour les données de test
y_test: variable objective des données de test
Ensuite, nous visons à apprendre la relation entre X_train et y_train et à prédire y_test à partir de X_test.
La bibliothèque d'apprentissage automatique de Python scikit-learn fournit des méthodes de fractionnement en données d'entraînement et de test.
#Méthode d'importation à diviser en données d'entraînement et données de test
from sklearn.model_selection import train_test_split
#Vers les données d'entraînement / les données de test 6:Divisé au hasard par un rapport de 4
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
La régression logistique est similaire à la régression multiple linéaire, mais avec une valeur discrète indiquant si la variable objective $ y $ est 0 ou 1. Dans ma dernière conférence, j'ai implémenté la régression logistique en utilisant la bibliothèque scipy, mais il est plus pratique d'utiliser scikit-learn dans la pratique.
Découvrez les méthodes et paramètres disponibles sur les sites suivants.
from sklearn.linear_model import LogisticRegression #Retour logistique
classifier = LogisticRegression() #Générer un classificateur
classifier.fit(X_train, y_train) #Apprentissage
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l2',
random_state=None, solver='warn', tol=0.0001, verbose=0,
warm_start=False)
Il est utile d'utiliser timeit pour mesurer le temps nécessaire à l'apprentissage.
import timeit #Bibliothèque de mesure du temps d'exécution
timeit.timeit(lambda: classifier.fit(X_train, y_train), number=1)
0.006864218999993454
Il est nécessaire de faire la distinction entre «l'exactitude de la classification des données utilisées pour la formation» et «l'exactitude de la classification des données non utilisées pour la formation». Les modèles avec un premier très haut et un second bas ont de faibles performances de généralisation et sont dits "sur-équipés".
#Taux de réponse correct(train) :Avec quelle précision peut-on prévoir les données utilisées pour la formation?
classifier.score(X_train,y_train)
0.7800289435600579
#Taux de réponse correct(test) :Avec quelle précision pouvez-vous prédire les données qui n'ont pas été utilisées pour la formation?
classifier.score(X_test,y_test)
0.7402597402597403
Il est possible de prédire non seulement le taux de précision, mais également quelles données sont spécifiquement classées dans lesquelles.
#Prédire les données non utilisées pour la formation
y_pred = classifier.predict(X_test)
y_pred
array([1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0])
Si vous connaissez la bonne réponse, vous pouvez faire correspondre les réponses. La matrice de confusion est utile pour cette agrégation.
from sklearn.metrics import confusion_matrix #Méthode de calcul de la matrice de confusion
#Une matrice de confusion qui montre dans quelle mesure le résultat de la prédiction et la bonne réponse (vraie réponse) correspondent.
pd.DataFrame(confusion_matrix(y_pred, y_test),
index=['predicted 0', 'predicted 1'], columns=['real 0', 'real 1'])
real 0 | real 1 | |
---|---|---|
predicted 0 | 47 | 18 |
predicted 1 | 2 | 10 |
Les données dans lesquelles sont classées sont jugées par la «force de confiance» de chaque classification. En les organisant par ordre de confiance forte, vous pouvez dessiner des courbes ROC et PR et évaluer les performances du modèle de prédiction.
#Calculez la force de confiance dans les résultats de prédiction
y_proba = classifier.predict_proba(X_test)
y_proba
array([[0.21417054, 0.78582946],
[0.46404957, 0.53595043],
[0.70401466, 0.29598534],
[0.75314361, 0.24685639],
[0.76452966, 0.23547034],
[0.33685542, 0.66314458],
[0.76393323, 0.23606677],
[0.82487552, 0.17512448],
[0.87720401, 0.12279599],
[0.83530283, 0.16469717],
[0.64980016, 0.35019984],
[0.78574888, 0.21425112],
[0.51054138, 0.48945862],
[0.24870259, 0.75129741],
[0.91082684, 0.08917316],
[0.86200773, 0.13799227],
[0.71562431, 0.28437569],
[0.62886446, 0.37113554],
[0.63181921, 0.36818079],
[0.77975231, 0.22024769],
[0.65396517, 0.34603483],
[0.81535938, 0.18464062],
[0.54607196, 0.45392804],
[0.79688063, 0.20311937],
[0.80333846, 0.19666154],
[0.728435 , 0.271565 ],
[0.36817034, 0.63182966],
[0.54025915, 0.45974085],
[0.6614052 , 0.3385948 ],
[0.74309548, 0.25690452],
[0.92572332, 0.07427668],
[0.80406998, 0.19593002],
[0.61165474, 0.38834526],
[0.43564389, 0.56435611],
[0.42922327, 0.57077673],
[0.61369072, 0.38630928],
[0.68195508, 0.31804492],
[0.86971152, 0.13028848],
[0.81006182, 0.18993818],
[0.86324924, 0.13675076],
[0.82269894, 0.17730106],
[0.48717372, 0.51282628],
[0.72772261, 0.27227739],
[0.81581007, 0.18418993],
[0.54651378, 0.45348622],
[0.65486361, 0.34513639],
[0.69695761, 0.30304239],
[0.50397912, 0.49602088],
[0.70579261, 0.29420739],
[0.56812519, 0.43187481],
[0.28702944, 0.71297056],
[0.78684682, 0.21315318],
[0.77913962, 0.22086038],
[0.20665217, 0.79334783],
[0.64020202, 0.35979798],
[0.54394942, 0.45605058],
[0.74972094, 0.25027906],
[0.89307226, 0.10692774],
[0.63129007, 0.36870993],
[0.775181 , 0.224819 ],
[0.88651222, 0.11348778],
[0.83087546, 0.16912454],
[0.52015754, 0.47984246],
[0.17895175, 0.82104825],
[0.68620306, 0.31379694],
[0.6503939 , 0.3496061 ],
[0.53702941, 0.46297059],
[0.74395419, 0.25604581],
[0.79430285, 0.20569715],
[0.70717315, 0.29282685],
[0.74036824, 0.25963176],
[0.35031104, 0.64968896],
[0.59128595, 0.40871405],
[0.62945511, 0.37054489],
[0.85812094, 0.14187906],
[0.95492842, 0.04507158],
[0.82726693, 0.17273307]])
#Importez une bibliothèque pour illustrer des diagrammes et des graphiques.
import matplotlib.pyplot as plt
%matplotlib inline
Voici la méthode pour gérer la courbe ROC et le score AUC en dessous.
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.auc.html
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
#Donnez un score AUC
fpr, tpr, thresholds = roc_curve(y_test, y_proba[:, 1])
roc_auc = auc(fpr, tpr)
print ("AUC curve : %f" % roc_auc)
#Dessinez une courbe ROC
plt.figure(figsize=(4,4))
plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve: AUC=%0.2f' % roc_auc)
plt.legend(loc="lower right")
plt.show()
AUC curve : 0.756560
De même, voici la méthode pour dessiner une courbe PR.
from sklearn.metrics import auc
from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(y_test, y_proba[:, 1])
area = auc(recall, precision)
print ("AUPR score: %0.2f" % area)
#Dessinez une courbe PR
plt.figure(figsize=(4,4))
plt.plot(recall, precision, label='Precision-Recall curve')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.ylim([0.0, 1.05])
plt.xlim([0.0, 1.0])
plt.title('Precision-Recall curve: AUPR=%0.2f' % area)
plt.legend(loc="lower left")
plt.show()
AUPR score: 0.68
Les méthodes d'apprentissage automatique nécessitent de nombreux paramètres. La valeur par défaut (par défaut) ne fait pas une bonne prédiction. Une des façons de trouver de bons paramètres est la "recherche de grille". GridSearchCV divise davantage les données d'entraînement (par défaut, validation croisée en 3 parties), essaie toutes les combinaisons de paramètres candidats et recherche les paramètres qui affichent d'excellentes performances en moyenne.
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Paramètres pour effectuer la recherche de grille (paramètres LogisticRegression)
parameters = [
{'solver': ['liblinear', 'saga'], 'penalty':['l1', 'l2'], 'C': [0.1, 1, 10, 100]},
{'solver': ['newton-cg', 'sag', 'lbfgs' ], 'penalty':['l2'], 'C': [0.1, 1, 10, 100]},
]
#Exécution de la recherche de grille
classifier = GridSearchCV(LogisticRegression(), parameters, cv=3, n_jobs=-1)
classifier.fit(X_train, y_train)
print("Accuracy score (train): ", classifier.score(X_train, y_train))
print("Accuracy score (test): ", classifier.score(X_test, y_test))
print(classifier.best_estimator_) #Classificateur avec les meilleurs paramètres
Accuracy score (train): 0.784370477568741
Accuracy score (test): 0.6883116883116883
LogisticRegression(C=1, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l1',
random_state=None, solver='saga', tol=0.0001, verbose=0,
warm_start=False)
CPU times: user 192 ms, sys: 25.4 ms, total: 218 ms
Wall time: 2.52 s
Désormais, j'aimerais comparer les performances de différentes méthodes d'apprentissage automatique. Par conséquent, préparons une variable pour enregistrer l'indice d'évaluation.
scores = []
Il existe différents indicateurs de la performance du modèle de classification. Les principaux sont les suivants. Vérifions la signification de chacun.
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html
https://scikit-learn.org/stable/modules/generated/sklearn.metrics.matthews_corrcoef.html
J'ai créé une fonction qui calcule ces index d'évaluation ensemble et les stocke dans une variable pour l'enregistrement comme suit. Répétez l'entraînement et la validation croisée pour différentes divisions de données et enregistrez leurs performances moyennes, leur écart type et leur temps d'entraînement.
import timeit
from sklearn import metrics
def record_classification_scores(classifier_name, classifier, iter=5):
records = []
for run_id in range(iter):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
print('Run ', run_id + 1)
seconds = timeit.timeit(lambda: classifier.fit(X_train, y_train), number=1)
print(' Learning Time (s):', seconds)
y_pred = classifier.predict(X_test)
y_proba = classifier.predict_proba(X_test)
accuracy_score = metrics.accuracy_score(y_test, y_pred)
precision_score = metrics.precision_score(y_test, y_pred)
recall_score = metrics.recall_score(y_test, y_pred)
f1_score = metrics.f1_score(y_test, y_pred)
fpr, tpr, thresholds = roc_curve(y_test, y_proba[:, 1])
roc_auc = auc(fpr, tpr)
pre, rec, thresholds = precision_recall_curve(y_test, y_proba[:, 1])
aupr = auc(rec, pre)
mcc = metrics.matthews_corrcoef(y_test, y_pred)
records.append([classifier_name, accuracy_score, precision_score, recall_score,
f1_score, roc_auc, aupr, mcc, seconds])
return records
Maintenant, apprenons à utiliser le "classificateur avec les meilleurs paramètres" créé précédemment et enregistrons l'indice de performance.
%%time
scores += record_classification_scores('LR', classifier.best_estimator_)
Run 1
Learning Time (s): 0.004809510999990607
Run 2
Learning Time (s): 0.004076423000000773
Run 3
Learning Time (s): 0.004598837999992611
Run 4
Learning Time (s): 0.004291107000000238
Run 5
Learning Time (s): 0.003665049000005638
CPU times: user 65.8 ms, sys: 3.33 ms, total: 69.1 ms
Wall time: 67.6 ms
La performance moyenne et son écart type sont les suivants.
df_scores = pd.DataFrame(scores, columns = ['Classifier', 'Accuracy', 'Precision', 'Recall',
'F1 score', 'ROC AUC', 'AUPR', 'MCC', 'Time'])
df_scores_mean = df_scores.iloc[:, :-1].mean()
df_scores_errors = df_scores.iloc[:, :-1].std()
df_scores_mean.plot(kind='bar', grid=True, yerr=df_scores_errors)
<matplotlib.axes._subplots.AxesSubplot at 0x7fd15943ca90>
Le Gradient Boosting est une technique qui a récemment attiré l'attention. Je n'entrerai pas dans les détails ici. Vérifiez les paramètres requis sur le site ci-dessous.
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Augmentation du gradient
from sklearn.ensemble import GradientBoostingClassifier
#Paramètres pour effectuer une recherche de grille
parameters = [{
'loss': ['deviance', 'exponential'],
'learning_rate':[0.1,0.2],
'n_estimators':[20,100,200],
'max_depth':[3,5,7,9]
}]
#Exécution de la recherche de grille
classifier = GridSearchCV(GradientBoostingClassifier(), parameters, cv=3, n_jobs=-1)
classifier.fit(X_train, y_train)
print("Accuracy score (train): ", classifier.score(X_train, y_train))
print("Accuracy score (test): ", classifier.score(X_test, y_test))
print(classifier.best_estimator_) #Meilleurs paramètres
Accuracy score (train): 1.0
Accuracy score (test): 0.7142857142857143
GradientBoostingClassifier(criterion='friedman_mse', init=None,
learning_rate=0.2, loss='deviance', max_depth=7,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_iter_no_change=None, presort='auto',
random_state=None, subsample=1.0, tol=0.0001,
validation_fraction=0.1, verbose=0,
warm_start=False)
CPU times: user 947 ms, sys: 25.1 ms, total: 973 ms
Wall time: 25.2 s
Apprenons et enregistrons les performances en utilisant le "classificateur avec les meilleurs paramètres" obtenu.
%%time
scores += record_classification_scores('GB', classifier.best_estimator_)
Run 1
Learning Time (s): 0.3291641410000068
Run 2
Learning Time (s): 0.31575948799999765
Run 3
Learning Time (s): 0.3144692120000059
Run 4
Learning Time (s): 0.3252903609999862
Run 5
Learning Time (s): 0.3103595519999942
CPU times: user 1.64 s, sys: 7.28 ms, total: 1.65 s
Wall time: 1.65 s
J'ai créé une fonction pour visualiser la comparaison des performances de plusieurs méthodes de classification.
def visualize_classification_result(scores):
df_scores = pd.DataFrame(scores, columns = ['Classifier', 'Accuracy', 'Precision', 'Recall',
'F1 score', 'ROC AUC', 'AUPR', 'MCC', 'Time'])
df_scores_mean = df_scores.iloc[:, :-1].groupby('Classifier').mean()
df_scores_errors = df_scores.iloc[:, :-1].groupby('Classifier').std()
df_scores_mean.T.plot(kind='bar', grid=True, yerr=df_scores_errors.T,
figsize=(12, 2), legend=False)
plt.legend(loc = 'right', bbox_to_anchor = (0.7, 0.5, 0.5, 0.0))
df_scores_mean.plot(kind='bar', grid=True, yerr=df_scores_errors,
figsize=(12, 2), legend=False)
plt.legend(loc = 'right', bbox_to_anchor = (0.7, 0.5, 0.5, 0.0))
df_time_mean = df_scores.iloc[:, [0, -1]].groupby('Classifier').mean()
df_time_errors = df_scores.iloc[:, [0, -1]].groupby('Classifier').std()
df_time_mean.plot(kind='bar', grid=True, yerr=df_time_errors,
figsize=(12, 2), legend=False)
plt.yscale('log')
visualize_classification_result(scores)
Multi-Layer Perceptron est le modèle le plus simple d'apprentissage en profondeur et est également implémenté dans scikit-learn.
Découvrez les méthodes et paramètres disponibles sur les sites suivants.
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Perceptron multicouche
from sklearn.neural_network import MLPClassifier
#Paramètres pour effectuer une recherche de grille
parameters = [{'hidden_layer_sizes': [8, (8, 8), (8, 8, 8)],
'solver': ['sgd', 'adam', 'lbfgs'],
'activation': ['logistic', 'tanh', 'relu'],
'learning_rate_init': [0.1, 0.01, 0.001]}]
#Exécution de la recherche de grille
classifier = GridSearchCV(MLPClassifier(max_iter=10000, early_stopping=True),
parameters, cv=3, n_jobs=-1)
classifier.fit(X_train, y_train)
print("Accuracy score (train): ", classifier.score(X_train, y_train))
print("Accuracy score (test): ", classifier.score(X_test, y_test))
print(classifier.best_estimator_) #Classificateur avec les meilleurs paramètres
Accuracy score (train): 0.7930535455861071
Accuracy score (test): 0.7272727272727273
MLPClassifier(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
beta_2=0.999, early_stopping=True, epsilon=1e-08,
hidden_layer_sizes=8, learning_rate='constant',
learning_rate_init=0.1, max_iter=10000, momentum=0.9,
n_iter_no_change=10, nesterovs_momentum=True, power_t=0.5,
random_state=None, shuffle=True, solver='lbfgs', tol=0.0001,
validation_fraction=0.1, verbose=False, warm_start=False)
CPU times: user 1.15 s, sys: 39.8 ms, total: 1.19 s
Wall time: 2min 29s
Apprenons et enregistrons les performances en utilisant le "classificateur avec les meilleurs paramètres" obtenu.
%%time
scores += record_classification_scores('MLP', classifier.best_estimator_)
Run 1
Learning Time (s): 0.4756240830000138
Run 2
Learning Time (s): 0.34581674499997916
Run 3
Learning Time (s): 0.15651393699999971
Run 4
Learning Time (s): 0.14490434999999025
Run 5
Learning Time (s): 0.005184319999955278
CPU times: user 1.16 s, sys: 3.54 ms, total: 1.17 s
Wall time: 1.17 s
Comparez les performances.
visualize_classification_result(scores)
scikit-learn fournit l'ensemble de données breast_cancer en tant que données d'entraînement pour l'apprentissage automatique. Divisez l'ensemble de données en variables explicatives et en variables objectives comme suit, classez les données breast_cancer avec MLPClassifier tout en ajustant les paramètres avec GridSearchCV et évaluez les performances.
# https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_breast_cancer.html
from sklearn.datasets import load_breast_cancer
breast_cancer = load_breast_cancer()
X = pd.DataFrame(breast_cancer.data)
y = pd.DataFrame(breast_cancer.target.ravel())
scikit-learn fournit un ensemble de données wine en tant que données de formation pour l'apprentissage automatique. Divisez l'ensemble de données en variables explicatives et en variables objectives comme suit, classez les données de vin avec MLPClassifier tout en ajustant les paramètres avec GridSearchCV et évaluez les performances.
# https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_wine.html
from sklearn.datasets import load_wine
wine = data = load_wine()
X = pd.DataFrame(wine.data)
y = pd.DataFrame(wine.target)
Cependant, comme l'ensemble de données wine n'est pas une classification à deux classes comme l'ensemble de données breast_cancer, mais une classification à trois classes, la variable objective doit être prétraitée comme suit.
# https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
import numpy as np
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(categories="auto", sparse=False, dtype=np.float32)
y = pd.DataFrame(encoder.fit_transform(y))
De plus, si le nombre de nœuds MLP (nombre de neurones) est trop petit, les performances de classification seront faibles, augmentez donc le nombre de nœuds (nombre de neurones) de manière appropriée.
Maintenant que nous avons résolu le problème de classification, résolvons le problème de régression. En tant que sujet, nous discuterons de la relation entre la composition et la résistance du béton. Tout d'abord, récupérez les données concrètes.
La source des données est l'ensemble de données du test de dégringolade du béton https://archive.ics.uci.edu/ml/datasets/Concrete+Slump+Test.
#Importez une bibliothèque qui permet d'accéder aux ressources par URL.
import urllib.request
#Spécifier les ressources sur le Web
url = 'https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/slump_test.data'
#Téléchargez la ressource à partir de l'URL spécifiée et donnez-lui un nom.
urllib.request.urlretrieve(url, 'slump_test.data')
('slump_test.data', <http.client.HTTPMessage at 0x7ff02ed82518>)
import pandas as pd
df = pd.read_csv('slump_test.data', index_col=0)
df
Cement | Slag | Fly ash | Water | SP | Coarse Aggr. | Fine Aggr. | SLUMP(cm) | FLOW(cm) | Compressive Strength (28-day)(Mpa) | |
---|---|---|---|---|---|---|---|---|---|---|
No | ||||||||||
1 | 273.0 | 82.0 | 105.0 | 210.0 | 9.0 | 904.0 | 680.0 | 23.0 | 62.0 | 34.99 |
2 | 163.0 | 149.0 | 191.0 | 180.0 | 12.0 | 843.0 | 746.0 | 0.0 | 20.0 | 41.14 |
3 | 162.0 | 148.0 | 191.0 | 179.0 | 16.0 | 840.0 | 743.0 | 1.0 | 20.0 | 41.81 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
101 | 258.8 | 88.0 | 239.6 | 175.3 | 7.6 | 938.9 | 646.0 | 0.0 | 20.0 | 50.50 |
102 | 297.1 | 40.9 | 239.9 | 194.0 | 7.5 | 908.9 | 651.8 | 27.5 | 67.0 | 49.17 |
103 | 348.7 | 0.1 | 223.1 | 208.5 | 9.6 | 786.2 | 758.1 | 29.0 | 78.0 | 48.77 |
103 rows × 10 columns
Lisons la description de la source des données. Ici, les 7 colonnes de gauche sont considérées comme des variables explicatives, et la colonne la plus à droite est considérée comme la variable objective.
X = df.iloc[:, :-3].apply(lambda x: (x-x.min())/(x.max() - x.min()), axis=0)
y = df.iloc[:, -1]
#Méthode d'importation à diviser en données d'entraînement et données de test
from sklearn.model_selection import train_test_split
#Vers les données d'entraînement / les données de test 6:Divisé au hasard par un rapport de 4
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
Essayons le modèle de régression le plus simple, la régression linéaire multiple.
from sklearn.linear_model import LinearRegression
regressor = LinearRegression() #Régression multiple linéaire
regressor.fit(X_train, y_train) #Apprentissage
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
Dans le modèle de régression scikit-learn, une méthode appelée .score () calcule le facteur de décision (valeur R2). La valeur R2 est
C'est calculé comme ça. Donc,
Il y a une fonctionnalité.
Maintenant, vérifions les performances avec l'ensemble de test après l'apprentissage avec l'ensemble de l'enseignant.
regressor.score(X_train, y_train), regressor.score(X_test, y_test)
(0.9224703183565424, 0.8177828980042425)
La prédiction peut être faite en remplaçant les données non utilisées pour l'apprentissage dans le modèle de régression obtenu.
Le tracé de la variable objectif et sa valeur prédite est communément appelé le tracé y-y (bien qu'il ne semble pas être le nom officiel). Plus le graphique est diagonal, meilleur est le modèle de régression.
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test) #Données de remplacement non utilisées pour la formation
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.8177828980042425
RMSE= 3.0139396734524633
MAE= 2.4622169354183447
scikit-learn fournit des méthodes pour calculer les indicateurs suivants pour l'évaluation des performances des modèles de régression.
sklearn.metrics.r2_score
La valeur R2 décrite précédemment. Un modèle de régression qui prend une valeur plus grande (une valeur plus proche de 1) est un meilleur modèle.
sklearn.metrics.mean_squared_error
L'erreur quadratique moyenne est la somme des carrés de l'écart entre la variable objectif et la valeur prédite. RMSE (Root Mean Square Error) est la racine carrée de ceci. Les formules sont similaires respectivement à la variance et à l'écart type. Un modèle de régression qui prend une valeur plus petite (une valeur plus proche de 0) est un meilleur modèle.
sklearn.metrics.mean_absolute_error
L'erreur absolue moyenne est la somme des valeurs absolues de l'écart entre la variable objectif et la valeur prédite. Étant donné que l'erreur quadratique moyenne équivaut à l'erreur, l'erreur absolue moyenne n'a pas tendance à le faire, alors qu'elle a tendance à mettre l'accent sur les erreurs importantes. Un modèle de régression qui prend une valeur plus petite (une valeur plus proche de 0) est un meilleur modèle.
PLS (Partial Least Squares)
La régression partielle des moindres carrés (PLS) est un type de méthode de régression linéaire qui renvoie à l'aide de variables (variables latentes) qui sont linéairement transformées à partir de variables explicatives afin qu'elles ne soient pas corrélées les unes aux autres. Par rapport à la régression multiple linéaire normale
Il a l'avantage de.
#Méthode d'importation à diviser en données d'entraînement et données de test
from sklearn.model_selection import train_test_split
#Vers les données d'entraînement / les données de test 6:Divisé au hasard par un rapport de 4
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
from sklearn.cross_decomposition import PLSRegression #Méthode pour effectuer une régression PLS
regressor = PLSRegression() #Génération d'appareils de récupération
regressor.fit(X_train, y_train) #Apprentissage
PLSRegression(copy=True, max_iter=500, n_components=2, scale=True, tol=1e-06)
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.7649827980366806
RMSE= 3.523505754210429
MAE= 2.8524226793359198
Affinons les paramètres et créons un meilleur modèle.
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Paramètres pour effectuer une recherche de grille
parameters = [
{'n_components': [2, 3, 4, 5, 6], 'scale':[True, False], 'max_iter': [1000]},
]
#Exécution de la recherche de grille
regressor = GridSearchCV(PLSRegression(), parameters, cv=3, n_jobs=-1)
regressor.fit(X_train, y_train)
print("R2 (train): ", regressor.score(X_train, y_train))
print("R2 (test): ", regressor.score(X_test, y_test))
print(regressor.best_estimator_) #Modèle de régression avec les meilleurs paramètres
R2 (train): 0.9225247360485105
R2 (test): 0.8162623239997147
PLSRegression(copy=True, max_iter=1000, n_components=3, scale=False, tol=1e-06)
CPU times: user 114 ms, sys: 30.4 ms, total: 144 ms
Wall time: 2.18 s
Faisons une prédiction en utilisant le modèle de régression obtenu. Les performances de prédiction se sont-elles améliorées?
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.8162623239997147
RMSE= 3.115474987155132
MAE= 2.3005236909984426
Désormais, j'aimerais comparer les performances de différents modèles de régression. Par conséquent, préparons une variable pour enregistrer l'indice d'évaluation.
scores = []
J'ai fait la fonction suivante pour calculer l'indice d'évaluation du modèle de régression collectivement et le stocker dans la variable pour l'enregistrement. Répétez l'entraînement et la validation croisée pour différentes divisions de données et enregistrez leurs performances moyennes, leur écart type et leur temps d'entraînement.
import timeit
import numpy as np
from sklearn import metrics
def record_regression_scores(regressor_name, regressor, iter=5):
records = []
run_id = 0
successful = 0
max_trial = 100
while successful < iter:
run_id += 1
if run_id >= max_trial:
break
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
print('Run ', run_id)
seconds = timeit.timeit(lambda: regressor.fit(X_train, y_train), number=1)
print(' Learning Time (s):', seconds)
y_pred = regressor.predict(X_test)
r2_score = metrics.r2_score(y_test, y_pred)
rmse_score = np.sqrt(metrics.mean_squared_error(y_test, y_pred))
mae_score = metrics.mean_absolute_error(y_test, y_pred)
if r2_score < 0:
print("\t\t encountered negative r2_score")
continue
else:
successful += 1
records.append([regressor_name, r2_score, rmse_score, mae_score, seconds])
return records
Maintenant, apprenons à utiliser le «modèle de régression avec les meilleurs paramètres» créé précédemment et enregistrons l'indice d'évaluation des performances.
%%time
scores += record_regression_scores("PLS", regressor)
Run 1
Learning Time (s): 2.0181297670001186
Run 2
Learning Time (s): 1.9526900320001914
Run 3
Learning Time (s): 1.9921050099997046
Run 4
Learning Time (s): 2.0573012720001316
Run 5
Learning Time (s): 1.979584856999736
CPU times: user 552 ms, sys: 101 ms, total: 653 ms
Wall time: 10 s
La performance moyenne et son écart type sont les suivants.
df_scores = pd.DataFrame(scores, columns = ['Regressor', 'R2', 'RMSE', 'Mae', 'Time'])
df_scores_mean = df_scores.iloc[:, :-1].mean()
df_scores_errors = df_scores.iloc[:, :-1].std()
df_scores_mean.plot(kind='bar', grid=True, yerr=df_scores_errors)
<matplotlib.axes._subplots.AxesSubplot at 0x7ff0177f0550>
Nous avons classé par amplification de gradient plus tôt, mais vous pouvez également revenir par augmentation de gradient.
#Méthode d'importation à diviser en données d'entraînement et données de test
from sklearn.model_selection import train_test_split
#Vers les données d'entraînement / les données de test 6:Divisé au hasard par un rapport de 4
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
from sklearn.ensemble import GradientBoostingRegressor
regressor = GradientBoostingRegressor() #Augmentation du gradient
regressor.fit(X_train, y_train) #Apprentissage
GradientBoostingRegressor(alpha=0.9, criterion='friedman_mse', init=None,
learning_rate=0.1, loss='ls', max_depth=3,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_iter_no_change=None, presort='auto',
random_state=None, subsample=1.0, tol=0.0001,
validation_fraction=0.1, verbose=0, warm_start=False)
regressor.score(X_train, y_train), regressor.score(X_test, y_test)
(0.9996743754326906, 0.7386973055974495)
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.7386973055974495
RMSE= 4.012901982806575
MAE= 3.0486670616108
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Augmentation du gradient
from sklearn.ensemble import GradientBoostingRegressor
#Paramètres pour effectuer une recherche de grille
parameters = [{
'learning_rate':[0.1,0.2],
'n_estimators':[20,100],
'max_depth':[3,5]
}]
#Exécution de la recherche de grille
regressor = GridSearchCV(GradientBoostingRegressor(), parameters, cv=3, n_jobs=-1)
regressor.fit(X_train, y_train)
print("R2 (train): ", regressor.score(X_train, y_train))
print("R2 (test): ", regressor.score(X_test, y_test))
print(regressor.best_estimator_) #Modèle de régression avec les meilleurs paramètres
R2 (train): 0.9996743754326906
R2 (test): 0.7195388936429337
GradientBoostingRegressor(alpha=0.9, criterion='friedman_mse', init=None,
learning_rate=0.1, loss='ls', max_depth=3,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_iter_no_change=None, presort='auto',
random_state=None, subsample=1.0, tol=0.0001,
validation_fraction=0.1, verbose=0, warm_start=False)
CPU times: user 130 ms, sys: 15.4 ms, total: 145 ms
Wall time: 2.26 s
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.7195388936429337
RMSE= 4.15741070004397
MAE= 3.0704656592653317
%%time
scores += record_regression_scores("GB", regressor.best_estimator_)
Run 1
Learning Time (s): 0.027196151000225655
Run 2
Learning Time (s): 0.01961764999987281
Run 3
Learning Time (s): 0.01894888400011041
Run 4
Learning Time (s): 0.019140249999964
Run 5
Learning Time (s): 0.020592135999777383
CPU times: user 123 ms, sys: 2.75 ms, total: 126 ms
Wall time: 128 ms
J'ai créé une fonction pour visualiser la comparaison des performances de plusieurs méthodes de régression.
def visualize_regression_result(scores):
df_scores = pd.DataFrame(scores, columns =['Regressor', 'R2', 'RMSE', 'MAE', 'Time'])
df_scores_mean = df_scores.iloc[:, :-1].groupby('Regressor').mean()
df_scores_errors = df_scores.iloc[:, :-1].groupby('Regressor').std()
df_scores_mean.T.plot(kind='bar', grid=True, yerr=df_scores_errors.T,
figsize=(12, 2), legend=False)
#plt.yscale('log')
plt.legend(loc = 'right', bbox_to_anchor = (0.7, 0.5, 0.5, 0.0))
df_scores_mean.plot(kind='bar', grid=True, yerr=df_scores_errors,
figsize=(12, 2), legend=False)
#plt.yscale('log')
plt.legend(loc = 'right', bbox_to_anchor = (0.7, 0.5, 0.5, 0.0))
df_time_mean = df_scores.iloc[:, [0, -1]].groupby('Regressor').mean()
df_time_errors = df_scores.iloc[:, [0, -1]].groupby('Regressor').std()
df_time_mean.plot(kind='bar', grid=True, yerr=df_time_errors,
figsize=(12, 2), legend=False)
plt.yscale('log')
visualize_regression_result(scores)
Nous avons classé par perceptron multicouche plus tôt, mais vous pouvez également revenir par perceptron multicouche.
#Méthode d'importation à diviser en données d'entraînement et données de test
from sklearn.model_selection import train_test_split
#Vers les données d'entraînement / les données de test 6:Divisé au hasard par un rapport de 4
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4)
from sklearn.neural_network import MLPRegressor
regressor = MLPRegressor() #Génération d'appareils de récupération
regressor.fit(X_train, y_train) #Apprentissage
/usr/local/lib/python3.6/dist-packages/sklearn/neural_network/multilayer_perceptron.py:566: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (200) reached and the optimization hasn't converged yet.
% self.max_iter, ConvergenceWarning)
MLPRegressor(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
beta_2=0.999, early_stopping=False, epsilon=1e-08,
hidden_layer_sizes=(100,), learning_rate='constant',
learning_rate_init=0.001, max_iter=200, momentum=0.9,
n_iter_no_change=10, nesterovs_momentum=True, power_t=0.5,
random_state=None, shuffle=True, solver='adam', tol=0.0001,
validation_fraction=0.1, verbose=False, warm_start=False)
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= -4.0467411800805415
RMSE= 19.21649631146132
MAE= 17.449687389239205
%%time
#Recherche de grille pour trouver les meilleurs paramètres
from sklearn.model_selection import GridSearchCV
#Paramètres pour effectuer une recherche de grille
parameters = [{
'hidden_layer_sizes': [10, (10, 10)],
'solver': ['sgd', 'adam', 'lbfgs'],
#'solver': ['lbfgs'],
#'activation': ['logistic', 'tanh', 'relu']
'activation': ['relu']
}]
#Exécution de la recherche de grille
regressor = GridSearchCV(MLPRegressor(max_iter=10000, early_stopping=True),
parameters, cv=3, n_jobs=-1)
regressor.fit(X_train, y_train)
print("R2 (train): ", regressor.score(X_train, y_train))
print("R2 (test): ", regressor.score(X_test, y_test))
print(regressor.best_estimator_) #Modèle de régression avec les meilleurs paramètres
R2 (train): 0.9742637037080083
R2 (test): 0.9562295568855493
MLPRegressor(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
beta_2=0.999, early_stopping=True, epsilon=1e-08,
hidden_layer_sizes=(10, 10), learning_rate='constant',
learning_rate_init=0.001, max_iter=10000, momentum=0.9,
n_iter_no_change=10, nesterovs_momentum=True, power_t=0.5,
random_state=None, shuffle=True, solver='lbfgs', tol=0.0001,
validation_fraction=0.1, verbose=False, warm_start=False)
CPU times: user 222 ms, sys: 17.5 ms, total: 239 ms
Wall time: 7.86 s
import numpy as np
import sklearn.metrics as metrics
y_pred = regressor.predict(X_test)
print("R2=", metrics.r2_score(y_test, y_pred))
print("RMSE=", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print("MAE=", metrics.mean_absolute_error(y_test, y_pred))
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(4,4))
plt.scatter(y_test, y_pred, alpha=0.2, c="blue")
plt.plot([y.min(), y.max()], [y.min(), y.max()], c="black")
plt.grid()
plt.xlabel("Real Y")
plt.ylabel("Predicted Y")
plt.show()
R2= 0.9562295568855493
RMSE= 1.789613149534058
MAE= 1.3873465536350154
%%time
scores += record_regression_scores("MLP", regressor.best_estimator_)
Run 1
Learning Time (s): 0.06779548599979535
Run 2
Learning Time (s): 0.1298420270004499
Run 3
Learning Time (s): 0.1824235089998183
Run 4
Learning Time (s): 0.43246253200004503
Run 5
Learning Time (s): 0.22879209799975797
CPU times: user 1.06 s, sys: 3.13 ms, total: 1.06 s
Wall time: 1.07 s
visualize_regression_result(scores)
scikit-learn fournit l'ensemble de données sur le diabète sous forme de données d'entraînement pour l'apprentissage automatique. Divisez l'ensemble de données en variables explicatives et en variables objectives comme suit, et comparez les performances en retraçant les données de diabète avec MLPRegressor et GradientBoostingRegressor tout en ajustant les paramètres avec GridSearchCV.
# https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_diabetes.html
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
X = diabetes.data
y = diabetes.target