Я не совсем уверен в вашей проблеме с настройкой, но я думаю, что это может помочь вам начать.Предположим, что ваша коллекция словарей такова:
import math
dict_list = {
"water": {
"ground": 1,
"journey": 1,
"longitude": 1,
"main": 1,
"contrary": 1,
"cover": 1,
"delaware": 1,
"remarkable": 1
},
"mississippi": {
"main": 1,
"contrary": 1,
"cover": 1,
"delaware": 1,
"remarkable": 1,
"steamboats": 1,
"germany": 1
}
}
Если вы хотите применить к ним правило косинуса, вам нужно настроить векторы, показывающие вхождение каждого слова, присутствующего в обоих словарях (т. Е. Если оно отображаетсяв одном, а не в другом он должен быть равен нулю в другом):
def setup_vec(dict1, dict2):
dict1_missing = list(set(dict2.keys() - set(dict1.keys())))
dict2_missing = list(set(dict1.keys() - set(dict2.keys())))
for i in dict1_missing:
dict1[i] = 0
for i in dict2_missing:
dict2[i] = 0
vec1 = []
vec2 = []
for i in dict1.keys():
vec1.append(dict1[i])
vec2.append(dict2[i])
return([vec1, vec2])
Обратите внимание, что порядок элементов вектора важен.Если вы запустите это с «водой» и «Миссисипи», вы получите:
[[1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1]]
После этого вам просто нужно применить правило:
def dot_prod(p, q):
return sum([p[x]*q[x] for x in range(0, len(p))])
def norm(p):
return math.sqrt(dot_prod(p, p))
def cosine_metric(p, q):
return dot_prod(p, q)/(norm(p) * norm(q))
И функцию, которая их вычисляетдля данного словаря в сравнении со всеми остальными:
def find_dict(word):
if word in dict_list.keys():
for other_dicts in dict_list.keys():
if other_dicts != word:
vecs = setup_vec(dict_list[word], dict_list[other_dicts])
print(other_dicts + " " + str(cosine_metric(vecs[0], vecs[1])))
Здесь приведены следующие результаты:
find_dict('water')
0.6681531047810609
Оставшаяся задача - упорядочить вывод, что не должно быть сложным.