[PYTHON] Ich habe die einfachste Methode zur Klassifizierung von Dokumenten mit mehreren Etiketten ausprobiert

Was ist Dokumentklassifizierung?

Eine der Aufgaben von NLP ist die Klassifizierung von Dokumenten. Es schätzt die Beschriftung für ein beschriftetes Dokument.

Die Klassifizierung von Dokumenten kann je nach Art des dem Dokument beigefügten Etiketts grob in die folgenden zwei Typen unterteilt werden.

Dokumentklassifizierungsmodell

Es gibt viele Möglichkeiten, diese Probleme bei der Dokumentklassifizierung zu lösen. Es gibt die folgenden zwei typischen Methoden. (Ich denke, es gibt andere)

--Erstellen Sie einen Dokumentvektor und klassifizieren Sie ihn nach der Methode des maschinellen Lernens

Ich habe es am einfachsten versucht

Obwohl ich das einfachste gemacht habe, bin ich mir nicht sicher, welches das einfachste ist (hey). Dieses Mal möchte ich an der Methode der SVM (mit linearem Karnel) des Tf-idf-Vektors arbeiten. Tf-idf ist ein Vektor, bei dem die Häufigkeit des Auftretens jedes Wortes in einem Dokument mit der Wichtigkeit dieses Wortes als Element multipliziert wird. Daher ist die Dimension des Dokumentvektors gleich der Anzahl der Vokabeln.

SVM mit linearem Karnel scheint etwas schwierig zu erklären zu sein, deshalb werde ich es weglassen.

Dieses Mal werde ich die in sklearn enthaltene verwenden.

Da das Modell einfach ist (?), Werde ich versuchen, einen etwas komplizierten Korpus zu verwenden (Multi-Label + einige Themen werden jedem Dokument zugewiesen). Der verwendete Korpus ist ein Reuters-Nachrichtenartikel mit etwa 10.000 Dokumenten und 90 Etiketten.

Laden Sie zuerst den Korpus herunter

Laden Sie den Korpus herunter. Das reuters-Korpus ist im Python-Modul nltk enthalten, verwenden Sie es also.

Erstens, wenn nltk nicht enthalten ist

pip install nltk

Geben Sie dann Folgendes in die interaktive Shell von Python ein:

python
>>> import nltk
>>> nltk.download("reuters")

Anschließend wird unter dem Benutzerverzeichnis ein Verzeichnis mit dem Namen nltk_data erstellt, und die Daten befinden sich in diesem Verzeichnis. ____ ist drinnen.

Implementierungscode


import glob
import nltk
import re
import codecs
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk import word_tokenize
from nltk.stem.porter import PorterStemmer
from nltk.corpus import stopwords, reuters
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.svm import SVC
from sklearn.multiclass import OneVsRestClassifier
from sklearn import metrics

path = "../nltk_data/corpora/reuters/"
with open(path+"stopwords") as sw:
    stopwords = [x for x in sw]

#Tokenizer definieren
def tokenize(text):
  min_length = 3
  words = map(lambda word: word.lower(), word_tokenize(text))
  words = [word for word in words if word not in stopwords]
  tokens = (list(map(lambda token: PorterStemmer().stem(token), words)))
  p = re.compile('[a-zA-Z]+');
  filtered_tokens = list(filter (lambda token: p.match(token) and len(token) >= min_length, tokens))
  return filtered_tokens
    
#Abrufen der Dokument-ID und ihrer Kategorie aus Daten
with codecs.open("../nltk_data/corpora/reuters/cats.txt", "r", "utf-8", "ignore") as categories:
    train_docs_id = [line.split(" ")[0][9:] for line in categories if line.split(" ")[0][:9] == 'training/']
    categories.seek(0)
    test_docs_id = [line.split(" ")[0][5:] for line in categories if line.split(" ")[0][:5] == 'test/']
    categories.seek(0)
    train_docs_cat = [line.strip("\n").split(" ")[1:] for line in categories if line.split(" ")[0][:9] == 'training/']
    categories.seek(0)
    test_docs_cat = [line.strip("\n").split(" ")[1:] for line in categories if line.split(" ")[0][:5] == 'test/']

#Dokumente auflisten
train_docs = []
test_docs = []
for num in train_docs_id:
    with codecs.open(path+"training/"+num, "r", "utf-8", "ignore") as doc:
        train_docs.append(" ".join([line.strip(" ") for line in doc.read().split("\n")]))
for num in test_docs_id:
    with codecs.open(path+"test/"+num, "r", "utf-8", "ignore") as doc:
        test_docs.append(" ".join([line.strip(" ") for line in doc.read().split("\n")]))

#Sklearn aus der Dokumentenliste.Generieren Sie einen Dokumentvektor mit TfidfVectorizer
vectorizer = TfidfVectorizer(tokenizer=tokenize)
vectorised_train_documents = vectorizer.fit_transform(train_docs)
vectorised_test_documents = vectorizer.transform(test_docs)

#Binäres Etikett(0 or 1)In einen Vektor von konvertieren
# Transform multilabel labels
mlb = MultiLabelBinarizer()
train_labels = mlb.fit_transform(train_docs_cat)
test_labels = mlb.transform(test_docs_cat)

# Classifier
#Probieren Sie verschiedene Parameter aus
param_list = [0.001, 0.01, 0.1, 0.5, 1, 10, 100]
for C in param_list:
    classifier = OneVsRestClassifier(LinearSVC(C=C, random_state=42))
    classifier.fit(vectorised_train_documents, train_labels)
    predictions = classifier.predict(vectorised_test_documents)
    train_predictions = classifier.predict(vectorised_train_documents)
    ftest = metrics.f1_score(test_labels, predictions, average="macro")
    ftrain = metrics.f1_score(train_labels, train_predictions, average="macro")
    print("parameter       test_f1                 train_f1")
    print("c={}:\t{}\t{}".format(C, ftest, ftrain))  

Das Ausführen des obigen Codes führt zu folgendem Ergebnis:

parameter       test_f1                 train_f1
c=0.001:	0.009727246626471432	0.007884179312750742
c=0.01:	0.02568945815128711	0.02531440097069285
c=0.1:	0.20504347026711428	0.26430270726815386
c=0.5:	0.3908058642922242	0.6699048987962078
c=1:	0.45945765878179573	0.9605946547451458
c=10:	0.5253686991407462	0.9946632502765812
c=100:	0.5312185383446876	0.9949908225328556

Sie lernen nach Herzenslust über. Die gleiche Methode gemäß dem folgenden Papier sollte eine Genauigkeit der zweiten Hälfte von 80% ergeben ... https://www.aclweb.org/anthology/N19-1408/

Wenn jemand weiß, warum es nicht gut ist, lass es mich wissen.

Recommended Posts

Ich habe die einfachste Methode zur Klassifizierung von Dokumenten mit mehreren Etiketten ausprobiert
Ich habe den asynchronen Server von Django 3.0 ausprobiert
Ich habe versucht, die häufig verwendete Implementierungsmethode von pytest-mock zusammenzufassen
Ich habe die einfachste Methode zur Klassifizierung von Dokumenten mit mehreren Etiketten ausprobiert
Starten Sie einen einfachen WEB-Server, der den Header überprüfen kann
[Linux] Ich habe versucht, die sichere Bestätigungsmethode von FQDN (CentOS7) zu überprüfen.
Ich habe die Pivot-Table-Funktion von Pandas ausprobiert
Ich habe die Methode der kleinsten Quadrate in Python ausprobiert
Ich habe versucht, die Trapezform des Bildes zu korrigieren
Ich habe versucht, den Bildfilter von OpenCV zu verwenden
Ich habe versucht, die Texte von Hinatazaka 46 zu vektorisieren!
Ich habe das TensorFlow-Tutorial mit Kommentaren ausgeführt (Textklassifizierung von Filmkritiken).
Ich habe versucht, die Grundform von GPLVM zusammenzufassen
Ich habe das MNIST-Tutorial von tensorflow für Anfänger ausprobiert.
Ich habe versucht, EKG-Daten mit der K-Shape-Methode zu gruppieren
Ich habe versucht, die API von Sakenowa Data Project zu verwenden
Ich habe versucht, die Spacha-Informationen von VTuber zu visualisieren
Ich habe versucht, den negativen Teil von Meros zu löschen
Ich habe versucht, die Methode zur Mittelung der Dollarkosten zu simulieren
Ich habe versucht, die Stimmen der Sprecher zu klassifizieren
Ich habe versucht, den Beispielcode des Ansible-Moduls auszuführen
Ich habe versucht, die String-Operationen von Python zusammenzufassen
Ich habe die Bildklassifizierung von AutoGluon ausprobiert
Ich habe die Changefinder-Bibliothek ausprobiert!
Ich habe versucht, die Entropie des Bildes mit Python zu finden
[Pferderennen] Ich habe versucht, die Stärke des Rennpferdes zu quantifizieren
Ich habe versucht, die Standortinformationen des Odakyu-Busses zu erhalten
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
Ich habe versucht, das CNN-Modell von TensorFlow mit TF-Slim umzugestalten
Ich habe versucht, das Lachproblem mit Keras zu erkennen.
Ich habe versucht, den allgemeinen Kommentar des verdammten Spiels des Jahres morphologisch zu analysieren
[Python] Ich habe versucht, die folgende Beziehung von Twitter zu visualisieren
Ich habe ein wenig versucht, das Verhalten der Zip-Funktion
[Maschinelles Lernen] Ich habe versucht, die Theorie von Adaboost zusammenzufassen
[Python] Ich habe versucht, Daten mit der API von Wikipedia zu sammeln
Ich habe versucht, das lokale Minimum der Goldstein-Preis-Funktion zu bekämpfen
Ich habe versucht, die Yin- und Yang-Klassifikation hololiver Mitglieder durch maschinelles Lernen zu überprüfen
Ich möchte den Namen der ausgeführten Funktion / Methode erhalten
Ich habe versucht, das Ranking des Qiita-Adventskalenders mit Python zu kratzen
[Linux] Ich habe versucht, die Ressourcenbestätigungsbefehle zusammenzufassen
Ich habe das TensorFlow-Tutorial als erstes ausprobiert
Ich habe die Naro-Roman-API 2 ausprobiert
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
Ich habe versucht, das SD-Boot-Image von LicheePi Nano zu erstellen
Ich habe versucht, GrabCut von OpenCV zu verwenden
Ich habe das 2. TensorFlow-Tutorial ausprobiert
Ich habe mir die Metainformationen von BigQuery angesehen und versucht, sie zu verwenden
Ich habe versucht, die Größe des logischen Volumes mit LVM zu erweitern
Ich habe die neuartige API von Naruro ausprobiert
Ich habe versucht, den DNN-Teil von OpenPose mit Chainer-CPU auszuführen
Ich habe versucht, den allgemeinen Zustand der VTuber-Kanalbetrachter zu visualisieren
Ich habe versucht, den Ball zu bewegen
[Satzklassifikation] Ich habe verschiedene Pooling-Methoden von Convolutional Neural Networks ausprobiert
Ich habe versucht, die checkio-API zu verwenden
Ich habe versucht, den Abschnitt zu schätzen.
Ich habe versucht, das Gesichtsbild mit sparse_image_warp von TensorFlow Addons zu transformieren
Ich habe versucht, die Trefferergebnisse von Hachinai mithilfe der Bildverarbeitung zu erhalten
Ich habe versucht, die Altersgruppe und die Ratenverteilung von Atcoder zu visualisieren