首页 > 解决方案 > 计算关键字和文本文件的每个单词之间的度量

问题描述

我有两个 .txt 文件,一个包含 200.000 个单词,第二个包含 100 个关键字(每行一个)。我想计算 100 个关键字中的每一个与我的 200.000 个单词中的每个单词之间的余弦相似度,并为每个关键字显示得分最高的 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)

这会继续运行,但不会停止。知道如何纠正这个吗?

标签: pythonpython-3.xcosine-similarity

解决方案


我对伯特一无所知……但是导入和运行有些可疑。我认为您没有正确安装它或其他东西。我试图 pip 安装它并运行它:

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

它从未完成。看一下 bert 的 dox ,看看是否需要做其他事情。

在您的代码上,通常最好先进行所有读取,然后进行处理,因此首先分别导入两个列表,检查一些值,例如:

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

此外,您需要寻找一种不同的方法来进行比较,而不是使用嵌套循环。您现在意识到您每次都在words为每个关键字转换每个单词,这不是必需的,而且可能真的很慢。我建议您使用字典将单词与编码配对,或者如果您对它更满意,则使用其中的(单词,编码)创建一个元组列表。

如果在您启动并运行 Bert 后这没有意义,请给我评论。

- 编辑 -

这是一段与您想要做的类似的代码。根据您的需要,您可以选择很多方法来保存结果等,但这应该让您开始使用“fake bert”

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

推荐阅读