эффективный способ вычислить все косинусные сходства предложений - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь сопоставить предложения с наибольшим косинусным сходством в наборе данных, состоящем из 10.000 вопросов, заданных на форуме.Я уже создал алгоритм и вижу отличные результаты.однако вычисление занимает много времени, и это только для одного предложения.Есть ли эффективный способ сопоставить все предложения вместе?Я думаю, цикл for не является достаточным методом.

import re
import math
from collections import Counter
import csv
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

#nltk.download("punkt")
#nltk.download("stopwords")

#print()
#print()
stopwords = set(stopwords.words('english'))
reader = csv.reader(open("/Users/stefan/dev.csv"))
dev = []
for line in reader:
    dev.append(line[1])

reader2 = csv.reader(open("/Users/stefan/test.csv"))
test = []
for line2 in reader2:
    test.append(line2[1])

def get_cosine(vec1, vec2):
    intersection = set(vec1.keys()) & set(vec2.keys())
    numerator = sum([vec1[x] * vec2[x] for x in intersection])

    sum1 = sum([vec1[x]**2 for x in vec1.keys()])
    sum2 = sum([vec2[x]**2 for x in vec2.keys()])
    denominator = math.sqrt(sum1) * math.sqrt(sum2)

    if not denominator:
        return 0.0
    else:
        return float(numerator / denominator)

def text_to_vector(text):
    word_tokens = word_tokenize(text)
    filtered_sentence = [w for w in word_tokens if not w in stop_words]
    #print("the original tokens derived:", word_tokens)
    #print()
    #print("the resulted work tokens derived: ",filtered_sentence)
    return Counter(filtered_sentence)

def get_result(content_a, content_b):
    text1 = content_a
    text2 = content_b

    vector1 = text_to_vector(text1)
    vector2 = text_to_vector(text2)

    cosine_result = get_cosine(vector1, vector2)
    return cosine_result

print("Have a cosine similarity of: ", get_result(dev[1], test[1]))

Результат здесь будет следующим: иметь косинусное сходство: 0,3779644730092272.Тем не менее, это работает только для одного предложения.Когда я попробовал запустить его на первых 5 предложениях, мне уже пришлось ждать 10 минут.Учитывая, что я хочу соответствовать 10.000 предложений, я ищу эффективный способ обработки алгоритма.Я нашел некоторую информацию о многопроцессорной обработке с помощью пула, но я не уверен, как это осуществитьчто у меня сейчас:

finalresult = []
for countnum in range(1, 5):
    testchecker = []
    testresult = []
    for i in range(1, len(test)):
        testresult = get_result(test[countnum], test[i])
        if i != countnum:
            testchecker.append([testresult,countnum,test[countnum], i-1])
    resulttest = max(testchecker, key=lambda x: x[0])
    finalresult.append([resulttest[1]-1, resulttest[2], resulttest[3]])

print(finalresult)

Результат будет таким: Идентификатор, текст и идентификатор другого вопроса, на который он похож.

[[0, 'What are the hottest IT startup companies in Mumbai?', 8808], [1, 'How often do you drink coffee (-based) drinks?', 2103], [2, 'Which contries provide financial help to India?', 1386], [3, 'What are some interesting facts about the NSG?', 3472]]

Есть лиспособ сделать это более эффективным в вычислительном отношении?

...