Dự đoán tương tự câu


15

Tôi đang tìm cách giải quyết vấn đề sau: Tôi có một bộ câu làm tập dữ liệu của mình và tôi muốn có thể gõ một câu mới và tìm câu mà câu mới giống với câu nhất trong tập dữ liệu. Một ví dụ sẽ giống như:

Câu mới: " I opened a new mailbox"

Dự đoán dựa trên tập dữ liệu:

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

Tôi đã đọc rằng sự tương tự cosine có thể được sử dụng để giải quyết các loại vấn đề này được ghép nối với tf-idf (và RNN không nên mang lại sự cải thiện đáng kể cho các phương thức cơ bản), hoặc sử dụng word2vec cho các vấn đề tương tự. Là những người thực sự khả thi để sử dụng trong trường hợp cụ thể, quá? Có bất kỳ kỹ thuật / thuật toán nào khác để giải quyết vấn đề này (tốt nhất là với Python và SKLearn, nhưng tôi cũng sẵn sàng tìm hiểu về TensorFlow)?


Chắc chắn kiểm tra Bert . Đây là một thực hiện tốt đẹp . Nó thực hiện chính xác những gì bạn đang tìm kiếm với kết quả khá tốt
GioGio

Câu trả lời:


25

Vấn đề của bạn có thể được giải quyết với Word2vec cũng như Doc2vec. Doc2vec sẽ cho kết quả tốt hơn vì nó tính đến các câu trong khi đào tạo mô hình.

Giải pháp Doc2vec
Bạn có thể huấn luyện mô hình doc2vec của mình theo liên kết này . Bạn có thể muốn thực hiện một số bước xử lý trước như xóa tất cả các từ dừng (các từ như "the", "an", v.v. không thêm nhiều ý nghĩa cho câu). Khi bạn đã đào tạo mô hình của mình, bạn có thể tìm thấy các câu tương tự bằng cách sử dụng mã sau đây.

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)

Các kết quả:

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

Các kết quả trên là danh sách các bộ dữ liệu cho (label,cosine_similarity_score). Bạn có thể ánh xạ đầu ra thành câu bằng cách làm train[29670].

Xin lưu ý rằng cách tiếp cận trên sẽ chỉ cho kết quả tốt nếu mô hình doc2vec của bạn có chứa các từ nhúng cho các từ được tìm thấy trong câu mới. Nếu bạn cố gắng có được sự giống nhau cho một số câu vô nghĩa như thế sdsf sdf f sdf sdfsdffg, nó sẽ cho bạn một vài kết quả, nhưng đó có thể không phải là những câu tương tự thực tế vì mô hình được đào tạo của bạn có thể không nhìn thấy những từ ngữ vô nghĩa này trong khi đào tạo mô hình. Vì vậy, hãy cố gắng đào tạo mô hình của bạn trên càng nhiều câu càng tốt để kết hợp càng nhiều từ để có kết quả tốt hơn.

Giải pháp Word2vec
Nếu bạn đang sử dụng word2vec, bạn cần tính toán vectơ trung bình cho tất cả các từ trong mỗi câu và sử dụng độ tương tự cosine giữa các vectơ.

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

Tính tương tự

#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)

Cảm ơn bạn! Sẽ làm việc này vào cuối tuần, nhưng giải pháp có vẻ hoàn hảo ngay từ cái nhìn đầu tiên. Thanh danh!
lte__

chúng ta có cần token hóa các câu để đào tạo không
pyd

vâng @pyd chúng tôi phải! sentence_1.split()làm như vậy.
Harman

4

Khoảng cách của Word Mover (WMD) distance là một thuật toán để tìm khoảng cách giữa các câu. WMD dựa trên các từ nhúng (ví dụ: word2vec) mã hóa ý nghĩa ngữ nghĩa của các từ thành các vectơ dày đặc.

Khoảng cách WMD đo lường sự khác biệt giữa hai tài liệu văn bản là khoảng cách tối thiểu mà các từ được nhúng của một tài liệu cần phải "di chuyển" để đến các từ được nhúng của tài liệu khác.

Ví dụ:

nhập mô tả hình ảnh ở đây Nguồn: Tài liệu "Từ nhúng nhúng đến khoảng cách tài liệu"

Các gói gensimthực hiện WMD .

Đối với vấn đề của bạn, bạn sẽ so sánh câu đã nhập với tất cả các câu khác và trả về câu có WMD thấp nhất.


2

Bạn có thể thử một giải pháp dễ dàng bằng cách sử dụng sklearn và nó sẽ hoạt động tốt.

  • Sử dụng tfidfvectorizer để có được một đại diện vector của mỗi văn bản

  • Điều chỉnh vectorizer với dữ liệu của bạn, loại bỏ các từ dừng.

  • Chuyển đổi mục nhập mới với vectorizer được đào tạo trước đó

  • Tính toán độ tương tự cosin giữa biểu diễn này và mỗi biểu diễn của các phần tử trong tập dữ liệu của bạn.

Nếu bạn có bộ dữ liệu hugh, bạn có thể phân cụm nó (ví dụ: sử dụng KMeans từ scikit learn) sau khi có được đại diện và trước khi dự đoán về dữ liệu mới.

Mã này thực hiện tất cả các bước. Bạn có thể kiểm tra nó trên repo github của tôi .

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])

Này, sẽ thật tuyệt nếu bạn có thể đưa ra một ví dụ về việc sử dụng similiairity cosine?
Tido

Này, không nên là phần 2 đến trước, phù hợp với dữ liệu al và sử dụng phần này để chuyển đổi từng văn bản? Sẽ thật sự tuyệt vời nếu bạn có thể đưa ra một ví dụ về việc sử dụng similiairity cosine?
Tido

1

Có một số công việc gần đây dựa trên Bộ mã hóa tự động biến đổi trong các mô hình RNN. Tạo các câu từ một không gian liên tục , với các triển khai pytorch: mã github .
họ quản lý để nén tính năng ngữ nghĩa, cú pháp của một câu vào một không gian tiềm ẩn được biểu thị bằng một số biến ngẫu nhiên độc lập 10 đến 30 hữu hạn (phân phối theo yếu tố).
ý tưởng mới lạ trong tác phẩm này, chúng nội suy giữa hai câu. và kết quả khá tuyệt vời.


0

Giải pháp tổng quát bao gồm các bước sau -

  1. Featurization hoặc nhúng từ của một câu.
  2. Áp dụng một số liệu tương tự giữa các câu.

Đối với 1. word2vec là lựa chọn tốt nhất nhưng nếu bạn không muốn sử dụng word2vec, bạn có thể thực hiện một số phép tính gần đúng với nó. Một cách là tạo ra một ma trận các từ xuất hiện từ các câu được đào tạo của bạn theo sau bằng cách áp dụng TSVD trên đó. Ma trận coccurance củanXn chiều khi chuyển đổi thành nXd chiều, làm cho vectơ từ d kích thước.

Khi bạn nhận được từ nhúng của mỗi từ, bạn có thể áp dụng bất kỳ số liệu tương tự nào như độ tương tự cosine, v.v. trên mỗi câu để đo độ tương tự với các từ khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.