Могу ли я использовать косинусное сходство между строками, используя только ненулевые значения?

Я хочу найти косинусное сходство (или евклидово расстояние, если проще) между одной строкой запроса и 10 другими строками. Эти строки полны значений nan, поэтому, если столбец имеет значение nan, их следует игнорировать.

Например, запрос:

A   B   C   D   E   F
3   2  NaN  5  NaN  4

дф =

A   B   C   D   E   F
2   1   3  NaN  4   5
1  NaN  2   4  NaN  3
.   .   .   .   .   .
.   .   .   .   .   .

Поэтому я просто хочу получить косинусное сходство между каждым ненулевым столбцом, который запрашивается, и строками из df в столбце. Таким образом, для строки 0 в df A, B и F не равны NULL как в запросе, так и в df.

Затем я хочу напечатать косинусное сходство для каждой строки.

заранее спасибо

1 ответ

Решение

Самый простой метод, который я могу придумать, - это использовать склеарнcosine_similarity,

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(df.fillna(0), df1.fillna(0))
# array([[0.51378309],
#        [0.86958199]])

Самый простой способ "игнорировать" NaN - это просто рассматривать их как нули при вычислении сходства.

Для евклидова - https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.nan_euclidean_distances.html Это игнорирует нан в расчетах

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

Для вашего примера фрейма данных это вычислит косинусное сходство по всем строкам, используя только столбцы A, & F, по запросу и строке 1, используя A, B, & F, и по запросу и строке 2, используя A, D, F. Вам понадобится а затем составить какой-то рейтинг, по которому выбрать балл.

combinations = []
df.apply(lambda x: combinations.append(list(x.dropna().index)), axis=1)

# remove duplicate null combinations
combinations = [list(item) for item in set(tuple(row) for row in combinations)]

for i in combinations:
    pdist(df[i].dropna(), metric='cosine')
Другие вопросы по тегам