Ich habe einen Suchalgorithmus mit word2vec erstellt, mit der Erwartung, dass nicht nur exakte Wortübereinstimmungen, sondern auch Synonyme getroffen werden. Infolgedessen waren die word2vec-Informationen allein nicht zufriedenstellend, aber es scheint, dass der erwartete Effekt erzielt wird, sodass ich es für nützlich hielt, sie mit anderen Methoden zu kombinieren.
macOS Catalina 10.15.4 python 3.8.0
Ich werde die detaillierte Methode anderen Artikeln überlassen. Ich habe den vollständigen Text von Wikipedia heruntergeladen, ihn mit mecab-ipadic-neologd geteilt und word2vec mit gensim gelernt. Der Code zum Zeitpunkt des Lernens lautet wie folgt. Ich habe den Code von Erstellen eines word2vec-Modells mit dem Wikipedia-Korpus | Adhesive Devotion Diary ausgeliehen.
from gensim.models import word2vec
import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.Text8Corpus('./wiki_wakati_neologd.txt')
model = word2vec.Word2Vec(sentences, size=200, min_count=20, window=15)
model.save("./wiki_neologd.model")
Berechnen Sie die Ähnlichkeit zwischen dem Eingabetext und der Liste der zu durchsuchenden Dokumente mit der folgenden Methode, um den Text mit der höchsten Ähnlichkeit zu erhalten.
Der Code, der das oben genannte erreicht, ist unten.
import re
import neologdn
import MeCab, jaconv
import pandas as pd
from gensim.models import word2vec
#Laden des word2vec-Modells
MODEL_PATH = "wiki_neologd.model"
model = word2vec.Word2Vec.load(MODEL_PATH)
#Objekt für die morphologische Analyse
m = MeCab.Tagger()
#Objekt für die normale Ausdrucksverarbeitung
re_kana = re.compile('[a-zA-Z\u3041-\u309F]')
re_num = re.compile('[0-9]+')
#Dokumentieren Sie die Normalisierungsfunktion vor der morphologischen Analyse
def format_text(text):
text = neologdn.normalize(text)
return text
#Funktion zum Extrahieren des Prototyps des unabhängigen Wortes des Satzes mit Ausnahme eines alphanumerischen Zeichens
def extract_words(text):
words = []
for token in m.parse(text).splitlines()[:-1]:
if '\t' not in token: continue
surface = token.split('\t')[0]
pos = token.split('\t')[1].split(',')
ok = (pos[0]=='Substantiv' and pos[1] in ['Allgemeines','固有Substantiv','Verbindung ändern','Adjektiv Verbstamm'])
ok = (ok or (pos[0]=='Adjektiv' and pos[1] == 'Unabhängigkeit'))
ok = (ok or (pos[0]=='Adverb' and pos[1] == 'Allgemeines'))
ok = (ok or (pos[0]=='Verb' and pos[1] == 'Unabhängigkeit'))
if ok == False: continue
stem = pos[-3]
if stem == '*': stem = surface
if stem == '- -': continue
if re_kana.fullmatch(stem) and len(stem)==1: continue
if re_num.fullmatch(stem): continue
if stem == '': continue
words.append(stem)
return words
#Extrahieren Sie unabhängige Wörter aus einer Reihe von Dokumenten und erstellen Sie eine Datenbank.
def get_document_db(documents):
id_list = list(range(len(documents)))
words_list = []
for d in documents:
d = format_text(d)
words = extract_words(d)
#Duplikate ausschließen
words = set(words)
#Schließen Sie Wörter aus, die nicht in word2vec enthalten sind
words = [w for w in words if w in model.wv.vocab]
words_list.append(words)
db = pd.DataFrame({"id":id_list, "text":documents, "word":words_list})
return db
#Gibt die Ähnlichkeit zwischen Wortliste A und Wortliste B zurück
def calc_similarity(words1, words2):
total = 0
for w1 in words1:
if w1 not in model.wv.vocab: continue
max_sim = 0
for w2 in words2:
if w2 not in model.wv.vocab: continue
sim = model.wv.similarity(w1=w1, w2=w2)
max_sim = max(max_sim, sim)
total += max_sim
return total
#Berechnet die Ähnlichkeit zwischen der Eingabeanweisung und jedem Dokument in db und gibt sie zurück
def add_similarity_to_db(text, db):
text = format_text(text)
words1 = extract_words(text)
#Duplikate ausschließen
words1 = set(words1)
words1 = [w for w in words1 if w in model.wv.vocab]
similarity = []
for words2 in db.word:
sim = calc_similarity(words1, words2)
similarity.append(sim)
similarity_df = pd.DataFrame({"similarity": similarity})
db2 = pd.concat([db,similarity_df], axis=1)
db2 = db2.sort_values(["similarity"], ascending=False)
db2 = db2.reset_index()
return db2
#Ausgabeprüfung
#Zu durchsuchender Dokumentensatz
#Erstellen Sie eine Liste von Dokumenten, Element für Element. Hier verwende ich als Beispiel Sätze, die angemessen aus meinen früheren Artikeln extrahiert wurden.
documents = [
'Ich habe eine Funktion erstellt, um die japanische Aussprache in Kana mit MeCab und Python zu erhalten. Wenn Sie beispielsweise "Ich habe heute gut geschlafen" eingeben, wird "Kyowayokunemashita" zurückgegeben.',
'Ich habe eine Python-Funktion erstellt, die Japanisch (Katakana-Zeichenkette) in Einheiten von Mora (Mora-Division) unterteilt. Mora und Silben sind typische Teilungseinheiten für die japanische Phonologie. Mora ist ein Begrenzer beim Zählen der sogenannten "5, 7, 5" im Haiku, und lange Töne (-), Aufforderungstöne (tsu) und Tonabwehrmittel (n) werden ebenfalls als ein Schlag gezählt. Andererseits werden in Silben lange Noten, Aufforderungstöne und abstoßende Töne nicht einzeln gezählt, sondern als ein Schlag zusammen mit dem Kana betrachtet, das unmittelbar zuvor eine einzelne Silbe sein kann.',
'Ich habe eine Python-Funktion erstellt, die Japanisch (Katakana-Zeichenkette) in Silben (Sektar-Teilung) unterteilt. Mora und Silben sind typische Teilungseinheiten für die japanische Phonologie. Mora ist ein Begrenzer beim Zählen der sogenannten "5, 7, 5" im Haiku, und lange Töne (-), Aufforderungstöne (tsu) und Tonabwehrmittel (n) werden ebenfalls als ein Schlag gezählt. Andererseits werden in Silben lange Noten, Aufforderungstöne und abstoßende Töne nicht einzeln gezählt, sondern als ein Schlag zusammen mit dem Kana betrachtet, das unmittelbar zuvor eine einzelne Silbe sein kann. Wenn ein langer Ton, ein auffordernder Ton und eine Schallabweisung wie "Brennen" kontinuierlich sind, wird die Anzahl der Mora von 3 oder mehr zu einer Silbe.',
'In Python habe ich eine Funktion erstellt, die (die unterste Zeile der folgenden Tabelle) nach Phrasen und nicht nach Wörtern (Teilen) unterteilt.',
'"Finden Sie die 25 Billionen Ziffern der 100 Billionen Etage(Ich habe versucht, das Problem "Notation is decimal system)" mit Python zu lösen. (Die ursprüngliche Geschichte ist die berühmte Frage: "Ist die 25-Billionen-Zahl von rechts von den 100 Billionen Stockwerken gerade oder ungerade?")',
'Das Standardwörterbuch von MeCab ist mecab-ipadic-Dies ist ein Memo von dem, was ich in meiner Umgebung (macOS) getan habe, um zu NEologd zu wechseln. Wie viele Leute bereits geschrieben haben, kann das Standardwörterbuch durch Bearbeiten einer Datei namens Mecabrc geändert werden. In meiner Umgebung gibt es jedoch mehrere Mecabrc, und ich habe mich gefragt, welche und welche ich bearbeiten soll Ich schreibe darüber, wie es tatsächlich funktioniert hat, einschließlich der Frage, ob eine Datei bearbeitet werden sollte.'
]
db = get_document_db(documents)
input_texts = ["Separates Japanisch","Berechnung des Bodens","Trenne Japanisch mit Mora", "Trennen Sie Japanisch durch Silben"]
for text in input_texts:
print(text)
result = add_similarity_to_db(text, db)
for sim, d in list(zip(result.similarity, result.text))[:10]:
disp = d
if len(d)>20: disp = d[:20]+"..."
print(sim, disp)
Die Ausgabe ist unten. Die Anzahl der Dokumente ist gering und als Beispiel schwer zu verstehen, aber die ersten beiden Ergebnisse sind so. In den beiden letzteren waren die Punktzahlen für Mora und Silben genau gleich. Es scheint, dass Mora und Silben in diesem Dokumentensatz nebeneinander existierten. Das Gewicht der Wörter in jedem Dokument in die Berechnung mit tfidf usw. einzubeziehen, mag besser sein, aber ich möchte es in Zukunft überprüfen.
Separates Japanisch
2.593316972255707 Japanische Minuten (Katakana-Zeichenfolge) in Mora-Einheiten...
2.593316972255707 Japanisch (Katakana-Zeichenfolge) geteilt durch Silbe...
1.6599590480327606 Japanische Aussprache mit MeCab und Python...
1.5144233107566833 Das Standardwörterbuch von MeCab ist mecab-...
1.4240807592868805 In Python keine Einheit von Wörtern (Teilen)...
1.18932443857193 "Finden Sie die 25 Billionen Ziffern der 100 Billionen Etage...
Berechnung des Bodens
1.4738755226135254 "Ermitteln Sie die 25-Billionen-Ziffernzahl des 100-Billionen-Bodens...
1.1860262751579285 Japanische Aussprache mit MeCab und Python...
1.1831795573234558 Japanische Minuten (Katakana-Zeichenfolge) in Mora-Einheiten...
1.1831795573234558 Japanisch (Katakana-Zeichenkette) geteilt durch Silbe...
1.1831795573234558 In Python ist es keine Einheit von Wörtern (Teilen)...
0.7110081613063812 Das Standardwörterbuch von MeCab ist mecab-...
Trenne Japanisch mit Mora
3.0 Minuten Japanisch (Katakana-Zeichenkette) in Mora-Einheiten...
3.0 Ist Japanisch (Katakana-Zeichenfolge) in Silbeneinheiten unterteilt?...
1.754945456981659 Japanische Aussprache mit MeCab und Python...
1.6068530082702637 In Python, nicht in Worten (Teilen)...
1.226668268442154 Das Standardwörterbuch von MeCab ist mecab-...
1.1506744921207428 "Ermitteln Sie die 25-Billionen-Ziffernzahl des 100-Billionen-Bodens...
Trennen Sie Japanisch durch Silben
3.0 Minuten Japanisch (Katakana-Zeichenkette) in Mora-Einheiten...
3.0 Ist Japanisch (Katakana-Zeichenfolge) in Silbeneinheiten unterteilt?...
1.862914353609085 Japanische Aussprache mit MeCab und Python...
1.6907644867897034 In Python, nicht in Worten (Teilen)...
1.2761026918888092 MeCabs Standardwörterbuch mecab-...
1.2211730182170868 "Ermitteln Sie die 25-Billionen-Ziffernzahl des 100-Billionen-Bodens...
Recommended Posts