Bereiten Sie zunächst handschriftliche numerische Daten vor. Diesmal aus der Aufgabe von Digital Recognizer von Kaggle, Lehrerdaten mit dem Namen train Ich möchte es herunterladen und verwenden.
Da die Gesamtmenge dieser Daten 73 MB beträgt, was eine beträchtliche Datenmenge darstellt, werden wir das einfache Verständnis priorisieren und 20 von jeder Zahl von 0 bis 9 für insgesamt 200 erfassen und verwenden. Bitte laden Sie die aufgenommenen Daten von [hier] herunter (https://www.dropbox.com/s/qos6njxc48zrs3f/train_small.csv?dl=0).
Diese handschriftlichen numerischen Daten sind eine CSV-Datei
8, 0, 0, 0, 128, ... , 54, 23, 0, 0
```Die erste Ziffer ist eine Beschriftung, die angibt, welche Nummer geschrieben wurde, und die nachfolgenden Ziffern sind 28 x 28.=Es folgen numerische Daten für 784 Pixel.
Importieren Sie zunächst die erforderlichen Bibliotheken.
```py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
Anschließend werden die Daten gelesen, in einem Array gespeichert und in der Reihenfolge der Beschriftungen sortiert.
size = 28
raw_data= np.loadtxt('train_small.csv',delimiter=',',skiprows=1)
digit_data = []
for i in range(len(raw_data)):
digit_data.append((raw_data[i,0],raw_data[i,1:785]))
digit_data.sort(key=lambda x: x[0]) # sort array by label
Lassen Sie uns zunächst anzeigen, um welche Art von Bild es sich bei den gelesenen Daten handelt (mit dem Farbdiagramm von matplotlib).
# draw digit images
plt.figure(figsize=(15, 15))
for i in range(len(digit_data)):
X, Y = np.meshgrid(range(size),range(size))
Z = digit_data[i][1].reshape(size,size) # convert from vector to 28x28 matrix
Z = Z[::-1,:] # flip vertical
plt.subplot(10, 20, i+1) # layout 200 cells
plt.xlim(0,27)
plt.ylim(0,27)
plt.pcolor(X, Y, Z)
plt.flag()
plt.gray()
plt.tick_params(labelbottom="off")
plt.tick_params(labelleft="off")
plt.show()
Die 8. Daten von "2" sind erstaunlich, es gibt keine Spur von "2" (lacht) Wenn nicht gesagt wird, dass es sich um "2" handelt, ist es für Menschen möglicherweise nicht möglich, sie zu unterscheiden ... Dies ist der diesmal verwendete Datensatz.
Lassen Sie uns eine Korrelationsmatrix dieser 28x28 = 784 Pixel Bilddaten mit jedem Element als Graustufendichte mit einem 784-dimensionalen Vektor erstellen. Die Frage ist, wie sinnvoll es ist, einfach zu korrelieren, aber ich bin der Meinung, dass eine einfache Methode die Nähe der Bilder in gewissem Maße ausdrücken kann. Da es sich um eine 200x200-Matrix handelt, kann ich sie nicht verstehen, auch wenn es sich um eine Zahl handelt. Daher werde ich sie in einem Diagramm anzeigen, um ein Bild zu erhalten.
Es ist eine ziemlich spektakuläre Grafik (lacht)
Die vollständigen diagonalen Komponenten haben dieselben Daten, daher beträgt die Korrelation 1. Wenn ich es leicht betrachte, habe ich das Gefühl, dass die diagonalen Blöcke (Korrelationskoeffizient zwischen denselben Zahlen) etwas dunkel sind. "1" ist definitiv stark korreliert.
Die Berechnung in Python erfolgt wie folgt.
data_mat = []
# convert list to ndarray
for i in range(len(digit_data)):
label = digit_data[i][0]
data_mat.append(digit_data[i][1])
A = np.array(data_mat)
Z = np.corrcoef(A) # generate correlation matrix
area_size = len(digit_data)
X, Y = np.meshgrid(range(area_size),range(area_size))
Um die Anzeige zu vereinfachen, legen wir einen Schwellenwert fest und zeichnen diejenigen mit einem Korrelationskoeffizienten größer als 0 und diejenigen mit einem Korrelationskoeffizienten kleiner als 1. Ich habe 0,5 und 0,6 als Schwelle gewählt, aber sie sind willkürlich, und ich habe mehrere ausprobiert und diejenigen aufgegriffen, deren diagonale Komponenten zu entstehen begonnen haben. Betrachtet man den Wert 0,6, so scheint es einen großen Unterschied zwischen dem Diagonalblock und den anderen zu geben. Es scheint auch darauf hinzudeuten, dass "9" und "7" ähnlich sind. Es ist ersichtlich, dass "2" eine besonders geringe Korrelation zwischen "2" aufweist.
plt.clf()
plt.figure(figsize=(10, 10))
plt.xlim(0,area_size-1)
plt.ylim(0,area_size-1)
plt.title("Correlation matrix of digit charcter vector. (corr>0.5)")
thresh = .5
Z1 = Z.copy()
Z1[Z1 > thresh] = 1
Z1[Z1 <= thresh] = 0
plt.pcolor(X, Y, Z1, cmap=cm.get_cmap('Blues'),alpha=0.6)
plt.xticks([(i * 20) for i in range(10)],range(10))
plt.yticks([(i * 20) for i in range(10)],range(10))
plt.grid(color='deeppink',linestyle='--')
plt.show()
Lassen Sie uns abschließend den Durchschnittswert für jeden Block in einem 10x10-Diagramm anzeigen.
summary_Z = np.zeros(100).reshape(10,10)
for i in range(10):
for j in range(10):
i1 = i * 20
j1 = j * 20
#print "[%d:%d,%d:%d]" % (i1,i1+20,j1,j1+20)
if i==j:
#Da die diagonale Komponente auf 1 festgelegt ist, nehmen Sie den Durchschnitt ohne ihn, um zu vermeiden, dass der Wert überschritten wird.
summary_Z[i,j] = (np.sum(Z[i1:i1+20,j1:j1+20])-20)/380
else:
summary_Z[i,j] = np.sum(Z[i1:i1+20,j1:j1+20])/400
# average of each digit's grid
plt.clf()
plt.figure(figsize=(10, 10))
plt.xlim(0,10)
plt.ylim(0,10)
sX, sY = np.meshgrid(range(11),range(11))
plt.title("Correlation matrix of summuation of each digit's cell")
plt.xticks(range(10),range(10))
plt.yticks(range(10),range(10))
plt.pcolor(sX, sY, summary_Z, cmap=cm.get_cmap('Blues'),alpha=0.6)
plt.show()
Dieses Mal habe ich eine grobe Analyse in dem Sinne versucht, dass die Bilddaten als 784-dimensionaler Vektor betrachtet werden und die Korrelation so genommen wird, wie sie zwischen den Vektoren ist. Da die Bilddaten jedoch ursprünglich zweidimensional sind, sind die benachbarten Pixel wie oben, unten, links und rechts Ich denke, dass es möglich ist, die plausibelere Nähe zwischen Bildern auszudrücken, indem man die Nähe unter Berücksichtigung des Wertes betrachtet. Es ist noch vor dem maschinellen Lernen in dieser Phase. Die diagonalen Komponenten wurden jedoch korrekt angezeigt. Ich werde als nächsten Schritt in Nächster Artikel etwas Ernsthafteres schreiben.
Recommended Posts