Вычислить меру между ключевыми словами и каждым словом текстового файла - PullRequest
0 голосов
/ 19 июня 2020

У меня есть два файла .txt, один из которых содержит 200 000 слов, а второй - 100 ключевых слов (по одному на каждую строку). Я хочу вычислить косинусное сходство между каждым из 100 ключевых слов и каждым словом из моих 200000 слов и отобразить для каждого ключевого слова 50 слов с наивысшей оценкой.

Вот что я сделал, обратите внимание, что Bertclient - это то, что Я использую для извлечения векторов:

from sklearn.metrics.pairwise import cosine_similarity
from bert_serving.client import BertClient
bc = BertClient()

# Process words
with open("./words.txt", "r", encoding='utf8') as textfile:
    words = textfile.read().split()
    
with open("./100_keywords.txt", "r", encoding='utf8') as keyword_file:
    for keyword in keyword_file:
        vector_key = bc.encode([keyword])
        for w in words:
            vector_word = bc.encode([w])
            cosine_lib = cosine_similarity(vector_key,vector_word)
            print (cosine_lib)

Это продолжает работать, но не останавливается. Есть идеи, как я могу это исправить?

1 Ответ

1 голос
/ 20 июня 2020

Я ничего не знаю о Берте ... но есть что-то подозрительное с импортом и запуском. Я не думаю, что у вас он установлен правильно или что-то в этом роде. Я попытался установить его по пипу и просто запустил это:

from sklearn.metrics.pairwise import cosine_similarity
from bert_serving.client import BertClient
bc = BertClient()
print ('done importing')

, и он так и не закончился. Взгляните на dox для bert и посмотрите, нужно ли что-то еще сделать.

В вашем коде, как правило, лучше сначала выполнить ВСЕ чтение, а затем обработку, поэтому сначала импортируйте оба списка, отдельно проверьте несколько значений, например:

# check first five
print(words[:5])

Кроме того, вам нужно рассмотреть другой способ сравнения вместо вложенных циклов. Теперь вы понимаете, что конвертируете каждое слово в words КАЖДЫЙ РАЗ для каждого ключевого слова, что не обязательно и, вероятно, очень медленно. Я бы порекомендовал вам либо использовать словарь, чтобы связать слово с кодировкой, либо составить список кортежей с (словом, кодировкой) в нем, если вам это удобнее.

Прокомментируйте меня, если это не так Это не имеет смысла после того, как вы запустите Bert.

- Edit -

Вот фрагмент кода, который работает аналогично тому, что вы хотите сделать. Существует множество вариантов хранения результатов и т. Д. c. в зависимости от ваших потребностей, но это должно помочь вам начать с "поддельного берта"

from operator import itemgetter

# fake bert  ... just return something like length
def bert(word):
    return len(word)

# a fake compare function that will compare "bert" conversions
def bert_compare(x, y):
    return abs(x-y)

# Process words
with open("./word_data_file.txt", "r", encoding='utf8') as textfile:
    words = textfile.read().split()

# Process keywords
with open("./keywords.txt", "r", encoding='utf8') as keyword_file:
    keywords = keyword_file.read().split()

# encode the words and put result in dictionary
encoded_words = {}
for word in words:
    encoded_words[word] = bert(word)

encoded_keywords = {}
for word in keywords:
    encoded_keywords[word] = bert(word)

# let's use our bert conversions to find which keyword is most similar in
# length to the word

for word in encoded_words.keys():
    result = []   # make a new result set for each pass
    for kword in encoded_keywords.keys():
        similarity = bert_compare(encoded_words.get(word), encoded_keywords.get(kword))
        # stuff the answer into a tuple that can be sorted
        result.append((word, kword, similarity))
    result.sort(key=itemgetter(2))
    print(f'the keyword with the closest size to {result[0][0]} is {result[0][1]}')
...