Ich habe kürzlich ein Gerücht [notMNIST] gehört (http://yaroslavvb.blogspot.jp/2011/09/notmnist-dataset.html). Ich habe einen Prozess zum Behandeln eines Datensatzes in Python geschrieben, daher werde ich ihn veröffentlichen: erröten:
MNIST ist ein Testdatensatz handgeschriebener Zahlen, den viele Menschen, die maschinelles Lernen lernen, kennen, aber dieser notMNIST ist handgeschrieben. Es ist ein Bilddatensatz von Alphabeten, die in verschiedenen Schriftarten und nicht in Zahlen ausgedrückt werden.
Wenn Sie versuchen, den Inhalt zu visualisieren, wird der folgende Datensatz angezeigt. Die Buchstaben am Bildanfang sind das Alphabet, das das Bild darstellt, und das entsprechende Bild wird angezeigt. Schauen Sie sich die zweite von rechts in der ersten Zeile an. Es sieht überhaupt nicht nach "Ich" aus, es ist ein Haus, oder? Dies: heat_smile: Selbst wenn eine Person eine Zeile sieht, enthält sie verdächtige Daten, aber ich denke, es ist ein sehr interessantes Thema.
Die offizielle Seite von notMNIST ist http://yaroslavvb.blogspot.jp/2011/09/notmnist-dataset.html Also wird eine Person namens Jaroslaw Bulatow gemacht.
Als allererstes http://yaroslavvb.com/upload/notMNIST/ Geh zu und dorthin notMNIST_large.tar.gz Bitte laden Sie die Daten von herunter.
Da es mit tar.gz komprimiert wird, können Sie es gegebenenfalls mit einem Dekomprimierungswerkzeug usw. dekomprimieren notMNIST_large Ordner werden erstellt, und Ordner für jedes Alphabet von A, B, C ... werden in den Unterordnern erstellt. Ich werde den Prozess schreiben, um dies in Python zu lesen. Ich verwende ein Jupyter-Notizbuch. In diesem Fall soll sich die .ipynb-Datei im selben Verzeichnis wie dieser notMNIST_large-Ordner befinden. Stellen Sie für .py sicher, dass die .py-Datei ebenfalls im selben Verzeichnis erstellt wird.
Der Codesatz wird auch auf [Github] hochgeladen (https://github.com/matsuken92/Qiita_Contents/blob/master/General/load_notMNIST.ipynb), aber ich werde ihn auch hier schreiben.
Installieren Sie verschiedene Bibliotheken,
from __future__ import division
import sys, os, pickle
import numpy as np
import numpy.random as rd
from scipy.misc import imread
import matplotlib.pyplot as plt
%matplotlib inline
Definieren Sie eine Funktion zum Einlegen, eine Funktion zum Anzeigen eines Bildes usw.
image_size = 28
depth = 255
def unpickle(filename):
with open(filename, 'rb') as fo:
_dict = pickle.load(fo)
return _dict
def to_pickle(filename, obj):
with open(filename, 'wb') as f:
#pickle.dump(obj, f, -1)
pickle.Pickler(f, protocol=2).dump(obj)
def count_empty_file(folder):
cnt = 0
for file in os.listdir(folder):
if os.stat(os.path.join(folder, file)).st_size == 0:
cnt += 1
return cnt
Ich möchte das Label als int-Typ speichern, also bereite ein Wörterbuch für die Konvertierung vor.
label_conv = {a: i for a, i in zip('ABCDEFGHIJ', range(10))}
num2alpha = {i: a for i,a in zip(range(10), 'ABCDEFGHIJ')}
Lesen Sie jede Bilddatei im Ordner und speichern Sie sie als numpy ndarray. Bereiten Sie gleichzeitig Etikettendaten mit dem Ordnernamen als Etikett vor. Speichern Sie nach dem Lesen die Bilddaten in "Daten" und die Etikettendaten in "Ziel" im Wörterbuchformat und speichern Sie das Objekt als Datei mit Pickle. Gelegentlich gibt es eine beschädigte Datei mit einer Größe von 0, die nicht gelesen werden kann. Daher ist die Überspringverarbeitung als Gegenmaßnahme für solche Dinge und Dinge enthalten, die Lesefehler verursachen.
#Überprüfen Sie, ob der zu lesende Ordner vorhanden ist
assert os.path.exists('notMNIST_large')
# assert os.path.exists('notMNIST_small') #Wenn Sie klein lesen, stellen Sie es bitte zur Überprüfung wieder her.
for root_dir in ['notMNIST_large']: # ['notMNIST_small', 'notMNIST_large']: #Wenn Sie auch klein verwenden, wählen Sie beide aus
folders = [os.path.join(root_dir, d) for d in sorted(os.listdir(root_dir))
if os.path.isdir(os.path.join(root_dir, d))]
#Machen Sie einen Rahmen
file_cnt = 0
for folder in folders:
label_name = os.path.basename(folder)
file_list = os.listdir(folder)
file_cnt += len(file_list)-count_empty_file(folder)
dataset = np.ndarray(shape=(file_cnt, image_size*image_size), dtype=np.float32)
labels = np.ndarray(shape=(file_cnt), dtype=np.int)
last_num = 0 #Letzter Index des vorherigen Zeichens
for folder in folders:
file_list = os.listdir(folder)
file_cnt = len(file_list)-count_empty_file(folder)
label_name = os.path.basename(folder)
labels[last_num:(last_num+file_cnt)] = label_conv[label_name]
#label = np.array([label_name] * file_cnt)
skip = 0
for i, file in enumerate(file_list):
#Dateigröße 0 überspringen
if os.stat(os.path.join(folder, file)).st_size == 0:
skip += 1
continue
try:
data = imread(os.path.join(folder, file))
data = data.astype(np.float32)
data /= depth # 0-In 1 Daten konvertieren
dataset[last_num+i-skip, :] = data.flatten()
except:
skip += 1
print 'error {}'.format(file)
continue
last_num += i-skip
notmnist = {}
notmnist['data'] = dataset
notmnist['target'] = labels
to_pickle('{}.pkl'.format(root_dir), notmnist)
Wenn Sie es verwenden, entfernen Sie es, lesen Sie die Datei und extrahieren Sie sie als Objekt. Ändern Sie gegebenenfalls den Wertebereich auf 0-1 oder teilen Sie ihn in Trainingsdaten und Validierungsdaten auf.
from sklearn.cross_validation import train_test_split
notmnist = unpickle('notMNIST_large.pkl') #NotMNIST im selben Ordner_large.Angenommen, es enthält pkl.
notmnist_data = notmnist['data']
notmnist_target = notmnist['target']
notmnist_data = notmnist_data.astype(np.float32)
notmnist_target = notmnist_target.astype(np.int32)
notmnist_data /= 255 # 0-In 1 Daten konvertieren
#75 Trainingsdaten%, Verifizierungsdaten mit verbleibender Nummer einstellen
x_train, x_test, y_train, y_test = train_test_split(notmnist_data, notmnist_target)
Wenn Sie visualisieren möchten, wie das geladene Bild aussieht, versuchen Sie den Anzeigevorgang mit der folgenden Funktion.
def draw_digit(digits):
size = 28
plt.figure(figsize=(len(digits)*1.5, 2))
for i, data in enumerate(digits):
plt.subplot(1, len(digits), i+1)
X, Y = np.meshgrid(range(size),range(size))
Z = data[0].reshape(size,size) # convert from vector to 28x28 matrix
Z = Z[::-1,:] # flip vertical
plt.xlim(0,27)
plt.ylim(0,27)
plt.pcolor(X, Y, Z)
plt.gray()
plt.title(num2alpha[data[1]])
plt.tick_params(labelbottom="off")
plt.tick_params(labelleft="off")
plt.show()
Es wird in 10 Zeilen und 10 Spalten angezeigt.
[draw_digit2([[notmnist_data[idx], notmnist_target[idx]] for idx in rd.randint(len(dataset), size=10)]) for i in range(10)]
Da ich es mit viel Mühe gelesen habe, werde ich versuchen, es mit Random Forest zu klassifizieren. (Da die Anzahl der schwachen Lernmaschinen auf 100 eingestellt ist, dauert das Lernen einige Zeit.)
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=100)
clf = clf.fit(x_train, y_train)
Schauen wir uns zunächst die Fehlerquote bei der Neuzuweisung an.
#Neuzuweisungsfehlerrate
pred = clf.predict(x_train)
result = [y==p for y, p in zip(y_train,pred)]
np.sum(result)/len(pred)
out
0.99722555413319358
#Überprüfung der Generalisierungsleistung
pred = clf.predict(x_test)
result = [y==p for y, p in zip(y_test,pred)]
np.sum(result)/len(pred)
Die Generalisierungsleistung ist mit 91% ebenfalls gut.
out
0.91262407487205077
Lassen Sie uns das Ergebnis der Vorhersage visualisieren.
#Ergebnisse visualisieren
rd.seed(123)
[draw_digit([[x_test[idx], y_test[idx], pred[idx]] for idx in rd.randint(len(x_test), size=10)]) for i in range(10)]
Die meisten Menschen können falsche Dinge beantworten, die wahrscheinlich falsch sind, und fast richtige Antworten, die als Alphabete erkannt werden können: smile:
Recommended Posts