Сходство косинуса между столбцами двух фреймов данных разной длины?
У меня есть текстовый столбец в df1 и текстовый столбец в df2. Длина df2 будет отличаться от длины df1. Я хочу вычислить косинусное сходство для каждой записи в df1[текст] по отношению к каждой записи в df2[текст] и дать оценку для каждого совпадения.
образец ввода
df1
mahesh
suresh
df2
surendra
mahesh
shrivatsa
suresh
maheshwari
образец вывода
mahesh surendra 30
mahesh mahesh 100
mahesh shrivatsa 20
mahesh suresh 60
mahesh maheshwari 80
suresh surendra 70
suresh mahesh 60
suresh shrivatsa 40
suresh suresh 100
suresh maheshwari 30
У меня возникли проблемы (получение ключевых ошибок), когда я пытался сопоставить эти два столбца на предмет схожести с использованием подхода tf-idf, поскольку эти столбцы имели разную длину. есть ли другой способ решить эту проблему... Любая помощь будет очень приветствоваться. Я много искал и обнаружил, что почти во всех случаях люди сравнивали первый документ с остальными документами в том же корпусе. здесь это похоже на сравнение каждого документа корпуса 1 с каждым документом корпуса 2.
1 ответ
Существует множество различных мер длины струны. Я не знаю, как использовать косинусное сходство для этого случая, но предлагаю изучить strsim
библиотека.
Я дам вам пример того, как я подхожу к проблеме, используя Jaro-Winkler
метрика, которая лучше всего подходит для коротких струн.
Кроме того, я включаю свою попытку использовать cosine similarity
учитывая пример из документации указанной библиотеки.
Это может быть совершенно неверно, но должно дать вам общее представление о том, как создать фрейм данных из декартова произведения двух столбцов разной длины, а также о том, как применять strsim
алгоритмов к данным, хранящимся в pd.DataFrame
Подготовка данных:
import pandas as pd
from similarity.jarowinkler import JaroWinkler
from similarity.cosine import Cosine
df1 = pd.DataFrame({
"name": ["mahesh", "suresh"]
})
df2 = pd.DataFrame({
"name": ["mahesh", "surendra", "shrivatsa", "suresh", "maheshwari"]
})
df = pd.MultiIndex.from_product(
[df1["name"], df2["name"]], names=["col1", "col2"]
).to_frame(index=False)
возвращает:
col1 col2
0 mahesh mahesh
1 mahesh surendra
2 mahesh shrivatsa
3 mahesh suresh
4 mahesh maheshwari
5 suresh mahesh
6 suresh surendra
7 suresh shrivatsa
8 suresh suresh
9 suresh maheshwari
Яро-Винклер:
jarowinkler = JaroWinkler()
df["jarowinkler_sim"] = [jarowinkler.similarity(i,j) for i,j in zip(df["col1"],df["col2"])]
возвращает:
col1 col2 jarowinkler_sim
0 mahesh mahesh 1.0
1 mahesh surendra 0.4305555555555555
2 mahesh shrivatsa 0.5185185185185185
3 mahesh suresh 0.6666666666666666
4 mahesh maheshwari 0.9466666666666667
5 suresh mahesh 0.6666666666666666
6 suresh surendra 0.8333333333333334
7 suresh shrivatsa 0.611111111111111
8 suresh suresh 1.0
9 suresh maheshwari 0.48888888888888893
Косинусное сходство:
cosine = Cosine(2)
df["p0"] = df["col1"].apply(lambda s: cosine.get_profile(s))
df["p1"] = df["col2"].apply(lambda s: cosine.get_profile(s))
df["cosine_sim"] = [cosine.similarity_profiles(p0,p1) for p0,p1 in zip(df["p0"],df["p1"])]
df.drop(["p0", "p1"], axis=1)
возвращает:
col1 col2 cosine_sim
0 mahesh mahesh 0.9999999999999998
1 mahesh surendra 0.0
2 mahesh shrivatsa 0.15811388300841897
3 mahesh suresh 0.3999999999999999
4 mahesh maheshwari 0.7453559924999299
5 suresh mahesh 0.3999999999999999
6 suresh surendra 0.5070925528371099
7 suresh shrivatsa 0.15811388300841897
8 suresh suresh 0.9999999999999998
9 suresh maheshwari 0.29814239699997197