Japanische Textkategorien mit tf-idf und zufälligen Forest ~ Livedoor-Nachrichten lernen scheint Raum für Optimierungen zu haben, versuchen Sie also Ihr Bestes Ich werde.
Es ist das gleiche wie im vorherigen Artikel.
import glob
import random
import numpy as np
from natto import MeCab
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
def load_livedoor_news_corpus():
category = {
'dokujo-tsushin': 1,
'it-life-hack':2,
'kaden-channel': 3,
'livedoor-homme': 4,
'movie-enter': 5,
'peachy': 6,
'smax': 7,
'sports-watch': 8,
'topic-news':9
}
docs = []
labels = []
for c_name, c_id in category.items():
files = glob.glob("./text/{c_name}/{c_name}*.txt".format(c_name=c_name))
text = ''
for file in files:
with open(file, 'r') as f:
lines = f.read().splitlines()
url = lines[0]
datetime = lines[1]
subject = lines[2]
body = "\n".join(lines[3:])
text = subject + "\n" + body
docs.append(text)
labels.append(c_id)
return docs, labels
docs, labels = load_livedoor_news_corpus()
random.seed()
indices = list(range(len(docs)))
random.shuffle(indices)
split_size = 7000
train_data = [docs[i] for i in indices[0:split_size]]
train_labels = [labels[i] for i in indices[0:split_size]]
test_data = [docs[i] for i in indices[split_size:]]
test_labels = [labels[i] for i in indices[split_size:]]
def tokenize(text):
tokens = []
with MeCab('-F%f[0],%f[6]') as nm:
for n in nm.parse(text, as_nodes=True):
# ignore any end-of-sentence nodes
if not n.is_eos() and n.is_nor():
klass, word = n.feature.split(',', 1)
if klass in ['Substantiv']:
tokens.append(word)
return tokens
vectorizer = TfidfVectorizer(tokenizer=tokenize)
train_matrix = vectorizer.fit_transform(train_data)
test_matrix = vectorizer.transform(test_data)
clf2 = RandomForestClassifier(n_estimators=100, max_features=3000, oob_score=True)
clf2.fit(train_matrix, train_labels)
print(clf2.score(train_matrix, train_labels))
print(clf2.score(test_matrix, test_labels))
Dataset | Score |
---|---|
Training | 1.0 |
Test | 0.901 |
Da die Identifikationsrate der Trainingsdaten 100% beträgt, scheint es gut, die Teilwörter zu entfernen und die Merkmale zu reduzieren.
def tokenize(text):
tokens = []
with MeCab('-F%f[0],%f[6]') as nm:
for n in nm.parse(text, as_nodes=True):
# ignore any end-of-sentence nodes
if not n.is_eos() and n.is_nor():
klass, word = n.feature.split(',', 1)
if klass in ['Substantiv']:
tokens.append(word)
return tokens
Dataset | Score |
---|---|
Training | 1.0 |
Test | 0.918 |
Die Identifikationsrate der Testdaten hat sich auf 91,8% verbessert.
Gemessen mit der Methode get_feature_names von TfidfVectorizer war die Funktion 31258.
Die max_features von RandomForestClassifier waren standardmäßig sqrt, in diesem Fall 176. Ich denke, das ist zu klein, also werde ich es ein wenig erhöhen.
clf2 = RandomForestClassifier(n_estimators=100, max_features=num_features)
clf2.fit(train_matrix, train_labels)
num_features = 1000
Dataset | Score |
---|---|
Training | 1.0 |
Test | 0.931 |
num_features = 3000
Dataset | Score |
---|---|
Training | 1.0 |
Test | 0.937 |
Die Identifikationsrate der Testdaten hat sich auf 93,7% verbessert.
Im API-Dokument für sklearn heißt es: "Gibt an, ob Out-of-Bag-Beispiele zur Schätzung des Generalisierungsfehlers verwendet werden sollen."
Ich kann nicht verstehen, wie es sich aus dem Dokument verhält. ..
clf2 = RandomForestClassifier(n_estimators=100, max_features=3000, oob_score=True)
clf2.fit(train_matrix, train_labels)
Dataset | Score |
---|---|
Training | 1.0 |
Test | 0.948 |
In diesem Fall war es besser, mit oob_score = True abzustimmen.
Vor dem Einstellen waren es 90,1%, aber schließlich verbesserte sich die Identifikationsrate auf 94,8%.
Recommended Posts