अजगर के साथ gensim के word2vec मॉडल का उपयोग करके वाक्य समानता की गणना कैसे करें


125

Gensim Word2Vec के अनुसार , मैं 2 शब्दों के साथ समानता की गणना करने के लिए gensim पैकेज में word2vec मॉडल का उपयोग कर सकता हूं।

जैसे

trained_model.similarity('woman', 'man') 
0.73723527

हालाँकि, word2vec मॉडल वाक्य समानता की भविष्यवाणी करने में विफल रहता है। मैं एलएसआई मॉडल को गेंसिम में वाक्य समानता के साथ खोजता हूं, लेकिन, ऐसा नहीं लगता कि इसे वर्ड 2vec मॉडल के साथ जोड़ा जा सकता है। मेरे पास प्रत्येक वाक्य के कॉर्पस की लंबाई बहुत लंबी नहीं है (10 शब्दों से कम)। तो, क्या लक्ष्य प्राप्त करने के लिए कोई सरल तरीके हैं?


4
इस मुद्दे पर चर्चा करते हुए एक एसीएल ट्यूटोरियल है (अन्य बातों के अलावा): youtube.com/watch?v=_ASOqXiWBVo&feature=youtu.be
Emiel

7
अब आप gensim के doc2vec का उपयोग करें और एक ही मॉड्यूल से सजा समानता प्राप्त कर सकते हैं
kampta

@kampta नमस्ते क्या आप किसी भी पोस्ट का सुझाव देंगे जो कार्यान्वयन को दर्शाता है?
Ian_De_Oliveira

जवाबों:


86

यह वास्तव में एक बहुत ही चुनौतीपूर्ण समस्या है जो आप पूछ रहे हैं। कम्प्यूटिंग वाक्य समानता को वाक्य के एक व्याकरणिक मॉडल के निर्माण की आवश्यकता है, समतुल्य संरचनाओं को समझना (जैसे "वह कल दुकान पर चला गया" और "कल, वह दुकान पर चला गया"), समानता केवल सर्वनामों और क्रियाओं में ही नहीं, बल्कि उचित संज्ञाएं, वास्तविक पाठ्य उदाहरणों के बहुत सारे सांख्यिकीय सह-संबंध / संबंध खोजना।

सबसे आसान काम जो आप कर सकते हैं - हालांकि मुझे नहीं पता कि यह कितना अच्छा प्रदर्शन करेगा और यह निश्चित रूप से आपको इष्टतम परिणाम नहीं देगा - सबसे पहले सभी "स्टॉप" शब्दों ("जैसे", "ए" को हटाना होगा) ", आदि जो वाक्य में बहुत अधिक अर्थ नहीं जोड़ते हैं) और फिर दोनों वाक्यों पर शब्द 2vec चलाते हैं, एक वाक्य में वैक्टर को जोड़ते हैं, दूसरे वाक्य में वैक्टर को जोड़ते हैं, और फिर बीच का अंतर पाते हैं रकम। शब्द-वार अंतर करने के बजाय उन्हें संक्षेप में लिखकर, आप कम से कम शब्द क्रम के अधीन नहीं होंगे। यह कहा जा रहा है, यह बहुत तरीकों से विफल होगा और किसी भी तरह से एक अच्छा समाधान नहीं है (हालांकि इस समस्या का अच्छा समाधान लगभग हमेशा एनएलपी, मशीन सीखने और अन्य चतुराई की कुछ राशि शामिल है)।

तो, संक्षिप्त उत्तर है, नहीं, ऐसा करने का कोई आसान तरीका नहीं है (कम से कम इसे अच्छी तरह से नहीं करने के लिए)।


4
मेरे विचार से आप सही है। सरलतम विधि शब्दों के सभी वैक्टरों को एक वाक्य में संचित करना और रकम के बीच का अंतर खोजना है। वैसे, क्या यह सरल विधि शब्द गणना से प्रभावित होगी? क्योंकि एक वाक्य में जितने अधिक शब्द होंगे, उतने ही अधिक हिस्टोग्राम को अभिव्यक्त किया जाएगा।
zhfkt

2
@zhfkt, सबसे अधिक संभावना है, हाँ। तो आपको शब्दों की संख्या या कुछ ऐसा करने की आवश्यकता हो सकती है जो कारक को बाहर करने की कोशिश करें। किसी भी तरह, इस तरह के किसी भी अनुमान को गंभीर रूप से दोषपूर्ण माना जाएगा।
माइकल आरोन सफायन


75

चूँकि आप gensim का उपयोग कर रहे हैं, आपको संभवतः इसे doc2vec कार्यान्वयन का उपयोग करना चाहिए। doc2vec वाक्यांश-, वाक्य-, और दस्तावेज़-स्तर के लिए शब्द 2vec का विस्तार है। यह एक बहुत ही सरल विस्तार है, यहाँ वर्णित है

http://cs.stanford.edu/~quocle/paragraph_vector.pdf

Gensim अच्छा है क्योंकि यह सहज, तेज और लचीला है। क्या महान है कि आप आधिकारिक वर्ड 2vec पेज से प्रीट्रेन किए गए शब्द एम्बेडिंग को पकड़ सकते हैं और gensim के Doc2Vec मॉडल की syn0 परत को उजागर किया जाता है ताकि आप इन उच्च गुणवत्ता वाले वैक्टर के साथ शब्द एम्बेडिंग को बीज कर सकें!

GoogleNews-vectors-negative300.bin.gz ( Google कोड में लिंक किया गया )

मुझे लगता है कि gensim निश्चित रूप से सबसे आसान (और अब तक मेरे लिए, सबसे अच्छा) एक वेक्टर अंतरिक्ष में एक वाक्य एम्बेड करने के लिए उपकरण है।

ऊपर दिए गए Le & Mikolov के पेपर में प्रस्तावित की तुलना में अन्य वाक्य-से-वेक्टर तकनीक मौजूद हैं। स्टैनफोर्ड से सोचर और मैनिंग निश्चित रूप से इस क्षेत्र में काम करने वाले सबसे प्रसिद्ध शोधकर्ताओं में से दो हैं। उनका काम रचना के सिद्धांत पर आधारित है - वाक्य के शब्दार्थ से आते हैं:

1. semantics of the words

2. rules for how these words interact and combine into phrases

उन्होंने वाक्य-स्तर के निरूपण के निर्माण के लिए रचनाधर्मिता का उपयोग करने के लिए कुछ ऐसे मॉडल (तेजी से और अधिक जटिल होते हुए) प्रस्तावित किए हैं।

2011 - पुनरावर्ती ऑटोकेनोडर को खोलना (बहुत तुलनात्मक रूप से सरल। यदि रुचि हो तो यहां शुरू करें)

2012 - मैट्रिक्स-वेक्टर तंत्रिका नेटवर्क

2013 - तंत्रिका टेंसर नेटवर्क

2015 - ट्री एलएसटीएम

उसके कागजात socher.org पर उपलब्ध हैं। इन मॉडलों में से कुछ उपलब्ध हैं, लेकिन मैं अभी भी gensim के doc2vec की सिफारिश करूंगा। एक के लिए, 2011 URAE विशेष रूप से शक्तिशाली नहीं है। इसके अलावा, यह न्यूज़-वाई डेटा को पैराफ्रेसिंग के लिए उपयुक्त वेट के साथ ढाला जाता है। वह जो कोड प्रदान करता है, वह आपको नेटवर्क को वापस करने की अनुमति नहीं देता है। आप अलग-अलग शब्द वैक्टर में स्वैप भी नहीं कर सकते हैं, इसलिए आप ट्यूरियन से 2011 के पूर्व-वर्ड 2vec एम्बेडिंग के साथ फंस गए हैं। ये वैक्टर निश्चित रूप से शब्द 2vec या GloVe's के स्तर पर नहीं हैं।

ट्री LSTM के साथ अभी तक काम नहीं किया है, लेकिन यह बहुत आशाजनक लगता है!

tl; डॉ। हाँ, गेंसिम के doc2vec का उपयोग करें। लेकिन अन्य तरीके मौजूद हैं!


क्या आपको इस बारे में अधिक जानकारी है कि doc2vec मॉडल को पहले से प्रशिक्षित word2vec मानों से कैसे जोड़ा जाए?
साइमन एच

42

यदि आप word2vec का उपयोग कर रहे हैं, तो आपको प्रत्येक वाक्य / दस्तावेज़ में सभी शब्दों के लिए औसत वेक्टर की गणना करने की आवश्यकता है और वैक्टर के लिए कोसाइन समानता का उपयोग करें:

import numpy as np
from scipy import spatial

index2word_set = set(model.wv.index2word)

def avg_feature_vector(sentence, model, num_features, index2word_set):
    words = sentence.split()
    feature_vec = np.zeros((num_features, ), dtype='float32')
    n_words = 0
    for word in words:
        if word in index2word_set:
            n_words += 1
            feature_vec = np.add(feature_vec, model[word])
    if (n_words > 0):
        feature_vec = np.divide(feature_vec, n_words)
    return feature_vec

समानता की गणना करें:

s1_afv = avg_feature_vector('this is a sentence', model=model, num_features=300, index2word_set=index2word_set)
s2_afv = avg_feature_vector('this is also sentence', model=model, num_features=300, index2word_set=index2word_set)
sim = 1 - spatial.distance.cosine(s1_afv, s2_afv)
print(sim)

> 0.915479828613

4
क्या आप कृपया index2word_set और model.index2word पर अधिक स्पष्टीकरण दे सकते हैं? धन्यवाद।
द एडेडबॉय

3
ध्यान दें कि "औसत वेक्टर" की गणना एक मनमानी विकल्प के रूप में होती है जितना कि यह बिल्कुल भी गणना नहीं करता है।
gented

2
मैं हैरान हूं कि यह शीर्ष उत्तर क्यों नहीं है, यह काफी अच्छी तरह से काम करता है और इसमें अनुक्रम समस्या नहीं है जो औसत विधि है।
असीम

यह वह उत्तर है जिसकी मुझे तलाश थी। मेरे मुद्दे का समाधान करें। समाधान के लिए धन्यवाद
iRunner

25

आप Word Mover की दूरी एल्गोरिथ्म का उपयोग कर सकते हैं। यहाँ WMD के बारे में एक आसान वर्णन है

#load word2vec model, here GoogleNews is used
model = gensim.models.KeyedVectors.load_word2vec_format('../GoogleNews-vectors-negative300.bin', binary=True)
#two sample sentences 
s1 = 'the first sentence'
s2 = 'the second text'

#calculate distance between two sentences using WMD algorithm
distance = model.wmdistance(s1, s2)

print ('distance = %.3f' % distance)

Ps: यदि आपको आयात pyemd लाइब्रेरी के बारे में कोई त्रुटि आती है, तो आप इसे निम्न आदेश का उपयोग करके स्थापित कर सकते हैं:

pip install pyemd

2
मैंने पहले WMD का उपयोग किया था और यह अच्छी तरह से काम करता है, हालांकि यह बड़े कॉर्पस पर चोक होगा। सॉफ्टकॉइनसिमिलिटी की कोशिश करें। इसके अलावा gensim में पाया गया ( twitter.com/gensim_py/status/963382840934195200 )
क्रिंकर

1
WMD बहुत तेज़ नहीं है, लेकिन जब आप एक कॉर्पस क्वेरी करना चाहते हैं।
अमर्त्य

18

एक बार जब आप शब्द वैक्टर के दो सेट की राशि की गणना करते हैं, तो आपको वैक्टर के बीच कोसाइन लेना चाहिए, न कि अंतर। सामान्यीकृत दो वैक्टर के डॉट उत्पाद को ले कर कॉशन की गणना की जा सकती है। इस प्रकार, शब्द गणना एक कारक नहीं है।


1
क्या आप यह करने के लिए कि मैं कैसे कर रहा हूँ (मैं gensim / अजगर का उपयोग नहीं कर रहा हूँ) पर थोड़ा सा छद्मकोड प्रदान कर सकता हूं
dcsan

13

शब्दों की एक सूची लेने और उनकी समानता की तुलना करने के प्रलेखन से एक समारोह है ।

s1 = 'This room is dirty'
s2 = 'dirty and disgusting room' #corrected variable name

distance = model.wv.n_similarity(s1.lower().split(), s2.lower().split())

12

मैं मौजूदा समाधान को उन लोगों की मदद करने के लिए अद्यतन करना चाहूंगा जो वाक्यों की शब्दार्थ समानता की गणना करने जा रहे हैं।

चरण 1:

जेनसिम का उपयोग करके उपयुक्त मॉडल को लोड करें और वाक्य में शब्दों के लिए वैक्टर शब्द की गणना करें और उन्हें शब्द सूची के रूप में संग्रहीत करें

चरण 2: वाक्य वेक्टर की गणना

वाक्यों के बीच शब्दार्थ समानता की गणना पहले मुश्किल थी लेकिन हाल ही में एक पेपर जिसका नाम है " A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SENTENCE EMBEDDINGS " प्रस्तावित किया गया था जो वाक्य में शब्द वैक्टरों के भारित औसत की गणना करके एक सरल दृष्टिकोण का सुझाव देता है और फिर हटा देता है। अपने पहले मुख्य घटक पर औसत वैक्टर के अनुमान। शब्द w का वजन एक / (a ​​+ p (w)) एक पैरामीटर और p (w) के साथ है (अनुमानित) शब्द आवृत्ति जिसे चिकनी व्युत्क्रम आवृत्ति कहा जाता है .इस विधि का प्रदर्शन काफी बेहतर है।

एसआईएफ (चिकनी व्युत्क्रम आवृत्ति) का उपयोग करके वाक्य वेक्टर की गणना करने के लिए एक सरल कोड कागज में प्रस्तावित विधि दी गई है है

चरण 3: स्केलेरिन cosine_similarity का उपयोग वाक्यों के लिए दो वैक्टर लोड करें और समानता की गणना करें।

यह वाक्य समानता की गणना करने के लिए सबसे सरल और कुशल तरीका है।


2
बहुत अच्छा पेपर। नोट: SIF कार्यान्वयन के लिंक के लिए get_word_frequency () विधि लिखने की आवश्यकता होती है, जिसे आसानी से पायथन काउंटर () का उपयोग करके पूरा किया जा सकता है और कुंजियों के साथ एक तानाशाही लौटाया जा सकता है: अनूठे शब्द w, मान: # w / # कुल डॉक लेन
Quetzalcoatl

8

मैं निम्नलिखित विधि का उपयोग कर रहा हूं और यह अच्छी तरह से काम करता है। आपको पहले एक POSTagger को चलाने की आवश्यकता है और फिर स्टॉप शब्दों (निर्धारक, संयोजन, ...) से छुटकारा पाने के लिए अपनी सजा को फ़िल्टर करना होगा। मैं TextBlob APTagger की सलाह देता हूं । फिर आप वाक्य में प्रत्येक शब्द सदिश का अर्थ लेकर एक word2vec बनाते हैं। Gemsim word2vec में n_similarity विधि वास्तव में शब्दों की तुलना करने के दो सेट से पारित करने की अनुमति देकर करता है।


वैक्टर बनाम उन्हें जोड़ने के लिए वाक्य वेक्टर बनाने के बीच क्या अंतर है?
15αrΚhικ

1
अंतर यह है कि वेक्टर का आकार सभी वाक्यों के लिए तय किया गया है
लेक्चिटिटो

जब तक आप कॉशन समानता का उपयोग करते हैं तब तक कोई अंतर नहीं है। @lechatpito वेक्टर आकार के साथ कुछ नहीं करना है। वैक्टर सम्‍मिलित हैं, सम्‍मिलित नहीं।
वोक

6

वाक्यांश या वाक्यों जैसे पाठ के लंबे टुकड़ों की तुलना करने की समस्या को हल करने के उद्देश्य से Word2Vec के विस्तार हैं। उनमें से एक अनुच्छेद 2vec या doc2vec है।

"बांटे गए प्रतिनिधि और दस्तावेज़ों के प्रतिनिधि" http://cs.stanford.edu/~quocle/paragraph_vector.pdf

http://rare-technologies.com/doc2vec-tutorial/


2
यह शीघ्र ही ध्यान देने योग्य है कि प्रस्तुत एल्गोरिथ्म कैसे काम करता है। आप मूल रूप से प्रत्येक उच्चारण में एक अद्वितीय "टोकन" जोड़ते हैं और शब्द 2vec वैक्टर की गणना करते हैं। अंत में आपको कॉर्पस में आपके प्रत्येक शब्द के लिए वैक्टर शब्द मिलेगा (बशर्ते आप सभी शब्दों के लिए पूछें, अद्वितीय शब्द भी)। उच्चारण में प्रत्येक अद्वितीय "टोकन" उस उच्चारण का प्रतिनिधित्व करेगा। पेपर में प्रस्तुत परिणामों के बारे में कुछ विवाद है लेकिन यह एक और कहानी है।
व्लादिस्लाव्स डोवलगेक्स

5

Gensim पैरा एम्बेडिंग के लिए Doc2Vec नामक मॉडल को लागू करता है

IPython पुस्तिकाओं के रूप में अलग-अलग ट्यूटोरियल प्रस्तुत किए गए हैं:

एक अन्य विधि Word2Vec और Word Mover की दूरी (WMD) पर निर्भर करेगी , जैसा कि इस ट्यूटोरियल में दिखाया गया है:

एक वैकल्पिक समाधान औसत वैक्टर पर भरोसा करना होगा:

from gensim.models import KeyedVectors
from gensim.utils import simple_preprocess    

def tidy_sentence(sentence, vocabulary):
    return [word for word in simple_preprocess(sentence) if word in vocabulary]    

def compute_sentence_similarity(sentence_1, sentence_2, model_wv):
    vocabulary = set(model_wv.index2word)    
    tokens_1 = tidy_sentence(sentence_1, vocabulary)    
    tokens_2 = tidy_sentence(sentence_2, vocabulary)    
    return model_wv.n_similarity(tokens_1, tokens_2)

wv = KeyedVectors.load('model.wv', mmap='r')
sim = compute_sentence_similarity('this is a sentence', 'this is also a sentence', wv)
print(sim)

अंत में, यदि आप टेंसरफ़्लो चला सकते हैं, तो आप कोशिश कर सकते हैं: https://tfhub.dev/google/universal-sentence-encoder/2


4

मैंने पिछले उत्तरों द्वारा दिए गए तरीकों की कोशिश की है। यह काम करता है, लेकिन इसका मुख्य दोष यह है कि वाक्य जितनी बड़ी होंगे उतनी ही अधिक होगी (समानता की गणना करने के लिए मैं किसी भी दो वाक्यों के दो माध्य एम्बेडिंग के कोसाइन स्कोर का उपयोग करता हूं) क्योंकि शब्द अधिक सकारात्मक अर्थ प्रभाव है। वाक्य में जोड़ा जाएगा।

मैंने सोचा कि मुझे अपना दिमाग बदल देना चाहिए और इस पेपर और इस अध्ययन में दिए गए वाक्य का उपयोग करना चाहिए ।


3

फेसबुक रिसर्च ग्रुप ने InferSent Results नाम से एक नया समाधान जारी किया और Github पर कोड प्रकाशित किए गए हैं, उनके रेपो की जांच करें। यह बहुत बढ़िया है। मैं इसका उपयोग करने की योजना बना रहा हूं। https://github.com/facebookresearch/InferSent

उनका कागज https://arxiv.org/abs/1705.02364 सार: कई आधुनिक एनएलपी सिस्टम शब्द एम्बेडिंग पर भरोसा करते हैं, जो पहले आधार सुविधाओं के रूप में बड़े कॉर्पोरा पर एक असुरक्षित तरीके से प्रशिक्षित होते हैं। हालांकि, वाक्यों जैसे पाठ की बड़ी मात्रा के लिए एम्बेडिंग प्राप्त करने का प्रयास हालांकि इतना सफल नहीं रहा है। वाक्य के अप्रकाशित अभ्यावेदन सीखने के कई प्रयास व्यापक रूप से अपनाए जाने के लिए संतोषजनक पर्याप्त प्रदर्शन तक नहीं पहुंचे हैं। इस पत्र में, हम दिखाते हैं कि कैसे स्टैनफोर्ड नेचुरल लैंग्वेज इनफेरेंस डेटासेट के पर्यवेक्षित डेटा का उपयोग करके प्रशिक्षित सार्वभौमिक वाक्य निरूपण, ट्रांसफर कार्यों की एक विस्तृत श्रृंखला पर SkipTought वैक्टर जैसे असुरक्षित तरीकों को लगातार बेहतर बना सकते हैं। बहुत कुछ ऐसा है कि कैसे कंप्यूटर विज़न इमेजनेट का उपयोग करता है ताकि सुविधाएँ प्राप्त की जा सकें, जिसे बाद में अन्य कार्यों में स्थानांतरित किया जा सकता है, हमारा काम अन्य एनएलपी कार्यों के लिए स्थानांतरण सीखने के लिए प्राकृतिक भाषा की उपयुक्तता को इंगित करता है। हमारा एनकोडर सार्वजनिक रूप से उपलब्ध है।


3

यदि Word2Vec का उपयोग नहीं कर रहे हैं तो हमारे पास एम्बेड के लिए BERT का उपयोग करके इसे खोजने के लिए अन्य मॉडल है। नीचे संदर्भ लिंक https://github.com/UKPLab/sentence-transformers हैं

pip install -U sentence-transformers

from sentence_transformers import SentenceTransformer
import scipy.spatial

embedder = SentenceTransformer('bert-base-nli-mean-tokens')

# Corpus with example sentences
corpus = ['A man is eating a food.',
          'A man is eating a piece of bread.',
          'The girl is carrying a baby.',
          'A man is riding a horse.',
          'A woman is playing violin.',
          'Two men pushed carts through the woods.',
          'A man is riding a white horse on an enclosed ground.',
          'A monkey is playing drums.',
          'A cheetah is running behind its prey.'
          ]
corpus_embeddings = embedder.encode(corpus)

# Query sentences:
queries = ['A man is eating pasta.', 'Someone in a gorilla costume is playing a set of drums.', 'A cheetah chases prey on across a field.']
query_embeddings = embedder.encode(queries)

# Find the closest 5 sentences of the corpus for each query sentence based on cosine similarity
closest_n = 5
for query, query_embedding in zip(queries, query_embeddings):
    distances = scipy.spatial.distance.cdist([query_embedding], corpus_embeddings, "cosine")[0]

    results = zip(range(len(distances)), distances)
    results = sorted(results, key=lambda x: x[1])

    print("\n\n======================\n\n")
    print("Query:", query)
    print("\nTop 5 most similar sentences in corpus:")

    for idx, distance in results[0:closest_n]:
        print(corpus[idx].strip(), "(Score: %.4f)" % (1-distance))

अन्य लिंक https://github.com/hanxiao/bert-as-service का अनुसरण करने के लिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.