Reproduzieren Sie das Ausführungsbeispiel von Kapitel 4 von Hajipata in Python

Einführung

Viele Leute werden Erste Mustererkennung als Einführung in maschinelles Lernen lesen. Ich war einer von ihnen, und ich dachte, ich hätte es einmal gelesen und vollständig verstanden, aber wenn ich es noch einmal lese, verstehe ich immer noch nichts [^ 1], also habe ich beschlossen, es während der Implementierung erneut zu lesen. Dieser Artikel fasst den Code zusammen, der das im Buch in Python beschriebene Ausführungsbeispiel reproduziert (die Betriebsumgebung des beschriebenen Codes ist numpy 1.16.2, pandas 0.24.2). Diesmal ist Kapitel 4, "Wahrscheinlichkeitsmodell und Diskriminierungsfunktion".

Ausführungsbeispiel 4.1 Standardisierung

Standardisierung ist die Subtraktion des Durchschnittswertes und die Division durch die Standardabweichung. Unten ist der Code.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
from sklearn.datasets import load_iris

iris = load_iris()
data = pd.DataFrame(iris['data'], columns=iris.feature_names)
target = pd.Series(iris['target']).map({0: 'setosa', 1:'versicolor', 2:'virginica'})
print('mu = ', np.mean(data[['petal length (cm)', 'petal width (cm)']]))
print('Sigma = ', np.cov(data[['petal length (cm)', 'petal width (cm)']], rowvar=0))

#Ausgabe=>
# mu = 
#  petal length (cm)    3.758000
# petal width (cm)     1.199333
# dtype: float64
# Sigma = 
#  [[3.11627785 1.2956094 ]
#  [1.2956094  0.58100626]]
for t in target.unique():
    data_tmp = data[target==t]
    plt.scatter(data_tmp['petal length (cm)'], data_tmp['petal width (cm)'], label=t)
plt.legend()
plt.xlabel('petal length (cm)')
plt.ylabel('petal width (cm')
plt.xlim([1, 7])
plt.ylim([-1, 4])
plt.show()

4-2a.png

def standardize(X):
    return (X - np.mean(X)) / np.std(X)

std_data = standardize(data[['petal length (cm)', 'petal width (cm)']])
for t in target.unique():
    data_tmp = std_data[target==t]
    plt.scatter(data_tmp['petal length (cm)'], data_tmp['petal width (cm)'], label=t)
plt.legend()
plt.xlabel('petal length (cm)')
plt.ylabel('petal width (cm)')
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.show()

4-2b.png

Ausführungsbeispiel 4.2 Nicht korreliert

Rotieren über eine Matrix von Eigenvektoren, das heißt Unkorrelation. Unten ist der Code.

def no_correlation(X):
    cov_mat = np.cov(X, rowvar=0)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    return np.dot(X, eig_vecs)

no_corr_data = no_correlation(data[['petal length (cm)', 'petal width (cm)']])
for t in target.unique():
    data_tmp = no_corr_data[target==t]
    plt.scatter(data_tmp[:, 0], data_tmp[:, 1], label=t)
plt.legend()
plt.xlabel('petal length (cm)')
plt.ylabel('petal width (cm)')
plt.xlim([0, 8])
plt.ylim([-3, 3])
plt.show()

4-3b.png

In diesem Ausführungsbeispiel ist das Vorzeichen der y-Komponente des Eigenvektors gegenüber dem im Buch beschriebenen umgekehrt, sodass auch die Richtung der y-Achse des Streudiagramms umgekehrt ist.

Sigma = np.cov(data[['petal length (cm)', 'petal width (cm)']], rowvar=0)
Lambda, S = np.linalg.eig(Sigma)
print('Lambda = \n', Lambda)
print('S = \n', S)
#Ausgabe=>
# Lambda = 
#  [3.66123805 0.03604607]
# S = 
#  [[ 0.92177769 -0.38771882]
#  [ 0.38771882  0.92177769]]
print('Sigma = \n', np.cov(no_corr_data, rowvar=0))
#Ausgabe=>
# Sigma = 
#  [[3.66123805e+00 6.01365790e-16]
#  [6.01365790e-16 3.60460707e-02]]

Ausführungsbeispiel 4.3 Bleaching

Bleaching ist Zentralisierung, Unkorrelation und Normalisierung der Standardabweichung auf 1. Unten ist der Code.

def whitening(X):
    cov_mat = np.cov(X, rowvar=0)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    diag_sqrt_eig_vals = np.diag(np.sqrt(eig_vals))

    return np.dot(np.dot(X-np.mean(X, axis=0), eig_vecs), np.linalg.inv(diag_sqrt_eig_vals.T))

whitened_data = whitening(data[['petal length (cm)', 'petal width (cm)']])
for t in target.unique():
    data_tmp = whitened_data[target==t]
    plt.scatter(data_tmp[:, 0], data_tmp[:, 1], label=t)
plt.legend()
plt.xlabel('petal length (cm)')
plt.ylabel('petal width (cm)')
plt.xlim([-3, 3])
plt.ylim([-3, 4])
plt.show()

4-6b.png

print('Sigma = \n', np.cov(whitened_data, rowvar=0))
#Ausgabe=>
# Sigma = 
#  [[1.00000000e+00 1.64411249e-15]
#  [1.64411249e-15 1.00000000e+00]]

Ausführungsbeispiel 4.4 Sekundäre Diskriminanzfunktion / lineare Diskriminanzfunktion

Eine Funktion, die eine Klasse identifiziert, vorausgesetzt, dass die klassenbedingten Wahrscheinlichkeiten einer Normalverteilung folgen. Unten ist der Code.

Die Daten stammen aus R-Datensätzen.

pima_train = pd.read_csv('https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/MASS/Pima.tr.csv')
pima_test = pd.read_csv('https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/MASS/Pima.te.csv')
for t in ['Yes', 'No']:
    pima_tmp = pima_train[pima_train['type']==t]
    plt.scatter(pima_tmp['glu'], pima_tmp['bmi'], label=t)
plt.legend()
plt.xlabel('glu')
plt.ylabel('bmi')
plt.xlim([50, 200])
plt.ylim([15, 50])
plt.show()

4-8.png

class QuadraticDiscriminantFunction:
    def __init__(self, threshold=0):
        self._S = None
        self._c = None
        self._F = None
        self._threshold = threshold
    
    def fit(self, X, Y):
        X_pos = X[Y==1]
        X_neg = X[Y==0]

        mu_pos = np.mean(X_pos, axis=0)
        mu_neg = np.mean(X_neg, axis=0)
        Sigma_pos = np.cov(X_pos, rowvar=0)
        Sigma_neg = np.cov(X_neg, rowvar=0)
        p_pos = len(Y[Y==1])/len(Y)
        p_neg = len(Y[Y==0])/len(Y)
        
        self._S = np.linalg.inv(Sigma_pos) - np.linalg.inv(Sigma_neg)
        self._c = np.dot(mu_neg, np.linalg.inv(Sigma_neg)) - np.dot(mu_pos, np.linalg.inv(Sigma_pos))
        self._F = np.dot(np.dot(mu_pos, np.linalg.inv(Sigma_pos)), mu_pos) - np.dot(np.dot(mu_neg, np.linalg.inv(Sigma_neg)), mu_neg)\
                    + np.log(np.linalg.det(Sigma_pos)/np.linalg.det(Sigma_neg))\
                    - 2*np.log(p_pos/p_neg)
    
    def predict(self, X):
        xSx = np.diag(np.dot(np.dot(X, self._S), X.T))
        cx = np.dot(self._c, X.T)
        Y_hat = xSx + 2*cx + self._F
        return np.where(Y_hat < self._threshold, 1, 0)
class LinearDiscriminantFunction:
    def __init__(self, threshold=0):
        self._c = None
        self._F = None
        self._threshold = threshold
    
    def fit(self, X, Y):
        X_pos = X[Y==1]
        X_neg = X[Y==0]

        mu_pos = np.mean(X_pos, axis=0)
        mu_neg = np.mean(X_neg, axis=0)
        Sigma_pos = np.cov(X_pos, rowvar=0)
        Sigma_neg = np.cov(X_neg, rowvar=0)
        p_pos = len(Y[Y==1])/len(Y)
        p_neg = len(Y[Y==0])/len(Y)
        Sigma_pool = p_pos*Sigma_pos + p_neg*Sigma_neg
        
        self._c = np.dot(mu_neg, np.linalg.inv(Sigma_pool)) - np.dot(mu_pos, np.linalg.inv(Sigma_pool))
        self._F = np.dot(np.dot(mu_pos, np.linalg.inv(Sigma_pool)), mu_pos) - np.dot(np.dot(mu_neg, np.linalg.inv(Sigma_pool)), mu_neg)\
                    - 2*np.log(p_pos/p_neg)
    
    def predict(self, X):
        cx = np.dot(self._c, X.T)
        Y_hat = 2*cx + self._F
        return np.where(Y_hat < self._threshold, 1, 0)
X_train = pima_train[['glu', 'bmi']].values
Y_train = pima_train['type'].map({'Yes':1, 'No':0})

qdf = QuadraticDiscriminantFunction(threshold=0)
qdf.fit(X_train, Y_train)
ldf = LinearDiscriminantFunction(threshold=0)
ldf.fit(X_train, Y_train)

X1_min, X1_max = np.min(X_train[:, 0])-1, np.max(X_train[:, 0])+1
X2_min, X2_max = np.min(X_train[:, 1])-1, np.max(X_train[:, 1])+1
X1, X2 = np.meshgrid(np.arange(X1_min, X1_max, 1), np.arange(X2_min, X2_max, 0.5))
X = np.c_[X1.ravel(), X2.ravel()]

Y_qdf_pred = qdf.predict(X)
Y_ldf_pred = ldf.predict(X)
plt.contour(X1, X2, Y_qdf_pred.reshape(X1.shape), colors='limegreen')
for t in ['Yes', 'No']:
    pima_tmp = pima_train[pima_train['type']==t]
    plt.scatter(pima_tmp['glu'], pima_tmp['bmi'], label=t)
plt.legend()
plt.xlabel('glu')
plt.ylabel('bmi')
plt.xlim([50, 200])
plt.ylim([15, 50])
plt.show()

4-9a.png

X_test = pima_test[['glu', 'bmi']].values
Y_test = pima_test['type'].map({'Yes':1, 'No':0})

Y_train_qdf_pred = qdf.predict(X_train)
print('error rate (train) = {:.1f}%'.format(np.mean(Y_train_qdf_pred != Y_train)*100))
Y_test_qdf_pred = qdf.predict(X_test)
print('error rate (test) = {:.1f}%'.format(np.mean(Y_test_qdf_pred != Y_test)*100))

#Ausgabe=>
# error rate (train) = 24.5%
# error rate (test) = 23.8%
plt.contour(X1, X2, Y_ldf_pred.reshape(X1.shape), colors='limegreen')
for t in ['Yes', 'No']:
    pima_tmp = pima_train[pima_train['type']==t]
    plt.scatter(pima_tmp['glu'], pima_tmp['bmi'], label=t)
plt.legend()
plt.xlabel('glu')
plt.ylabel('bmi')
plt.xlim([50, 200])
plt.ylim([15, 50])
plt.show()

4-9b.png

Y_train_ldf_pred = ldf.predict(X_train)
print('error rate (train) = {:.1f}%'.format(np.mean(Y_train_ldf_pred != Y_train)*100))
Y_test_ldf_pred = ldf.predict(X_test)
print('error rate (test) = {:.1f}%'.format(np.mean(Y_test_ldf_pred != Y_test)*100))
#Ausgabe=>
# error rate (train) = 24.0%
# error rate (test) = 22.0%
qdf_tpr_list = []
qdf_fpr_list = []
ldf_tpr_list = []
ldf_fpr_list = []

for th in np.arange(-9, 7, 0.1):
    qdf = QuadraticDiscriminantFunction(threshold=th)
    qdf.fit(X_train, Y_train)
    Y_qdf_pred = qdf.predict(X_test)

    tpr_qdf = len(Y_test[(Y_test==0)&(Y_qdf_pred==0)]) / len(Y_test[Y_test==0])
    qdf_tpr_list.append(tpr_qdf)
    fpr_qdf = len(Y_test[(Y_test==1)&(Y_qdf_pred==0)]) / len(Y_test[Y_test==1])
    qdf_fpr_list.append(fpr_qdf)
                        
    ldf = LinearDiscriminantFunction(threshold=th)
    ldf.fit(X_train, Y_train)
    Y_ldf_pred = ldf.predict(X_test)
    
    tpr_ldf = len(Y_test[(Y_test==0)&(Y_ldf_pred==0)]) / len(Y_test[Y_test==0])
    ldf_tpr_list.append(tpr_ldf)
    fpr_ldf = len(Y_test[(Y_test==1)&(Y_ldf_pred==0)]) / len(Y_test[Y_test==1])
    ldf_fpr_list.append(fpr_ldf)

plt.plot(qdf_fpr_list, qdf_tpr_list, label='Quadratic')
plt.plot(ldf_fpr_list, ldf_tpr_list, label='Linear')
plt.legend()
plt.xlabel('false positive ratio')
plt.ylabel('true positive ratio')
plt.show()

4-10.png

abschließend

Ich habe versucht, das Ausführungsbeispiel von Kapitel 4 von Hajipata in Python zu reproduzieren. Was die Richtigkeit des Codes betrifft, stimmt die gezeichnete Figur ungefähr mit der Figur im Buch überein, also Yoshi! Wir überprüfen nur den Abschluss. Wenn Sie also Fehler finden, würden wir uns freuen, wenn Sie eine Bearbeitungsanfrage stellen könnten.

Recommended Posts

Reproduzieren Sie das Ausführungsbeispiel von Kapitel 4 von Hajipata in Python
Reproduzieren Sie das Ausführungsbeispiel von Kapitel 5 von Hajipata in Python
Lassen Sie uns das Ausführungsergebnis des Programms mit C ++, Java, Python messen.
Überprüfen Sie das Verhalten des Zerstörers in Python
[Python] PCA-Scratch im Beispiel "Einführung in die multivariate Analysemethode"
[Hikari-Python] Kapitel 07-02 Ausnahmebehandlung (Kontinuierliche Ausführung des Programms durch Ausnahmebehandlung)
Grundlagen zum Ausführen von NoxPlayer in Python
Auf der Suche nach dem schnellsten FizzBuzz in Python
Praktisches Beispiel für hexagonale Architektur in Python
Ein Beispiel für die Antwort auf die Referenzfrage der Studiensitzung. Mit Python.
Geben Sie die Anzahl der CPU-Kerne in Python aus
[Python] Sortieren Sie die Liste von pathlib.Path in natürlicher Reihenfolge
Der Inhalt des Python-Tutorials (Kapitel 2) ist in einem Aufzählungszeichen zusammengefasst.
Holen Sie sich den Aufrufer einer Funktion in Python
Zeigen Sie das Ergebnis der Geometrieverarbeitung in Python an
Der Inhalt des Python-Tutorials (Kapitel 8) ist in einem Aufzählungszeichen zusammengefasst.
Der Inhalt des Python-Tutorials (Kapitel 1) ist in einem Aufzählungszeichen zusammengefasst.
Kopieren Sie die Liste in Python
Der Inhalt des Python-Tutorials (Kapitel 10) ist in einem Aufzählungszeichen zusammengefasst.
Finden Sie den Bruchteil des in Python eingegebenen Werts heraus
Finden Sie die Lösung der Gleichung n-ter Ordnung mit Python
Die Geschichte des Lesens von HSPICE-Daten in Python
[Hinweis] Über die Rolle des Unterstrichs "_" in Python
Lösen von Bewegungsgleichungen in Python (odeint)
Ausgabe in Form eines Python-Arrays
Der Inhalt des Python-Tutorials (Kapitel 6) ist in einem Aufzählungszeichen zusammengefasst.
Der Inhalt des Python-Tutorials (Kapitel 3) ist in einem Aufzählungszeichen zusammengefasst.
der Zen von Python
So übergeben Sie das Ergebnis der Ausführung eines Shell-Befehls in einer Liste in Python
Erleben Sie die gute Berechnungseffizienz der Vektorisierung in Python
So ermitteln Sie die Anzahl der Stellen in Python
[Python] Ruft die Liste der im Modul definierten Klassen ab
Ruby, Python-Codefragment Ausführung der Auswahl in Emacs
Die Geschichte von FileNotFound im Python open () -Modus = 'w'
Lernen Sie das Entwurfsmuster "Chain of Responsibility" in Python
Implementieren Sie die Lösung der Riccati-Algebra in Python
Ermitteln Sie die Größe (Anzahl der Elemente) von Union Find in Python
Den Inhalt der Daten in Python nicht kennen
Verwenden wir die offenen Daten von "Mamebus" in Python
Implementierte den Algorithmus von "Algorithm Picture Book" in Python3 (Heap Sort Edition)
[Python] Gibt alle Kombinationen von Elementen in der Liste aus
Rufen Sie die URL des HTTP-Umleitungsziels in Python ab
Ein Memorandum über die Umsetzung von Empfehlungen in Python
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Überprüfen Sie die atrophische Natur der Wahrscheinlichkeitsverteilung in Python
[Python] Kapitel 01-02 Über Python (Ausführung und Installation der Entwicklungsumgebung)
[Beispiel für eine Python-Verbesserung] In 2 Wochen wurden die Grundlagen von Python auf einer kostenlosen Website erlernt
[Maschinelles Lernen] "Erkennung von Abnormalitäten und Erkennung von Änderungen" Zeichnen wir die Abbildung von Kapitel 1 in Python.
Auf dem Weg zum Ruhestand von Python2
Finde Fehler in Python
Objektäquivalenzbeurteilung in Python
Reproduzieren Sie die euklidische Methode der gegenseitigen Teilung in Python
Externe Befehlsausführung in Python
Implementierung der schnellen Sortierung in Python
Über die Funktionen von Python
Die Kraft der Pandas: Python
Versuchen Sie, COVID-19 Tokyo-Daten mit Python zu kratzen
Finden Sie die scheinbare Breite einer Zeichenfolge in Python heraus