[PYTHON] Verbesserung der Leistungsmetrik durch 2-Stufen-Lernmodell

1. Dieser Artikel ist

Dies ist eine Erklärung der Mittel zur Verbesserung der F1-Bewertung durch Einführung eines zweistufigen Lernmodells in eine binäre Beurteilungsvorrichtung, die Eingabedaten als binäre Werte von 0 und 1 beurteilt. </ b>

Angenommen, Sie möchten ein binäres Beurteilungsgerät erstellen, das Eingabedaten als Binärwerte von 0 und 1 beurteilt. Das Modell der binären Beurteilungsvorrichtung liefert Trainingsdaten für das Training.

117.JPG

Hier wird nach dem Geben von Trainingsdaten wie unten gezeigt und dem Modellieren der Bestimmungsvorrichtung 1 das Ausgabeergebnis der Bestimmungsvorrichtung 1 zu den Trainingsdaten hinzugefügt, um die Bestimmungsvorrichtung 2 zu modellieren. Das Beurteilungsgerät 2 hat eine geringere Anzahl von Fehlalarmen als das Beurteilungsgerät 1, so dass die F1-Bewertung verbessert wird.

118.JPG

2. Inhalt

2-1 Daten vorbereiten und verarbeiten

[1] Importieren Sie 10 (0-9) handgeschriebene Zahlen, 28-Bit x 28-Bit-Schwarzweißbild, 60.000 Trainingsbilddaten, 10.000 Testbilddaten.

sample.py


from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train / 255.0 #Teilen Sie durch 255 und führen Sie eine Normalisierung durch.
x_test = x_test / 255.0   #Teilen Sie durch 255 und führen Sie eine Normalisierung durch.

x_train ist ein handgeschriebenes 28x28bit-Zeichen, das mit 0,1 angezeigt wird. y_train ist die Zahl, die durch handgeschriebene Zeichen dargestellt wird.

Ausführungsergebnis </ b> x_train size-> (60000, 28, 28) x_train ist ein handgeschriebenes 28x28bit-Zeichen, das mit 0,1 angezeigt wird 108.JPG

y_train-> Die Zahl, die durch handgeschriebene Zeichen dargestellt wird. (Größe 60000) [5 0 4 ... 5 6 8]

[2] Extrahiere die Daten, die "3" oder "5" entsprechen, aus den Daten von x_train, y_train, x_test, y_test. -> x_tra_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_In den Zugdaten y_train=Nehmen Sie die heraus, die 3 oder 5 entspricht.
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_In den Testdaten ist y_test=Nehmen Sie die heraus, die 3 oder 5 entspricht.
x_sub_test = x_test[(y_test == num1) | (y_test == num2)]
y_sub_test = y_test[(y_test == num1) | (y_test == num2)]

[3] Datenformatkonvertierung durchführen (Dimensionskonvertierung).

sample.py


#3D-Daten(11552,28,28)2D-Daten(11552,28*28)Konvertieren zu.
x_train_flat = x_sub_train.flatten().reshape(x_sub_train.shape[0], 28*28)
#3D-Daten(1902,28,28)2D-Daten(1902,28*28)Konvertieren zu.
x_test_flat = x_sub_test.flatten().reshape(x_sub_test.shape[0], 28*28)

# One hot encode target variables
#y_sub_Wenn das Element des Zuges 3 ist->Rückgabe 1. zu_1 nach kategorisch->[0,1]Konvertieren zu.
#y_sub_Wenn das Zugelement 5 ist->Gibt 0 zurück. zu_0 nach kategorisch->[1,0]Konvertieren zu.
y_sub_train_encoded = to_categorical([1 if value == num1 else 0 for value in y_sub_train])

#Teilen Sie die Datengruppe in Trainingsdaten und Testdaten auf.
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 Erstellen Sie das erste Lernmodell (Primary ML)

Erstellen Sie das erste Lernmodell. Das Trainingsmodell wird unter Verwendung des neuronalen Netzwerks der Keras-Bibliothek erstellt.

sample.py


# Build primary model
model = Sequential()
model.add(Dense(units=2, activation='softmax')) 
#Einheiten ・ ・ ・ Anzahl der Ausgänge
#Aktivierung ・ ・ ・ Aktivierungsfunktion.(https://keras.io/ja/activations/#relu)

#Geben Sie die Verlustfunktion an. Hier kategorisch_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.
#Das Argument Epochen ist x_Geben Sie an, wie oft der Block mit allen Eingabedaten des Zuges als ein Block neu gelernt werden soll.
#batch_Größe ist x_Es ist gegeben, wenn der Zug unterteilt ist. Ein in kleine Stücke unterteiltes Set wird als "Teilcharge" bezeichnet. Dies soll "Überlernen" verhindern

(Referenzinformationen) http://marupeke296.com/IKDADV_DL_No2_Keras.html

2-4 Bewerten Sie das erste konstruierte Lernmodell (neuronales Netzwerk).

Erstellen Sie ein neuronales Netzwerkmodell und zeichnen Sie eine ROC-Kurve.

sample.py


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

prediction = model.predict(X_train) #prediction:Neuronale Netzwerkausgabe
print('prediction','\n',prediction,len(prediction))#length:10396 [Wahrscheinlichkeit von 3,Wahrscheinlichkeit von 5]Angestellt in

prediction = np.array([i[1] for i in prediction]) #Ich bekomme eine Wahrscheinlichkeit von 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()

Da die ROC-Kurve in dem Bereich über der Hälfte gezeichnet wird, ist ersichtlich, dass ein gutes Modell für maschinelles Lernen mit binärer Klassifizierung konstruiert werden kann. 111.JPG

Stellen Sie den Schwellenwert so ein, dass der Rückruf = 0,99 ist.

sample.py


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

print(prediction) #Ich bekomme eine Wahrscheinlichkeit von 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 Erstellen Sie ein zweites Lernmodell (neuronales Netzwerk).

・ Ausgabe des 1. Modells + X_Train → Zugdateneingabe für den Bau des 2. Modells ・ Ausgabe des 1. Modells & Y_Train → Zugdatenausgabe zum Erstellen des 2. Modells.

Erhöhen Sie den F1-Score, indem Sie falsch positive Ergebnisse ausschließen, nachdem die meisten positiven Fälle bereits vom Primärmodell identifiziert wurden. Mit anderen Worten, die Rolle des sekundären Algorithmus für maschinelles Lernen besteht darin, zu bestimmen, ob die positive Beurteilung durch das primäre Modell wahr oder falsch ist.

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]Konvertieren zu
print("prediction_int",prediction_int)  #[False],[True],[True],....
print("X_train", X_train) #28*28 [0,0,....0]

#verketten verketten Arrays
# 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 Bewerten Sie das zweite Lernmodell.

X_Train-Daten wurden in das erste Trainingsmodell (neuronales Netzwerk) und das zweite Trainingsmodell (neuronales Netzwerk) eingegeben, um Vorhersagedaten zu erhalten. Ich habe sie mit Y_Train verglichen und einen Classfication-Bericht ausgegeben. Es wurde festgestellt, dass das zweite Lernmodell (neuronales Netzwerk) im Vergleich zum ersten Lernmodell (neuronales Netzwerk) eine verbesserte Genauigkeit aufweist.

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))    

Es wurde festgestellt, dass die Genauigkeit des zweiten neuronalen Netzwerks verbessert wurde, selbst wenn die tatsächlichen Testdaten anstelle der Trainingsdaten verwendet wurden.

sample.py


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

116.JPG

Recommended Posts