การทำนายความคล้ายคลึงกันของประโยค


15

ฉันกำลังมองหาที่จะแก้ปัญหาต่อไปนี้: ฉันมีชุดประโยคเป็นชุดข้อมูลของฉันและฉันต้องการที่จะสามารถพิมพ์ประโยคใหม่และค้นหาประโยคที่ประโยคใหม่คล้ายกับในชุดข้อมูล ตัวอย่างจะมีลักษณะดังนี้:

ประโยคใหม่: " I opened a new mailbox"

การทำนายขึ้นอยู่กับชุดข้อมูล:

Sentence                       | Similarity
A dog ate poop                   0%
A mailbox is good                50%
A mailbox was opened by me       80%

ฉันได้อ่านว่าโคไซน์ที่คล้ายคลึงกันสามารถใช้ในการแก้ปัญหาประเภทนี้ที่จับคู่กับ tf-idf (และ RNN ไม่ควรนำการปรับปรุงที่สำคัญไปใช้กับวิธีการพื้นฐาน) หรือword2vecใช้สำหรับปัญหาที่คล้ายกัน สิ่งเหล่านี้มีประโยชน์สำหรับการใช้งานในกรณีนี้หรือไม่ มีเทคนิค / อัลกอริธึมอื่น ๆ ที่จะแก้ปัญหานี้ (โดยเฉพาะกับ Python และ SKLearn แต่ฉันเปิดกว้างเพื่อเรียนรู้เกี่ยวกับ TensorFlow ด้วย)


ตรวจสอบเบอร์ทอย่างแน่นอน นี่คือการดำเนินงานที่ดี มันทำสิ่งที่คุณกำลังมองหาด้วยผลลัพธ์ที่ดีงาม
GioGio

คำตอบ:


26

ปัญหาของคุณสามารถแก้ไขได้ด้วย Word2vec เช่นเดียวกับ Doc2vec Doc2vec จะให้ผลลัพธ์ที่ดีขึ้นเพราะต้องคำนึงถึงประโยคในขณะฝึกอบรมโมเดล

โซลูชัน Doc2vec
คุณสามารถฝึกอบรมรุ่น doc2vec ของคุณตามลิงก์นี้ คุณอาจต้องการดำเนินการขั้นตอนล่วงหน้าบางขั้นตอนเช่นลบคำหยุดทั้งหมด(คำเช่น "the", "an" ฯลฯ ที่ไม่ได้เพิ่มความหมายให้กับประโยคมากนัก) เมื่อคุณฝึกฝนแบบจำลองของคุณคุณสามารถค้นหาประโยคที่คล้ายกันโดยใช้รหัสต่อไปนี้

import gensim  

model = gensim.models.Doc2Vec.load('saved_doc2vec_model')  

new_sentence = "I opened a new mailbox".split(" ")  
model.docvecs.most_similar(positive=[model.infer_vector(new_sentence)],topn=5)

ผล:

[('TRAIN_29670', 0.6352514028549194),
 ('TRAIN_678', 0.6344441771507263),
 ('TRAIN_12792', 0.6202734708786011),
 ('TRAIN_12062', 0.6163255572319031),
 ('TRAIN_9710', 0.6056315898895264)]

ผลดังกล่าวข้างต้นเป็นรายการของ tuples (label,cosine_similarity_score)สำหรับ train[29670]คุณสามารถแมผลประโยคด้วยการทำ

โปรดทราบว่าวิธีการข้างต้นจะให้ผลลัพธ์ที่ดีหากรุ่น doc2vec ของคุณมีงานแต่งงานสำหรับคำที่พบในประโยคใหม่ หากคุณพยายามที่จะได้รับความคล้ายคลึงกันสำหรับประโยคซึ่งพูดพล่อยๆเช่นsdsf sdf f sdf sdfsdffgนั้นมันจะให้ผลลัพธ์น้อย แต่คุณอาจจะไม่ได้เป็นประโยคที่คล้ายกันจริงตามที่แบบจำลองการฝึกอบรมของคุณอาจไม่เห็นคำพูดซึ่งพูดพล่อยๆเหล่านี้ ดังนั้นลองฝึกโมเดลของคุณให้มากที่สุดเท่าที่จะเป็นไปได้เพื่อรวมประโยคต่างๆเพื่อให้ได้ผลลัพธ์ที่ดียิ่งขึ้น

Word2vec Solution
หากคุณใช้ word2vec คุณจะต้องคำนวณเวกเตอร์เฉลี่ยสำหรับทุกคำในทุกประโยคและใช้ความคล้ายคลึงโคไซน์ระหว่างเวกเตอร์

def avg_sentence_vector(words, model, num_features, index2word_set):
    #function to average all words vectors in a given paragraph
    featureVec = np.zeros((num_features,), dtype="float32")
    nwords = 0

    for word in words:
        if word in index2word_set:
            nwords = nwords+1
            featureVec = np.add(featureVec, model[word])

    if nwords>0:
        featureVec = np.divide(featureVec, nwords)
    return featureVec

คำนวณความคล้ายคลึงกัน

from sklearn.metrics.pairwise import cosine_similarity

#get average vector for sentence 1
sentence_1 = "this is sentence number one"
sentence_1_avg_vector = avg_sentence_vector(sentence_1.split(), model=word2vec_model, num_features=100)

#get average vector for sentence 2
sentence_2 = "this is sentence number two"
sentence_2_avg_vector = avg_sentence_vector(sentence_2.split(), model=word2vec_model, num_features=100)

sen1_sen2_similarity =  cosine_similarity(sentence_1_avg_vector,sentence_2_avg_vector)

ขอขอบคุณ! จะใช้งานได้ในช่วงสุดสัปดาห์ แต่วิธีการแก้ปัญหาดูจะสมบูรณ์แบบตั้งแต่แรก รุ่งโรจน์!
lte__

เราจำเป็นต้องทำประโยคให้เหมาะสำหรับการฝึกอบรมหรือไม่
pyd

ใช่ @pyd เราต้องทำ! sentence_1.split()ทำเช่นเดียวกัน
Harman

4

ระยะทางของผู้เสนอญัตติ (WMD)เป็นอัลกอริทึมสำหรับการค้นหาระยะห่างระหว่างประโยค WMD ตั้งอยู่บนคำว่า embeddings (เช่น word2vec) ซึ่งเข้ารหัสความหมายของคำในรูปแบบเวกเตอร์ที่มีความหนาแน่นสูง

ระยะทาง WMD วัดความแตกต่างระหว่างเอกสารข้อความสองฉบับเป็นระยะทางขั้นต่ำที่คำฝังตัวของเอกสารหนึ่งต้อง "เดินทาง" เพื่อเข้าถึงคำที่ฝังของเอกสารอื่น

ตัวอย่างเช่น:

ป้อนคำอธิบายรูปภาพที่นี่ ที่มา: กระดาษ "จากโปรแกรม Word เพื่อจัดทำเอกสารระยะทาง"

แพคเกจ gensimมีการดำเนินการ WMD

สำหรับปัญหาของคุณคุณจะเปรียบเทียบประโยคที่ป้อนเข้ากับประโยคอื่นทั้งหมดและส่งคืนประโยคที่มี WMD ต่ำสุด


2

คุณสามารถลองวิธีแก้ปัญหาอย่างง่าย ๆ โดยใช้sklearnและมันจะทำงานได้ดี

  • ใช้tfidfvectorizerเพื่อให้ได้เวกเตอร์ที่เป็นตัวแทนของแต่ละข้อความ

  • ปรับ vectorizer ให้พอดีกับข้อมูลของคุณโดยลบคำหยุด

  • แปลงรายการใหม่ด้วย Vectorizer ที่ผ่านการฝึกอบรมมาก่อน

  • คำนวณความคล้ายคลึงโคไซน์ระหว่างการแทนค่านี้กับการแทนค่าองค์ประกอบในชุดข้อมูลของคุณ

หากคุณมีชุดข้อมูลฮิวจ์คุณสามารถทำคลัสเตอร์ได้ (ตัวอย่างเช่นใช้ KMeans จาก scikit Learn) หลังจากได้รับการเป็นตัวแทนและก่อนที่จะทำนายข้อมูลใหม่

รหัสนี้ทำตามขั้นตอนเหล่านี้ทั้งหมด คุณสามารถตรวจสอบบน GitHub ของฉันrepo

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
import numpy

texts = ["This first text talks about houses and dogs",
        "This is about airplanes and airlines",
        "This is about dogs and houses too, but also about trees",
        "Trees and dogs are main characters in this story",
        "This story is about batman and superman fighting each other", 
        "Nothing better than another story talking about airplanes, airlines and birds",
        "Superman defeats batman in the last round"]

# vectorization of the texts
vectorizer = TfidfVectorizer(stop_words="english")
X = vectorizer.fit_transform(texts)
# used words (axis in our multi-dimensional space)
words = vectorizer.get_feature_names()
print("words", words)


n_clusters=3
number_of_seeds_to_try=10
max_iter = 300
number_of_process=2 # seads are distributed
model = KMeans(n_clusters=n_clusters, max_iter=max_iter, n_init=number_of_seeds_to_try, n_jobs=number_of_process).fit(X)

labels = model.labels_
# indices of preferible words in each cluster
ordered_words = model.cluster_centers_.argsort()[:, ::-1]

print("centers:", model.cluster_centers_)
print("labels", labels)
print("intertia:", model.inertia_)

texts_per_cluster = numpy.zeros(n_clusters)
for i_cluster in range(n_clusters):
    for label in labels:
        if label==i_cluster:
            texts_per_cluster[i_cluster] +=1 

print("Top words per cluster:")
for i_cluster in range(n_clusters):
    print("Cluster:", i_cluster, "texts:", int(texts_per_cluster[i_cluster])),
    for term in ordered_words[i_cluster, :10]:
        print("\t"+words[term])

print("\n")
print("Prediction")

text_to_predict = "Why batman was defeated  by superman so easy?"
Y = vectorizer.transform([text_to_predict])
predicted_cluster = model.predict(Y)[0]
texts_per_cluster[predicted_cluster]+=1

print(text_to_predict)
print("Cluster:", predicted_cluster, "texts:", int(texts_per_cluster[predicted_cluster])),
for term in ordered_words[predicted_cluster, :10]:
print("\t"+words[term])

เฮ้มันจะดีจริงๆถ้าคุณสามารถแสดงตัวอย่างของการใช้โคซิเลียเรียมโคไซน์?
Tido

เฮ้ส่วนที่ 2 ไม่ควรมาก่อนพอดีกับข้อมูลอัลและใช้มันเพื่อแปลงข้อความแต่ละตัวใช่ไหม มันจะดีจริงๆถ้าคุณสามารถแสดงตัวอย่างของการใช้โคซิเลียเรียมโคไซน์?
Tido

1

มีการทำงานเมื่อเร็ว ๆ นี้บางส่วนจาก Variational Auto-Encoder ในรุ่น RNN การสร้างประโยคจากพื้นที่อย่างต่อเนื่องกับการใช้งาน pytorch: รหัส GitHub
พวกเขาสามารถบีบอัดความหมายของประโยคทั่วโลกในเชิงความหมายของประโยคในพื้นที่ที่ซ่อนเร้นซึ่งอาจจะมีตัวแปรสุ่มอิสระ 10 ถึง 30 อัน จำกัด (การกระจายแบบแยกตัวประกอบ)
ความคิดแปลกใหม่ในงานนี้พวกเขาแก้ไขระหว่างสองประโยค และผลลัพธ์ก็น่าทึ่งทีเดียว


0

โซลูชันทั่วไปประกอบด้วยขั้นตอนดังต่อไปนี้ -

  1. Featurization หรือ embeddings คำของประโยค
  2. การนำเมทริกความคล้ายคลึงกันมาใช้ในประโยค

nXnnXdd

เมื่อคุณได้รับการฝังคำของแต่ละคำคุณสามารถใช้การวัดความคล้ายคลึงกันใด ๆ เช่นความคล้ายคลึงโคไซน์ ฯลฯ ในแต่ละประโยคเพื่อวัดความคล้ายคลึงกันกับผู้อื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.