如何在python中找到向量和矩阵(大小不同的矩阵)之间的相似距离?
How to find similarity distance between vector and matrix (matrices that are not the same size) in python?
我有一个用户 'preferences' table 的数据集,table 的一个实例如下所示:
print(user_normalized[1].reshape(1, -1).shape)
print(user_normalized[1].reshape(1, -1))
___________________________________________________________________
(1, 20)
[[0. 0.00239107 0.00131709 0. 0.00355872 0.00212352
0.00300639 0.00044287 0.001469 0.00358637 0.01520913 0.
0. 0. 0.00174978 0.00237691 0.0026616 0.00241604
0. 0. ]]
这给了我第一个用户的偏好向量。
我有一个电影内容的数据集table:
print(movie_content.shape)
print(movie_content)
___________________________________________________________________
(27278, 20)
[[1 0 0 ... 0 0 0]
[1 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 1 ... 0 0 0]
[1 0 0 ... 0 0 0]]
我正在尝试获取用户偏好向量和电影内容的点积 table 以找到最优惠的电影(余弦相似度):
distances = np.dot(user_normalized[1], movie_content)
但这给了我以下错误:
ValueError: shapes (1,20) and (27278,20) not aligned: 20 (dim 1) != 27278 (dim 0)
为了找到最优惠的电影,找到距离度量的方法是否正确?
如果是,代码有什么问题?
您需要将向量整形为 (-1, 1)
。如果要对形状为 (m, k)
和 (t, n)
的两个数组进行点积,则 k
必须等于 t
。由于在 numpy 中没有向量的概念,你基本上有一个形状数组 (27278, 20)
(movie_content) 和另一个形状数组 (1, 20)
(user_normalized)。为了能够采用点积,您必须将 user_normalized 数组重塑为 (20, 1)
形状,使 movie_content 和 user_normalized 数组“对齐”(这就是 numpy 喜欢的dot
产品。
因此,您的代码将如下所示
import numpy as np
distances = np.dot(movie_content, user_normalized[1].reshape(-1, 1))
编辑:此解决方案仅在 user_normalized 是向量时有效。如果 user_normalized 是矩阵,则需要转置它。请参阅@amdex 对该案例的回答。
虽然上面的答案是正确的,但它只适用于第一维恰好为 1 的矩阵。使用 user_normalized
(user_normalized.T
) 的转置将适用于更多维。
所以,简短的回答是:使用
distances = np.dot(movie_content, user_normalized.T)
更复杂的答案是,如果 X
的第二个维度与 Y
的第一个维度匹配,则点积仅为两个矩阵 X
和 Y
定义],即 X
的形状为 (M, N)
,而 Y
的形状为 (N, D)
。点积的结果是一个维度为 (M, D)
.
的新矩阵
在您的例子中,您有一个 (27278, 20)
矩阵和一个 (1, 20)
矩阵。转置将 (1, 20)
矩阵变成 (20, 1)
矩阵,从而满足点积的条件。最终结果是一个 (27278, 1)
矩阵,其中每个单元格包含第 N 部电影和第 D 个用户的乘积。
我有一个用户 'preferences' table 的数据集,table 的一个实例如下所示:
print(user_normalized[1].reshape(1, -1).shape)
print(user_normalized[1].reshape(1, -1))
___________________________________________________________________
(1, 20)
[[0. 0.00239107 0.00131709 0. 0.00355872 0.00212352
0.00300639 0.00044287 0.001469 0.00358637 0.01520913 0.
0. 0. 0.00174978 0.00237691 0.0026616 0.00241604
0. 0. ]]
这给了我第一个用户的偏好向量。
我有一个电影内容的数据集table:
print(movie_content.shape)
print(movie_content)
___________________________________________________________________
(27278, 20)
[[1 0 0 ... 0 0 0]
[1 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 1 ... 0 0 0]
[1 0 0 ... 0 0 0]]
我正在尝试获取用户偏好向量和电影内容的点积 table 以找到最优惠的电影(余弦相似度):
distances = np.dot(user_normalized[1], movie_content)
但这给了我以下错误:
ValueError: shapes (1,20) and (27278,20) not aligned: 20 (dim 1) != 27278 (dim 0)
为了找到最优惠的电影,找到距离度量的方法是否正确?
如果是,代码有什么问题?
您需要将向量整形为 (-1, 1)
。如果要对形状为 (m, k)
和 (t, n)
的两个数组进行点积,则 k
必须等于 t
。由于在 numpy 中没有向量的概念,你基本上有一个形状数组 (27278, 20)
(movie_content) 和另一个形状数组 (1, 20)
(user_normalized)。为了能够采用点积,您必须将 user_normalized 数组重塑为 (20, 1)
形状,使 movie_content 和 user_normalized 数组“对齐”(这就是 numpy 喜欢的dot
产品。
因此,您的代码将如下所示
import numpy as np
distances = np.dot(movie_content, user_normalized[1].reshape(-1, 1))
编辑:此解决方案仅在 user_normalized 是向量时有效。如果 user_normalized 是矩阵,则需要转置它。请参阅@amdex 对该案例的回答。
虽然上面的答案是正确的,但它只适用于第一维恰好为 1 的矩阵。使用 user_normalized
(user_normalized.T
) 的转置将适用于更多维。
所以,简短的回答是:使用
distances = np.dot(movie_content, user_normalized.T)
更复杂的答案是,如果 X
的第二个维度与 Y
的第一个维度匹配,则点积仅为两个矩阵 X
和 Y
定义],即 X
的形状为 (M, N)
,而 Y
的形状为 (N, D)
。点积的结果是一个维度为 (M, D)
.
在您的例子中,您有一个 (27278, 20)
矩阵和一个 (1, 20)
矩阵。转置将 (1, 20)
矩阵变成 (20, 1)
矩阵,从而满足点积的条件。最终结果是一个 (27278, 1)
矩阵,其中每个单元格包含第 N 部电影和第 D 个用户的乘积。