Forschung und Entwicklung im Bereich der künstlichen Intelligenz sind in den letzten Jahren zu einem Boom geworden, und in verschiedenen Bereichen wurden verschiedene Ergebnisse erzielt. Die automatische Dokumentenzusammenfassungstechnologie ist auch im Bereich der KI in einem großen Rahmen und technisch im Bereich der Verarbeitung natürlicher Sprache. Dokumentzusammenfassungen werden häufig für elektrische Bulletin Boards im Shinkansen und Überschriften für Webnachrichten verwendet, aber ich denke, ihre Verwendung ist nicht auf ordentliche Dokumente wie Nachrichten beschränkt.
In diesem Artikel möchte ich den Dokumentzusammenfassungsalgorithmus LexRank verwenden, um typische Bewertungen von Käufern schnell zu visualisieren, indem Produktbewertungen auf der EC-Website (Rakuten) zusammengefasst werden.
LexRank LexRank ist ein von Erkan et al. Vorgeschlagener Algorithmus zur Zusammenfassung von Dokumenten, der auf dem Konzept von PageRank basiert.
Originalarbeit: LexRank: Graphbasierte lexikalische Zentralität als herausragende Rolle bei der Textzusammenfassung
Ich werde die Details weglassen, aber es gibt nur zwei wichtige Konzepte in LexRank.
Die folgende Grafik zeigt die beiden oben genannten Konzepte. (dXsY: Y-Satz von Dokument X)
Abbildung: Beispiel eines Ähnlichkeitsgraphen (extrahiert aus [Erkan 04])
Der Knoten mit der dicken Kante ist von hoher Bedeutung, und der Knoten mit der Kante von dem Knoten mit der höchsten Bedeutung wird ebenfalls als von hoher Bedeutung angesehen.
Wenn ich Amazon oder Rakuten benutze, spüre ich das oft.
――Die Anzahl der Bewertungen ist extrem groß und scheint sehr glaubwürdig zu sein, aber ich weiß nicht, auf welche Bewertung ich mich beziehen soll! ――Sie können abstimmen, wenn es hilfreich war, aber die hilfreiche Bewertung ist lang ...
Daher möchten wir dieses Mal ** einen zusammenfassenden Satz ausgeben, der den Teil enthält, den jeder in n Sätzen aus einer großen Anzahl von Überprüfungssätzen überprüft **. Dies sollte Ihnen viel Energie sparen und ein Gefühl für die Bewertungen bekommen, egal ob Sie Hunderte von Bewertungen oder lange Bewertungen haben!
Dieses Skript hängt von den folgenden Paketen ab. Alle können einfach mit pip install / conda install installiert werden.
Der Hauptcode des erstellten LexRank lautet wie folgt. Dieser Algorithmus basiert auf Algorithmus 3 des Originalpapiers.
lexrank.py
def lexrank(sentences, N, threshold, vectorizer):
CosineMatrix = np.zeros([N, N])
degree = np.zeros(N)
L = np.zeros(N)
if vectorizer == "tf-idf":
vector = tfidf.compute_tfidf(sentences)
elif vectorizer == "word2vec":
vector = tfidf.compute_word2vec(sentences)
# Computing Adjacency Matrix
for i in range(N):
for j in range(N):
CosineMatrix[i,j] = tfidf.compute_cosine(vector[i], vector[j])
if CosineMatrix[i,j] > threshold:
CosineMatrix[i,j] = 1
degree[i] += 1
else:
CosineMatrix[i,j] = 0
# Computing LexRank Score
for i in range(N):
for j in range(N):
CosineMatrix[i,j] = CosineMatrix[i,j] / degree[i]
L = PowerMethod(CosineMatrix, N, err_tol=10e-6)
return L
Input: --texts: Liste der Eingabesätze --N: Anzahl der Eingabesätze --threshold: Ähnlichkeitsschwelle beim Erstellen einer Adjazenzmatrix (Ähnlichkeitsdiagramm) --vectorizer: Anweisungsvektorisierungsmethode (tf-idf / word2vec)
Output: --L: Lex Rank Score (Wichtigkeit jedes Satzes)
Der LexRank-Score L bezieht sich auf den Eigenvektor. Im Originalpapier wird es nach der Power-Methode (Power-Methode) berechnet.
PowerMethod
def PowerMethod(CosineMatrix, N, err_tol):
p_old = np.array([1.0/N]*N)
err = 1
while err > err_tol:
err = 1
p = np.dot(CosineMatrix.T, p_old)
err = np.linalg.norm(p - p_old)
p_old = p
return p
Input: --CosineMatrix: Benachbarte Matrix --N: Anzahl der Eingabesätze --err_tol: Fehlertoleranz zur Bestimmung der Konvergenz durch PowerMethod
Output: --p: Eindeutiger Vektor (LexRank-Punktzahl)
Dieses Mal möchte ich die Bewertungen der folgenden in Rakuten ausgestellten Spielautomaten zusammenfassen. (Vorerst werde ich verbergen, welches Produkt nur der Modellname ist)
tf-idf model Hier ist eine Zusammenfassung des Modells, das eine benachbarte Matrix durch Vektorisieren von Sätzen mit tf-idf erstellt hat. Übrigens wird im Originalpapier die benachbarte Matrix vom tf-idf-Modell erstellt. (Zu diesem Zeitpunkt gab es noch kein word2vec)
1: Ich hatte vor langer Zeit ein Videospiel eines anderen Herstellers und bin überrascht, dass es sich so sehr weiterentwickelt hat! Ganz zu schweigen von dem schönen Bild, es hat verschiedene Funktionen, also dachte ich, dass diesem Preis nicht geholfen werden kann. Dieser Shop hat viele Punkte und Gutscheine, also war es billiger als ich erwartet hatte und es war gut, es zu kaufen. 2: Ich habe es hier gekauft. 3: Meine Familie hat es gekauft, aber ich bin überrascht über die hohe Leistung.
1: Ich habe Nintendo New 3DS für das Weihnachtsgeschenk meines Bruders bestellt. Es kam früher als erwartet an, nachdem ich es bestellt hatte. Da es sich um eine Spielmaschine handelt, dachte ich, dass die Verpackung etwas enger sein soll, aber es ist in Ordnung, da die Box keine anfänglichen Mängel oder Kratzer aufweist (lacht). Wenn es etwas gibt, danke. 2: Ich hatte ein 3DS, aber der Flüssigkristall brach und ich reparierte ihn einmal, aber er brach erneut und ich musste ein neues 3DS kaufen. Ich habe LL gekauft, weil ich dachte, es wäre besser, beim nächsten Mal einen mit einem größeren Bildschirm zu kaufen. 3: Wir haben zum Weihnachtsgeschenk ein Kind gekauft.
Das Merkmal von PS4 ist eine hohe Leistung, und es versteht sich, dass 3DS häufig als Geschenk für Kinder gekauft wird. Da die Überprüfung des ersten Satzes für beide Produkte überflüssig ist, erscheint es andererseits notwendig, etwas mehr Segmente zu berücksichtigen. Da die Informationen im zweiten Satz von PS4 keine besonders nützlichen Informationen enthalten, wird davon ausgegangen, dass sie in dieser Aufgabe nicht extrahiert werden sollten.
word2vec model Hier ist eine Zusammenfassung des Modells, das eine benachbarte Matrix durch Vektorisieren von Sätzen mit word2vec erstellt hat. Der Schwerpunkt aller im Satz enthaltenen Wörter wird vom vorgelernten Wortvektor als Satzvektor verwendet.
1: Ich habe Punkte verwendet, aber ich hatte das Gefühl, etwas verloren zu haben 2: Kann problemlos verwendet werden ♪ 3: Der Bildschirm auf dem Fernseher ist ziemlich sauber.
1: Für Kinder wäre es schön, wenn es einen faltbaren Typ wie 3DS gäbe, mit einer einfachen Funktion wie 2DS, die vor einiger Zeit herauskam, und etwas billiger. 2: Ich bin froh, dass Sie es sofort versendet haben. 3: Es ist ein Ersatz für LL in Eile.
Im Vergleich zur Zusammenfassung des tf-idf-Modells habe ich den Eindruck, dass es sich um eine präzisere Zusammenfassung handelt. Einige Zusammenfassungen sind jedoch keine Produktbewertungen. Da die Punktzahl von Sätzen, die vielen Sätzen semantisch ähnlich sind, hoch ist, kann gesagt werden, dass viele der Ausgabezusammenfassungen in gewissem Sinne plausibel sind, aber es scheint, dass für diese Aufgabe ein gewisser Einfallsreichtum erforderlich ist.
Dieses Mal haben wir die EC-Site mithilfe des automatischen Zusammenfassungsalgorithmus LexRank überprüft und zusammengefasst. Durch die Zusammenfassung einer großen Anzahl von Bewertungen scheint es, dass die Eigenschaften des Produkts effizient erfasst werden können. Auf der anderen Seite hielt ich es für notwendig, ein wenig mehr zu entwickeln, wie z. B. die Reduzierung von Satzsegmenten und Redundanz. Ich möchte diesen Punkt beim nächsten Mal noch einmal erstellen.
Der Code der Vektorberechnungsmethode (tf-idf, word2vec) zur Berechnung der Ähnlichkeit jedes Satzes ist unten gezeigt. Dieses Skript selbst wird in lexrank.py aufgerufen. (vector = tfidf.compute_tfidf (Sätze)) Sie können es ausführen, indem Sie tfidf in lexrank.py importieren. Auch das vom word2vec-Modell aufgerufene Wortvektormodell ('../ models / wiki_sg_d100.bin') ist ein Wortvektor, der aus dem Volltext der japanischen Wikipedia gelernt wurde.
tfidf.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import numpy as np
import fasttext as ft
from scipy.spatial import distance
def word2id(bow, word_id):
for w in bow:
if word_id.has_key(w) == False:
word_id[w] = len(word_id)
return word_id
def compute_tf(sentences, word_id):
tf = np.zeros([len(sentences), len(word_id)])
for i in range(len(sentences)):
for w in sentences[i]:
tf[i][word_id[w]] += 1
return tf
def compute_df(sentences, word_id):
df = np.zeros(len(word_id))
for i in range(len(sentences)):
exist = {}
for w in sentences[i]:
if exist.has_key(w) == False:
df[word_id[w]] += 1
exist[w] = 1
else:
continue
return df
def compute_idf(sentences, word_id):
idf = np.zeros(len(word_id))
df = compute_df(sentences, word_id)
for i in range(len(df)):
idf[i] = np.log(len(sentences)/df[i]) + 1
return idf
def compute_tfidf(sentences):
word_id = {}
for sent in sentences:
word_id = word2id(sent, word_id)
tf = compute_tf(sentences, word_id)
idf = compute_idf(sentences, word_id)
tf_idf = np.zeros([len(sentences), len(word_id)])
for i in range(len(sentences)):
tf_idf[i] = tf[i] * idf
return tf_idf
def compute_cosine(v1, v2):
return 1 - distance.cosine(v1, v2)
def sent2vec(bow, model_w):
vector = np.zeros(100)
N = len(bow)
for b in bow:
try:
vector += model_w[b]
except:
continue
vector = vector / float(N)
return vector
def compute_word2vec(sentences):
model_w = ft.load_model('../models/wiki_sg_d100.bin')
vector = np.zeros([len(sentences), 100])
for i in range(len(sentences)):
vector[i] = sent2vec(sentences[i], model_w)
return vector
if __name__ == "__main__":
pass
Recommended Posts