J'ai recherché des phrases similaires avec Doc2Vec, je vais donc vous présenter l'implémentation.
Pour qu'un ordinateur traite un langage naturel, il doit d'abord avoir une valeur que le langage humain peut gérer. [Word2Vec] existe comme méthode de vectorisation du sens des mots. Pour plus de détails, la destination du lien est très facile à comprendre, mais grosso modo, ce mot est exprimé par une liste de n mots avant et après. En faisant cela, par exemple, «chien» et «chat» sont utilisés dans des contextes similaires et peuvent être considérés comme ayant une «signification» similaire. Doc2Vec est une application de Word2Vec pour vectoriser des phrases.
Les deux fonctions suivantes seront réalisées à l'aide de Doc2Vec cette fois.
Comme exemple, j'ai utilisé le texte d'Aozora Bunko. Le code utilisé dans cet article est [Publié sur GitHub] [GitHub]. (Le texte utilisé pour l'apprentissage a également été compressé, mais veuillez noter qu'il est de grande taille)
Veuillez pouvoir utiliser.
Processus selon le flux de.
import os
import sys
import MeCab
import collections
from gensim import models
from gensim.models.doc2vec import LabeledSentence
Tout d'abord, importez les bibliothèques requises.
def get_all_files(directory):
for root, dirs, files in os.walk(directory):
for file in files:
yield os.path.join(root, file)
Obtient tous les fichiers dans le répertoire donné.
def read_document(path):
with open(path, 'r', encoding='sjis', errors='ignore') as f:
return f.read()
def trim_doc(doc):
lines = doc.splitlines()
valid_lines = []
is_valid = False
horizontal_rule_cnt = 0
break_cnt = 0
for line in lines:
if horizontal_rule_cnt < 2 and '-----' in line:
horizontal_rule_cnt += 1
is_valid = horizontal_rule_cnt == 2
continue
if not(is_valid):
continue
if line == '':
break_cnt += 1
is_valid = break_cnt != 3
continue
break_cnt = 0
valid_lines.append(line)
return ''.join(valid_lines)
Je pense que le traitement ici changera en fonction de la phrase cible. Cette fois, j'ai ignoré la partie explication du texte avant et après le texte. On ne sait pas dans quelle mesure cela affecte la précision en premier lieu.
def split_into_words(doc, name=''):
mecab = MeCab.Tagger("-Ochasen")
valid_doc = trim_doc(doc)
lines = mecab.parse(doc).splitlines()
words = []
for line in lines:
chunks = line.split('\t')
if len(chunks) > 3 and (chunks[3].startswith('verbe') or chunks[3].startswith('adjectif') or (chunks[3].startswith('nom') and not chunks[3].startswith('nom-nombre'))):
words.append(chunks[0])
return LabeledSentence(words=words, tags=[name])
def corpus_to_sentences(corpus):
docs = [read_document(x) for x in corpus]
for idx, (doc, name) in enumerate(zip(docs, corpus)):
sys.stdout.write('\r Prétraitement{} / {}'.format(idx, len(corpus)))
yield split_into_words(doc, name)
Prend une phrase d'un fichier et la décompose en mots. Afin d'améliorer la précision, il semble que les mots utilisés pour l'apprentissage ne soient parfois que de la nomenclature. Cette fois, j'ai utilisé des verbes, des adjectifs et une nomenclature (autres que des nombres).
def train(sentences):
model = models.Doc2Vec(size=400, alpha=0.0015, sample=1e-4, min_count=1, workers=4)
model.build_vocab(sentences)
for x in range(30):
print(x)
model.train(sentences)
ranks = []
for doc_id in range(100):
inferred_vector = model.infer_vector(sentences[doc_id].words)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
rank = [docid for docid, sim in sims].index(sentences[doc_id].tags[0])
ranks.append(rank)
print(collections.Counter(ranks))
if collections.Counter(ranks)[0] >= PASSING_PRECISION:
break
return model
Les paramètres d'apprentissage sont définis dans la partie models.Doc2Vec.
alpha Plus il est haut, plus il converge vite, mais s'il est trop haut, il diverge. Plus la valeur est basse, plus la précision est élevée, mais plus la convergence est lente.
sample Les mots qui apparaissent trop souvent sont probablement des mots dénués de sens et peuvent être ignorés. Définissez ce seuil.
min_count Contrairement à l'échantillon, les mots trop rares peuvent ne pas être appropriés pour décrire la phrase et peuvent être ignorés. Cependant, cette fois, j'ai ciblé tous les mots.
for x in range(30):
print(x)
model.train(sentences)
ranks = []
for doc_id in range(100):
inferred_vector = model.infer_vector(sentences[doc_id].words)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
rank = [docid for docid, sim in sims].index(sentences[doc_id].tags[0])
ranks.append(rank)
print(collections.Counter(ranks))
if collections.Counter(ranks)[0] >= PASSING_PRECISION:
break
return model
Nous apprenons et évaluons dans cette partie. L'évaluation est effectuée en recherchant des phrases similaires dans 100 des phrases apprises et en comptant le nombre de fois où la phrase la plus similaire était vous-même. Cette fois, l'apprentissage est terminé lorsque 94 fois ou plus. (Parce que j'ai essayé de le tourner plusieurs fois et que la précision ne s'améliorait plus)
model.save(OUTPUT_MODEL)
OUTPUT_MODEL contient le chemin de sortie.
model = models.Doc2Vec.load('doc2vec.model')
def search_similar_texts(words):
x = model.infer_vector(words)
most_similar_texts = model.docvecs.most_similar([x])
for similar_text in most_similar_texts:
print(similar_text[0])
Comme Doc2Vec vectorise également les mots (Word2Vec) en même temps, j'ai essayé de rechercher des mots similaires.
def search_similar_words(words):
for word in words:
print()
print(word + ':')
for result in model.most_similar(positive=word, topn=10):
print(result[0])
model = models.Doc2Vec.load('doc2vec.model')
def search_similar_texts(path):
most_similar_texts = model.docvecs.most_similar(path)
for similar_text in most_similar_texts:
print(similar_text[0])
J'ai essayé de mettre en œuvre une recherche de phrases similaires dans Doc2Vec. J'espère que cela vous aidera.
Seule l'erreur qui s'est produite dans mon environnement, mais je posterai la solution.
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
conda update numpy
.[Word2Vec: puissance incroyable du vecteur de mots qui surprend l'inventeur] [Word2Vec] [Document tutoriel de calcul de similarité utilisant le mécanisme Doc2Vec et le gensim] [Tutoriel] [Que se passe-t-il si vous effectuez un apprentissage automatique avec un roman pixiv [les données du modèle entraîné sont distribuées]] [pixiv] [Utilisez TensorFlow pour vérifier la différence de mouvement en fonction du taux d'apprentissage] [Taux d'apprentissage] [models.doc2vec – Deep learning with paragraph2vec][doc2vec]
<! - Lien-> [Word2Vec]:https://deepage.net/bigdata/machine_learning/2016/09/02/word2vec_power_of_word_vector.html [GitHub]:https://github.com/Foo-x/doc2vec-sample [Tutoriel]: https://deepage.net/machine_learning/2017/01/08/doc2vec.html [pixiv]:http://inside.pixiv.net/entry/2016/09/13/161454 [Taux d'apprentissage]: http://qiita.com/isaac-otao/items/6d44fdc0cfc8fed53657 [doc2vec]:https://radimrehurek.com/gensim/models/doc2vec.html
Recommended Posts