[PYTHON] fastText ist ziemlich erstaunlich! "Yahoo! News" Clustering-Lernen ohne Lehrer-

Letztes Mal verwendete die train_supervised-Methode von fastText zum überwachten Lernen und Clustering von Yahoo News-Artikeldaten. Verwenden wir dieses Mal die train_unsupervised-Methode von fastText, um unbeaufsichtigtes Lernen durchzuführen und zu analysieren, ob es so schön wie beim letzten Mal geclustert werden kann.

Entwicklungsumgebung

Implementierungsstart

① Bibliothek laden (2) Erstellen Sie eine Datei mit dem Namen Utility.py, um die bisher erstellten Funktionen zu speichern. Laden Sie von dort aus die Funktionen, die Sie diesmal benötigen. ③ Verwenden Sie die YN-Funktion, um Yahoo News-Artikel abzurufen. Sie können ungefähr 500 Artikel in ungefähr 10 erhalten. Diese Funktion wird unter hier eingeführt.

# ①
import pandas as pd, numpy as np
from sklearn.model_selection import train_test_split
import fasttext
from sklearn import preprocessing
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import japanize_matplotlib
import re
# ②
import utility as util 
wakati = util.wakati
M2A = util.MecabMorphologicalAnalysis
YN = util.YahooNews
cos_sim = util.cos_sim
# ③
df = YN(1000)
# df = pd.read_csv('./YahooNews.csv') #Wenn Sie die Daten bereits erfasst haben, lesen Sie sie und starten Sie die Analyse!
df

[===================] 502 Artikel

title category text
0 Umzug in eine Holdinggesellschaft in Pana 22 Wirtschaft Bloomberg Panasonic gab am 13. bekannt, dass es ab April 2022 zu einer Holdingstruktur wechseln wird ...
1 Über 1700 Menschen sind landesweit infiziert, die höchste Zahl aller Zeiten Inland Nippon News Network NNN Die neue infizierte Person des neuen Corona-Virus am 13. Tag ist N ...
2 Makos Ehe-Respekt für ihre Majestäten Inland Das Miyauchi-Büro wird mit Mako Akishino, der ältesten Tochter von Herrn und Frau Akishino, und Kei Komuro, einer Klassenkameradin aus der Zeit auf der Intensivstation der International Christian University, 29 ... , zusammen sein
3 Mr. Trumps Rat ist geteilt International CNN-Präsident Trump, der bei den US-Präsidentschaftswahlen mit Sicherheit besiegt wird, plant seinen nächsten Schritt, und ihm wird am meisten vertraut ...
4 Außenminister "Ich möchte GoTo erweitern" Inland CopyrightC Japan News Network All rights reser...
... ... ... ...
497 Mr. Byden zu einer TV-Rede für die Öffentlichkeit International AFP Current Affairs Joe Biden, Präsidentschaftskandidat der Demokratischen Partei der USA
498 Zusammenstoß- und Aufruhrwarnungen in den USA International Alle Nippon NewsNetworkANN Der Gewinner der Präsidentschaftswahlen ist in den USA ungewiss ...
499 Vereinbarung zur Wiederaufnahme des Geschäftsverkehrs zwischen Japan und China Inland Der Verkehr von Geschäftsleuten, der von der japanischen und chinesischen Regierung zur Verhinderung des neuen Koronavirus eingeschränkt wurde, wird Mitte dieses Monats erneut überprüft ...
500 Präsidentschaftswahlen nach Georgien berichten International AFP-Update zu aktuellen Angelegenheiten Der Demokrat Joe Biden bei den US-Präsidentschaftswahlen ist der Republikaner Donald Tran ...
501 IOC-Präsident Bach wird am 15. nach Japan kommen Sport Thomas Bach vom Internationalen Olympischen Komitee IOC über die Olympischen Paralympics in Tokio auf den nächsten Sommer verschoben ...

502 rows × 3 columns

Über Unterwort

Ich habe es das letzte Mal nicht erwähnt, aber dieses Mal werde ich das Unterwort betrachten, das ein Hauptmerkmal von fastText ist. Ein Unterwort besteht darin, ein Wort in kleinere "Unterwörter" zu unterteilen, um die Relevanz der Wörter zu erfassen. Sie können beispielsweise die Relevanz von Wörtern lernen, die einen gemeinsamen Teil haben, z. B. "Los" und "Los". Das Anwenden von Unterwörtern hat die Genauigkeit verbessert, daher werde ich es verwenden. Im Gegenteil, es scheint, dass es eine schädliche Auswirkung auf die Katata-Sprache gibt. Es kann implementiert werden, indem "maxn" und "minn" an die Argumente von train_supervised und train_unsupervised übergeben werden. Die Standardwerte für train_supervised und train_unsupervised sind unterschiedlich. Weitere Informationen finden Sie unter GitHub.

Betreutes Lernen (train_supervised)

Führen Sie zum Vergleich zunächst den Inhalt von Letztes Mal sofort aus.

#Speichern Sie Kategorie und Text in der Liste
cat_lst = ['__label__' + cat for cat in df.category]
text_lst = [M2A(text, mecab=wakati) for text in df.text]

#In Zug geteilt und gültig
text_train, text_valid, cat_train, cat_valid = train_test_split(
    text_lst, cat_lst, test_size=0.2, random_state=0, stratify=cat_lst
)

#Erstellen Sie Zug- und gültige Dateien
with open('./s_train', mode='w') as f:
    for i in range(len(text_train)):
        f.write(cat_train[i] + ' '+ text_train[i])
        
with open('./s_valid', mode='w') as f:
    for i in range(len(text_valid)):
        f.write(cat_valid[i] + ' ' + text_valid[i])

#Modelllernen
model = fasttext.train_supervised(input='./s_train', lr=0.5, epoch=500, minn=3, maxn=5,
                                  wordNgrams=3, loss='ova', dim=300, bucket=200000)

#Überprüfen Sie die Genauigkeit des Modells
# print("TrainData:", model.test('./s_news_train'))
print("ValidData:", model.test('./s_valid'))

#Erstellen eines zweidimensionalen Diagramms unter Verwendung gültiger Daten
with open("./s_valid") as f:
    l_strip = [s.strip() for s in f.readlines()] # strip()Entfernen Sie Zeilenvorschubzeichen mit
    
labels = []
texts = []
sizes = []
for t in l_strip:
    labels.append(re.findall('__label__(.*?) ', t)[0])
    texts.append(re.findall(' (.*)', t)[0])
    sizes.append(model.predict(re.findall(' (.*)', t))[1][0][0])

#Vektorerzeugung aus gültigem Artikelkörper
vectors = []
for t in texts:
    vectors.append(model.get_sentence_vector(t))

#In numpy konvertieren
vectors = np.array(vectors)
labels = np.array(labels)
sizes = np.array(sizes)

#Standardisierung
ss = preprocessing.StandardScaler()
vectors_std = ss.fit_transform(vectors)

#Dimensionsreduzierung
pca = PCA()
pca.fit(vectors_std)
feature = pca.transform(vectors_std)
feature = feature[:, :2]

#Handlung
x0, y0, z0 = feature[labels=='Unterhaltung', 0], feature[labels=='Unterhaltung', 1], sizes[labels=='Unterhaltung']*1000
x1, y1, z1 = feature[labels=='Sport', 0], feature[labels=='Sport', 1], sizes[labels=='Sport']*1000
x2, y2, z2 = feature[labels=='Leben', 0], feature[labels=='Leben', 1], sizes[labels=='Leben']*1000
x3, y3, z3 = feature[labels=='Inländisch', 0], feature[labels=='Inländisch', 1], sizes[labels=='Inländisch']*1000
x4, y4, z4 = feature[labels=='International', 0], feature[labels=='International', 1], sizes[labels=='International']*1000
x5, y5, z5 = feature[labels=='Bereich', 0], feature[labels=='Bereich', 1], sizes[labels=='Bereich']*1000
x6, y6, z6 = feature[labels=='Wirtschaft', 0], feature[labels=='Wirtschaft', 1], sizes[labels=='Wirtschaft']*1000

plt.figure(figsize=(14, 10))
plt.rcParams["font.size"]=20
plt.scatter(x0, y0, label="Unterhaltung", s=z0)
plt.scatter(x1, y1, label="Sport", s=z1)
plt.scatter(x2, y2, label="Leben", s=z2)
plt.scatter(x3, y3, label="Inländisch", s=z3)
plt.scatter(x4, y4, label="International", s=z4)
plt.scatter(x5, y5, label="Bereich", s=z5)
plt.scatter(x6, y6, label="Wirtschaft", s=z6)
plt.title("Yahoo Nachrichten")
plt.xlabel('1st dimension')
plt.ylabel('2nd dimension')
plt.legend(title="category")
plt.show()
ValidData: (101, 0.801980198019802, 0.801980198019802)

output_5_1.png

Unüberwachtes Lernen (train_unsupervised)

Datenaufbereitung

Für unbeaufsichtigtes Lernen ist kein Etikett erforderlich. Sie müssen also nur die Daten für das Lernen aufschreiben. (1) Die Kategorie wird in cat_lst gespeichert, und Sätze werden durch die M2A-Funktion getrennt und in text_lst gespeichert. (2) Teilen Sie in Zugdaten und gültige Daten. ③ Speichern Sie den Text in einer Datei.

# ①
cat_lst = [cat for cat in df.category]
text_lst = [M2A(text, mecab=wakati) for text in df.text]

# ②
text_train, text_valid, cat_train, cat_valid = train_test_split(
    text_lst, cat_lst, test_size=0.2, random_state=0, stratify=cat_lst
)

# ③
with open('./u_train', mode='w') as f:
    for i in range(len(text_train)):
        f.write(text_train[i])
        
with open('./u_valid', mode='w') as f:
    for i in range(len(text_valid)):
        f.write(text_valid[i])

Modelllernen

Unüberwachtes Lernen verwendet "train_unsupervised".

model = fasttext.train_unsupervised('./u_train', epoch=500, lr=0.01, minn=3, maxn=5, dim=300)

Zugdatenanalyse

Vergleich der Satzvektorähnlichkeit

Verwenden Sie das trainierte Modell, um die Ähnlichkeit des Artikelinhalts zu berechnen. ① Verwenden Sie die Methode "get_sentence_vector", um einen Satzvektor aus dem trainierten Modell zu generieren. ② Zeigen Sie die Artikelkategorie und den Text an. (3) Berechnen Sie die Kosinusähnlichkeit mit der oben gelesenen Funktion cos_sim.

# ①
vectors = []
for t in text_train:
    vectors.append(model.get_sentence_vector(t.strip()))

# ②
print("<{}>".format(cat_train[0]))
print(text_train[0][:200], end="\n\n")
print("<{}>".format(cat_train[1]))
print(text_train[1][:200], end="\n\n")
print("<{}>".format(cat_train[2]))
print(text_train[2][:200], end="\n\n")

# ③
print("<{}><{}>".format(cat_train[0], cat_train[1]), cos_sim(vectors[0], vectors[1]))
print("<{}><{}>".format(cat_train[1], cat_train[2]), cos_sim(vectors[1], vectors[2]))
print("<{}><{}>".format(cat_train[0], cat_train[2]), cos_sim(vectors[0], vectors[2]))
Shigeru Omi, Vorsitzender des Unterausschusses für Gegenmaßnahmen gegen neue Corona-Viren der Regierung, Vorsitzender der regionalen Organisation zur Förderung medizinischer Funktionen, hielt am 9. eine dringende Pressekonferenz ab, und es besteht kein Zweifel daran, dass die Zahl der Infektionen landesweit zunimmt. Er hat sich jetzt darüber beschwert, dass dies wahrscheinlich zu einem allmählichen, aber raschen Expansionstrend führen wird, und als dringende Empfehlung an die Regierung 1 bis jetzt. Senator Kawai, der beschuldigt wurde, im Juli letzten Jahres die Wahl des Repräsentantenhauses übernommen zu haben, verstieß gegen das Gesetz zur Wahl der öffentlichen Beschäftigung. Im ersten Prozess behauptete er wiederholt, es sei eine Feier der Wahl und ein Mitgefühl für das Team, und er sagte, dass dies nicht illegal sei. Update der aktuellen AFP-Angelegenheiten Donald Trump Der US-Präsident Donald Trump ist damit beschäftigt, auf Herrn Trump zu antworten, der keine Niederlage bei den Präsidentschaftswahlen zugibt, und enthüllt, dass er Verteidigungsminister Mark Esper in einem Beitrag auf Twitter Twitter am 9. entlassen hat. Mark Esper schrieb in einem Beitrag von Mr. Trump, der von der Administration weiter erschüttert wurde.

0,91201633 0.9294117 0.9201762

2D-Plot

Lassen Sie uns endlich in zwei Dimensionen zeichnen. ① Konvertieren Sie Vektor und Beschriftung in Numpy-Array ② Standardisieren Sie den Vektor ③ Dimensionsreduktion des Vektors mit PCA ④ Plot mit Matplotlib. Im Gegensatz zu "train_supervised" können Sie die Wahrscheinlichkeit für die Vorhersage nicht ermitteln, sodass alle Diagramme dieselbe Größe haben.

# ①
vectors = np.array(vectors)
labels = np.array(cat_train)


# ②
ss = preprocessing.StandardScaler()
vectors_std = ss.fit_transform(vectors)


# ③
pca = PCA()
pca.fit(vectors_std)
feature = pca.transform(vectors_std)
feature = feature[:, :2]


# ④
x0, y0 = feature[labels=='Unterhaltung', 0], feature[labels=='Unterhaltung', 1]
x1, y1 = feature[labels=='Sport', 0], feature[labels=='Sport', 1]
x2, y2 = feature[labels=='Leben', 0], feature[labels=='Leben', 1]
x3, y3 = feature[labels=='Inländisch', 0], feature[labels=='Inländisch', 1]
x4, y4 = feature[labels=='International', 0], feature[labels=='International', 1]
x5, y5 = feature[labels=='Bereich', 0], feature[labels=='Bereich', 1]
x6, y6 = feature[labels=='Wirtschaft', 0], feature[labels=='Wirtschaft', 1]

plt.figure(figsize=(14, 10))
plt.rcParams["font.size"]=20
plt.scatter(x0, y0, label="Unterhaltung", s=300)
plt.scatter(x1, y1, label="Sport", s=300)
plt.scatter(x2, y2, label="Leben", s=300)
plt.scatter(x3, y3, label="Inländisch", s=300)
plt.scatter(x4, y4, label="International", s=300)
plt.scatter(x5, y5, label="Bereich", s=300)
plt.scatter(x6, y6, label="Wirtschaft", s=300)
plt.title("Yahoo Nachrichten")
plt.xlabel('1st dimension')
plt.ylabel('2nd dimension')
plt.legend(title="category")
plt.show()

output_13_0.png

gültige Datenanalyse

Als nächstes gruppieren wir die gültigen Daten. Der Inhalt entspricht der Zugdatenanalyse, daher wird keine Erklärung angegeben.

vectors = []
for t in text_valid:
    vectors.append(model.get_sentence_vector(t.strip()))

print("<{}>".format(cat_valid[0]))
print(text_valid[0][:200], end="\n\n")
print("<{}>".format(cat_valid[1]))
print(text_valid[1][:200], end="\n\n")
print("<{}>".format(cat_valid[2]))
print(text_valid[2][:200], end="\n\n")
print("<{}><{}>".format(cat_valid[0], cat_valid[1]), cos_sim(vectors[0], vectors[1]))
print("<{}><{}>".format(cat_valid[1], cat_valid[2]), cos_sim(vectors[1], vectors[2]))
print("<{}><{}>".format(cat_valid[0], cat_valid[2]), cos_sim(vectors[0], vectors[2]))
KNT-CT Holdings HD, dem Kinki Japan Tourist usw. gehört, hat angekündigt, bis März 2025 ein Drittel seiner rund 7.000 Mitarbeiter in der Gruppe zu reduzieren, da am 11. ein Ruhestand angestrebt wird. Zwei Drittel der Geschäfte werden bis März 2010 geschlossen sein. Aufgrund der stark rückläufigen Nachfrage nach Reisen aufgrund der Ausbreitung der neuen Coronavirus-Infektion Am 9. November wurde festgestellt, dass die Zahl der mit dem neuen Koronavirus in Hokkaido infizierten Menschen 200 übersteigen sollte, die höchste Zahl aller Zeiten. Mehr als 100 Menschen werden am fünften Tag in Folge voraussichtlich das Niveau von 200 erreichen, und die Ausbreitung der Infektion wird erwartet. Es scheint, dass ein neuer Cluster bestätigt wurde. In Hokkaido wurden am 5. 119 infizierte Personen bestätigt. Hitachi kündigte am 28. Dezember an, den Erwerb von bezahlten Feiertagen bis zum 8. Januar nächsten Jahres zu fördern, um auf die Politik der Regierung zu reagieren, einen verteilten Erwerb von Urlauben für die Jahresend- und Neujahrsferien, normalerweise ab dem 30. Dezember, zu beantragen. Bis zum 3. Januar werden rund 150.000 Menschen, darunter Mitarbeiter von Konzernunternehmen, Urlaub machen, um interne Veranstaltungen zum Jahresende und Neujahr sowie unnötige und unaufhörliche Treffen zu vermeiden.

0.9284181 0,90896636 0,9533808

vectors = np.array(vectors)
labels = np.array(cat_valid)

ss = preprocessing.StandardScaler()
vectors_std = ss.fit_transform(vectors)

pca = PCA()
pca.fit(vectors_std)
feature = pca.transform(vectors_std)
feature = feature[:, :2]

x0, y0 = feature[labels=='Unterhaltung', 0], feature[labels=='Unterhaltung', 1]
x1, y1 = feature[labels=='Sport', 0], feature[labels=='Sport', 1]
x2, y2 = feature[labels=='Leben', 0], feature[labels=='Leben', 1]
x3, y3 = feature[labels=='Inländisch', 0], feature[labels=='Inländisch', 1]
x4, y4 = feature[labels=='International', 0], feature[labels=='International', 1]
x5, y5 = feature[labels=='Bereich', 0], feature[labels=='Bereich', 1]
x6, y6 = feature[labels=='Wirtschaft', 0], feature[labels=='Wirtschaft', 1]

plt.figure(figsize=(14, 10))
plt.rcParams["font.size"]=20
plt.scatter(x0, y0, label="Unterhaltung", s=300)
plt.scatter(x1, y1, label="Sport", s=300)
plt.scatter(x2, y2, label="Leben", s=300)
plt.scatter(x3, y3, label="Inländisch", s=300)
plt.scatter(x4, y4, label="International", s=300)
plt.scatter(x5, y5, label="Bereich", s=300)
plt.scatter(x6, y6, label="Wirtschaft", s=300)
plt.title("Yahoo Nachrichten")
plt.xlabel('1st dimension')
plt.ylabel('2nd dimension')
plt.legend(title="category")
plt.show()

output_16_0.png

Erwägung

Mit einem Lehrer lernen

――Durch die Übernahme des Unterworts wurde die Genauigkeit gegenüber dem vorherigen Artikel weiter verbessert. 0,75 → 0,80 ―― Ähnlich wie in der vorherigen Zeit gibt es in der ersten Dimension viele überlappende Teile zwischen "Unterhaltung" und "Sport", in der zweiten Dimension sind sie jedoch klar voneinander getrennt. Ich bin überzeugt, dass "Unterhaltung" und "Sport" nahe beieinander liegen. ―― „International“ und „Inland“ sind gut voneinander getrennt, und zwischen ihnen besteht eine „Wirtschaft“. Wie beim letzten Mal überzeugt auch dies. ―― Im vorherigen Artikel war die "Region" nicht klar, aber diesmal sind die Eigenschaften in zweidimensionaler Richtung stark. ―― Insgesamt fühlt es sich klarer klassifiziert an als beim letzten Mal.

Lernen ohne Lehrer

Zugdaten

  • Für jede Kategorie gibt es viele überlappende Teile. ―― „International“ und „Inland“ sind klar voneinander getrennt. ――Es war das übliche Muster zu sagen, dass "Wirtschaft" zwischen "international" und "inländisch" liegt, aber diesmal wurde es in einem weiten Bereich dargestellt. ―― „Unterhaltung“ und „Sport“ überschneiden sich stark, aber in der eindimensionalen Richtung befand sich „Unterhaltung“ leicht rechts und „Sport“ links. ―― „Region“ hat fast keine Überschneidung mit „international“, was überzeugt. Es gibt eine beträchtliche Überschneidung zwischen "Inland" und "Wirtschaft".

gültige Daten

――Es gibt nur wenige überlappende Teile, und es wurde ordentlich als Ganzes klassifiziert. ――Es gibt "Inland" im Zentrum, "International" auf der linken Seite und "Wirtschaft" im Zentrum. Es ist ganz anders als zuvor. ――Obwohl "Sport" und "Unterhaltung" diesmal ziemlich nahe beieinander liegen, wurden "Sport" über ein breites Spektrum verteilt. ――Die "Region" ist zweigeteilt. Diese Tendenz kann sogar von beaufsichtigten Lernenden beobachtet werden, daher kann es einige Kriterien geben.

Dieses Mal analysierte ich es, indem ich ohne Lehrer lernte, aber ich war überrascht, dass die Klassifizierung erfolgreich war. Da es kein Etikett gibt, bedeutet dies, dass Sie aus dem Text "international" oder "Sport" erhalten können. Ich bin sehr gespannt, welche Funktionen das Modell tatsächlich erhält und bei der Vektorerstellung widerspiegelt. Ich möchte tiefer in fastText eintauchen! !! !!

Verweise

Yahoo! News fastText Erklärung zur Installation und Verwendung von fastText, veröffentlicht von Facebook Nebenwirkungen des Unterworts fastText fastText tutorial(Word representations) GitHub (fastText/python) fastText ist unglaublich! Clustering "Yahoo! News"