[PYTHON] Lerne japanische Textkategorien mit tf-idf und Random Forest ~ [Tuning]

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.

Zu verwendender Code

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

Ergebnis

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.

Beschränken Sie Teilwörter nur auf die Nomenklatur

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

Ergebnis

Dataset Score
Training 1.0
Test 0.918

Die Identifikationsrate der Testdaten hat sich auf 91,8% verbessert.

Erhöhen Sie max_features in einer zufälligen Gesamtstruktur

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)

Ergebnis

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.

Verwenden Sie oob_score

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)

Ergebnis

Dataset Score
Training 1.0
Test 0.948

In diesem Fall war es besser, mit oob_score = True abzustimmen.

Zusammenfassung

Vor dem Einstellen waren es 90,1%, aber schließlich verbesserte sich die Identifikationsrate auf 94,8%.

Recommended Posts

Lerne japanische Textkategorien mit tf-idf und Random Forest ~ [Tuning]
Lernen Sie japanische Textkategorien mit tf-idf und Random Forest ~ livingoor News
Random Forest (Klassifizierung) und Hyperparameter-Tuning
Entscheidungsbaum und zufälliger Wald
Sprechen Sie japanischen Text mit OpenJTalk + Python
Unüberwachte Textklassifizierung mit Doc2Vec und k-means
Multi-Label-Klassifizierung nach Random Forest mit Scikit-Learn
Extrahieren Sie japanischen Text aus PDF mit PDFMiner