[PYTHON] Amélioration de la metrix de performance par modèle d'apprentissage en 2 étapes

1. Cet article est

Ceci est une explication des moyens d'améliorer le score F1 en introduisant un modèle d'apprentissage en deux étapes dans un dispositif de jugement binaire qui juge les données d'entrée comme des valeurs binaires de 0 et 1. </ b>

Supposons que vous souhaitiez créer un dispositif de jugement binaire qui juge les données d'entrée comme des valeurs binaires de 0 et 1. Le modèle d'appareil de jugement binaire fournit des données d'entraînement pour l'entraînement.

117.JPG

Ici, après avoir donné les données d'apprentissage comme indiqué ci-dessous et modélisé le dispositif de détermination 1, le résultat de sortie du dispositif de détermination 1 est ajouté aux données d'apprentissage pour modéliser le dispositif de détermination 2. Le dispositif de jugement 2 a un plus petit nombre de faux positifs que le dispositif de jugement 1, de sorte que le score F1 est amélioré.

118.JPG

2. Contenu

2-1 Préparer et traiter les données

[1] Importez 10 (0-9) numéros manuscrits 28 bits x 28 bits image noir et blanc, 60 000 données d'image d'entraînement, 10 000 données d'image de test.

sample.py


from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train / 255.0 #Divisez par 255 et effectuez la normalisation.
x_test = x_test / 255.0   #Divisez par 255 et effectuez la normalisation.

x_train est un caractère manuscrit 28x28 bits affiché avec 0,1. y_train est le nombre représenté par des caractères manuscrits.

Résultat de l’exécution </ b> x_train taille-> (60000, 28, 28) x_train est un caractère manuscrit 28x28 bits affiché avec 0,1 108.JPG

y_train-> Le nombre représenté par des caractères manuscrits. (Taille 60000) [5 0 4 ... 5 6 8]

[2] Extraire les données correspondant à "3" ou "5" à partir des données de x_train, y_train, x_test, y_test. -> x_sub_train, x_sub_test

sample.py


# Change these params if you want to change the numbers selected
num1 = 3
num2 = 5


# Subset on only two numbers: x_Dans les données du train, y_train=Retirez celui qui correspond à 3 ou 5.
x_sub_train = x_train[(y_train == num1) | (y_train == num2)]
y_sub_train = y_train[(y_train == num1) | (y_train == num2)]

# Subset on only two numbers: x_Dans les données de test, y_test=Retirez celui qui correspond à 3 ou 5.
x_sub_test = x_test[(y_test == num1) | (y_test == num2)]
y_sub_test = y_test[(y_test == num1) | (y_test == num2)]

[3] Effectuez une conversion de format de données (conversion dimensionnelle).

sample.py


#Données 3D(11552,28,28)Données 2D(11552,28*28)Convertir en.
x_train_flat = x_sub_train.flatten().reshape(x_sub_train.shape[0], 28*28)
#Données 3D(1902,28,28)Données 2D(1902,28*28)Convertir en.
x_test_flat = x_sub_test.flatten().reshape(x_sub_test.shape[0], 28*28)

# One hot encode target variables
#y_sub_Quand l'élément de train est 3->Renvoie 1. à_1 par catégorie->[0,1]Convertir en.
#y_sub_Quand l'élément de train est 5->Renvoie 0. à_0 par catégorie->[1,0]Convertir en.
y_sub_train_encoded = to_categorical([1 if value == num1 else 0 for value in y_sub_train])

#Divisez le groupe de données en données d'entraînement et données de test.
X_train, X_val, Y_train, Y_val = train_test_split(x_train_flat, y_sub_train_encoded, test_size = 0.1, random_state=42)

109.JPG

2-3 Construire le premier modèle d'apprentissage (ML primaire)

Construisez le premier modèle d'apprentissage. Le modèle d'apprentissage est construit à l'aide du réseau neuronal de la bibliothèque Keras.

sample.py


# Build primary model
model = Sequential()
model.add(Dense(units=2, activation='softmax')) 
#unités ・ ・ ・ Nombre de sorties
#activation ・ ・ ・ Fonction d'activation.(https://keras.io/ja/activations/#relu)

#Spécifiez la fonction de perte. Ici, catégorique_crossentropy
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

model.fit(x=X_train, y=Y_train, validation_data=(X_val, Y_val), epochs=3, batch_size=320) # batch size is so large so that the model can be poorly fit, Its easy to get 99% accuracy.
#L'argument epochs est x_Spécifiez le nombre de fois pour réapprendre le bloc avec toutes les données d'entrée du train en un seul bloc.
#batch_la taille est x_Il est donné lorsque le train est subdivisé. Un ensemble divisé en petits morceaux est appelé un "sous-lot". Ceci afin d'éviter le «surapprentissage»

(Informations de référence) http://marupeke296.com/IKDADV_DL_No2_Keras.html

2-4 Évaluer le premier modèle d'apprentissage (réseau neuronal) construit.

Construisez un modèle de réseau neuronal et tracez une courbe ROC.

sample.py


 # Plot ROC
print('X_train','\n',X_train,len(X_train)) #length:10396

prediction = model.predict(X_train) #prediction:Sortie de réseau neuronal
print('prediction','\n',prediction,len(prediction))#length:10396 [Probabilité de 3,Probabilité de 5]Aligné dans

prediction = np.array([i[1] for i in prediction]) #J'obtiens une probabilité de 5.
print('prediction','\n',prediction,len(prediction))#length:10396

print('Y_train','\n',Y_train) #[0,1] or [1,0]
actual = np.array([i[1] for i in Y_train]) == 1

plot_roc(actual, prediction)

def plot_roc(actual, prediction):
    # Calculate ROC / AUC
    fpr, tpr, thresholds = sk_metrics.roc_curve(actual, prediction, pos_label=1)
    roc_auc = sk_metrics.auc(fpr, tpr)

    # Plot
    plt.plot(fpr, tpr, color='darkorange',
             lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
    plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver Operating Characteristic Example')
    plt.legend(loc="lower right")
    plt.show()

Comme la courbe ROC est dessinée dans la zone au-dessus de la moitié, on peut voir qu'un bon modèle d'apprentissage automatique de classification binaire peut être construit. 111.JPG

Ajustez le seuil de sorte que le rappel = 0,99.

sample.py


# Create a model with high recall, change the threshold until a good recall level is reached
threshold = .30

print(prediction) #J'obtiens une probabilité de 5.

prediction_int = np.array(prediction) > threshold #prediction_int -> [False,True,.....]
print("prediction_int",prediction_int)

# Classification report
print(sk_metrics.classification_report(actual, prediction_int))

# Confusion matrix
cm = sk_metrics.confusion_matrix(actual, prediction_int)
print('Confusion Matrix')
print(cm)

112.JPG

2-5 Construire un deuxième modèle d'apprentissage (réseau neuronal).

・ Sortie du 1er modèle + X_Train → Entrée des données du train pour la construction du 2ème modèle ・ Sortie du 1er modèle & Y_Train → Sortie des données du train pour la construction du 2ème modèle.

Augmentez le score F1 en excluant les faux positifs une fois que la plupart des cas positifs ont déjà été identifiés par le modèle principal. En d'autres termes, le rôle de l'algorithme secondaire d'apprentissage automatique est de déterminer si le jugement positif du modèle principal est vrai ou faux.

113.JPG

sample.py


# Get meta labels
meta_labels = prediction_int & actual

print("prediction_int",prediction_int) #[False True True ...]
print("meta_labels",meta_labels) #[False True True ...]

meta_labels_encoded = to_categorical(meta_labels) #[1,0] [0,1] [0,1],....
print(meta_labels_encoded)

# Reshape data
prediction_int = prediction_int.reshape((-1, 1))#[1,0]->[False], [0,1]->[True]Convertir en
print("prediction_int",prediction_int)  #[False],[True],[True],....
print("X_train", X_train) #28*28 [0,0,....0]

#concaténer concaténer des tableaux
# MNIST data + forecasts_int
new_features = np.concatenate((prediction_int, X_train), axis=1)
print("new_features",new_features ) #[1. 0. 0. ... 0. 0. 0.],....

# Train a new model 
# Build model
meta_model = Sequential()
meta_model.add(Dense(units=2, activation='softmax'))

meta_model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

#new_features=MNIST data + forecasts_int -> [1. 0. 0. ... 0. 0. 0.],[1. 0. 0. ... 0. 0. 0.],・ ・ ・
#meta_labels_encoded =[1,0] [0,1] [0,1],....
# x_train and y_train are Numpy arrays --just like in the Scikit-Learn API.
meta_model.fit(x=new_features, y=meta_labels_encoded, epochs=4, batch_size=32)

2-6 Évaluer le deuxième modèle d'apprentissage.

Les données X_Train ont été placées dans le premier modèle d'apprentissage (réseau neuronal) et le deuxième modèle d'apprentissage (réseau neuronal) pour obtenir des données de prédiction. Je les ai comparés avec Y_Train et j'ai sorti un rapport de classification. Il a été constaté que le deuxième modèle d'apprentissage (réseau neuronal) a amélioré la précision par rapport au premier modèle d'apprentissage (réseau neuronal).

114.JPG

sample.py



test_meta_label(primary_model=model, secondary_model=meta_model, x=X_train, y=Y_train, threshold=threshold)

def test_meta_label(primary_model, secondary_model, x, y, threshold):
    """
    :param primary_model: model object (First, we build a model that achieves high recall, even if the precision is not particularly high)
    :param secondary_model: model object (the role of the secondary ML algorithm is to determine whether a positive from the primary (exogenous) model
                            is true or false. It is not its purpose to come up with a betting opportunity. Its purpose is to determine whether
                            we should act or pass on the opportunity that has been presented.)
    :param x: Explanatory variables
    :param y: Target variable (One hot encoded)
    :param threshold: The confidence threshold. This is used
    :return: Print the classification report for both the base model and the meta model.
    """
    # Get the actual labels (y) from the encoded y labels
    actual = np.array([i[1] for i in y]) == 1

    # Use primary model to score the data x
    primary_prediction = primary_model.predict(x)
    primary_prediction = np.array([i[1] for i in primary_prediction]).reshape((-1, 1))
    primary_prediction_int = primary_prediction > threshold # binary labels

    # Print output for base model
    print('Base Model Metrics:')
    print(sk_metrics.classification_report(actual, primary_prediction > 0.50))
    print('Confusion Matrix')
    print(sk_metrics.confusion_matrix(actual, primary_prediction_int))
    accuracy = (actual == primary_prediction_int.flatten()).sum() / actual.shape[0]
    print('Accuracy: ', round(accuracy, 4))
    print('')

    # Secondary model
    new_features = np.concatenate((primary_prediction_int, x), axis=1)

    # Use secondary model to score the new features
    meta_prediction = secondary_model.predict(new_features)
    meta_prediction = np.array([i[1] for i in meta_prediction])
    meta_prediction_int = meta_prediction > 0.5 # binary labels

    # Now combine primary and secondary model in a final prediction
    final_prediction = (meta_prediction_int & primary_prediction_int.flatten())

    # Print output for meta model
    print('Meta Label Metrics: ')
    print(sk_metrics.classification_report(actual, final_prediction))
    print('Confusion Matrix')
    print(sk_metrics.confusion_matrix(actual, final_prediction))
    accuracy = (actual == final_prediction).sum() / actual.shape[0]
    print('Accuracy: ', round(accuracy, 4))    

Il a été constaté que la précision du deuxième réseau neuronal était améliorée même lorsque les données de test réelles étaient utilisées à la place des données d'entraînement.

sample.py


test_meta_label(primary_model=model, secondary_model=meta_model, x=X_val, y=Y_val, threshold=threshold)

116.JPG

Recommended Posts