pandas 中的行余弦相似度计算

问题描述 投票:0回答:2

我有一个看起来像这样的数据框:

    api_spec_id label   Paths_modified        Tags_modified     Endpoints_added
933 803.0   minor              8.0                      3.0                    6               
934 803.0   patch              0.0                      4.0                    2
935 803.0   patch              3.0                      1.0                    0
938 803.0   patch             10.0                      0.0                    4
939 803.0   patch              3.0                      5.0                    1
940 803.0   patch              6.0                      0.0                    0
942 803.0   patch              0.0                      6.0                    2
946 803.0   patch              3.0                      2.0                    3
947 803.0   patch              0.0                      0.0                    1

我想计算每一行之间的逐行余弦相似度。数据框已经在

api_spec_id
date
上排序。

预期的输出应该是这样的(值不准确):

    api_spec_id label   Paths_modified        Tags_modified  Endpoints_added         Distance
933 803.0   minor              8.0                      3.0         6                  ...
934 803.0   patch              0.0                      4.0         2                  1.00234
935 803.0   patch              3.0                      1.0         0
938 803.0   patch             10.0                      0.0         4
939 803.0   patch              3.0                      5.0         1
940 803.0   patch              6.0                      0.0         0
942 803.0   patch              0.0                      6.0         2
946 803.0   patch              3.0                      2.0         3
947 803.0   patch              0.0                      0.0         1

我试着查看堆栈溢出中的解决方案,但用例似乎在所有情况下都有点不同。我还有更多功能,总共大约 32 个,我想考虑所有这些功能列(修改的路径、修改的标签和在上面的 df 中添加的端点是一些功能的示例),并计算每行的距离度量。

这是我能想到的,但它没有达到目的:

df = pd.DataFrame(np.random.randint(0, 5, (3, 5)), columns=['id', 'commit_date', 'feature1', 'feature2', 'feature3'])

similarity_df = df.iloc[:, 2:].apply(lambda x: cosine_similarity([x], df.iloc[:, 2:])[0], axis=1)

有人对我如何进行这件事有什么建议吗?

编辑:在我的用例中一个可能的障碍是我无法摆脱我的其他列,我仍然需要至少保留

api_spec_id
以提供一种将距离映射回原始数据框的方法。

python pandas cosine-similarity
2个回答
1
投票

这可以在没有

apply
(更快)的情况下完成:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0, 5, (3, 5)), columns=['id', 'commit_date', 'feature1', 'feature2', 'feature3'])


# Calculate L2 norm of features in row
df["l2norm"] = np.linalg.norm(df.loc[:, "feature1":"feature3"], axis=1)

# Create shifted dataframe
df2 = df.shift(1, fill_value=0)


# Dot product of current with previous row
dot_product = (df.loc[:, "feature1":"feature3"] * df2.loc[:, "feature1":"feature3"]).sum(axis=1)

# L2 norm product of current and previous row
norm_product = df["l2norm"] * df2["l2norm"]

# Divide and print
print(dot_product / norm_product)

0
投票

使用

cosine_similarity

尝试这种方法
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd

df['Distance'] = (df.iloc[:, 2:]
                    .apply(lambda row: cosine_similarity([row],
                    [df.iloc[row.name - 1, 2:]])[0][0]
                    if row.name > 0 else None, axis=1))
print(df)

您也可以使用

for-loop
但要考虑数据框的大小

similarity_df = cosine_similarity(df.iloc[:, 2:])
df['Distance'] = ([None] + [similarity_df[i, i-1] for i in range(1, len(df))]
print(df)

Note 如果提供的代码没有产生您想要的输出,您可能必须通过包含

Distance
列的确切值来更新您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.