0
from numpy.random import rand
from sklearn.preprocessing import normalize
from scipy.sparse import csr_matrix
from scipy.linalg import norm

w = (rand(1,10)<0.25)*rand(1,10)
x = (rand(1,10)<0.25)*rand(1,10)
w_csr = csr_matrix(w)
x_csr = csr_matrix(x)
(normalize(w_csr,axis=1,copy=False,norm='l2')*normalize(x_csr,axis=1,copy=False,norm='l2')).todense()

norm(w,ord='fro')*norm(x,ord='fro')

我正在使用 scipy csr_matrix 并希望使用 frobenius 范数对两个矩阵进行归一化并获得他们的产品。但是来自 scipy.linalg 的 norm 和来自 sklearn.preprocessing 的 normalize 似乎对矩阵的评估方式不同。由于从技术上讲,在上述两种情况下,我正在计算相同的 frobenius 范数,这两个表达式的计算结果不应该是相同的吗?但我得到以下答案:

矩阵([[ 0.962341]])

0.4431811178371029

分别用于 sklearn.preprocessing 和 scipy.linalg.norm。我真的很想知道我做错了什么。

4

1 回答 1

1

sklearn.prepocessing.normalize 每一行除以其范数。它返回一个与其输入形状相同的矩阵。 scipy.linalg.norm返回矩阵的范数。所以你的计算是不等价的。

请注意,您的代码在编写时不正确。这条线

(normalize(w_csr,axis=1,copy=False,norm='l2')*normalize(x_csr,axis=1,copy=False,norm='l2')).todense()

提高ValueError: dimension mismatch。这两个调用normalize都返回形状为 (1, 10) 的矩阵,因此它们的尺寸与矩阵乘积不兼容。你做了什么得到matrix([[ 0.962341]])

这是一个计算稀疏(例如 CSR 或 CSC)矩阵的 Frobenius 范数的简单函数:

def spnorm(a):
    return np.sqrt(((a.data**2).sum()))

例如,

In [182]: b_csr
Out[182]: 
<3x5 sparse matrix of type '<type 'numpy.float64'>'
with 5 stored elements in Compressed Sparse Row format>

In [183]: b_csr.A
Out[183]: 
array([[ 1.,  0.,  0.,  0.,  0.],
       [ 0.,  2.,  0.,  4.,  0.],
       [ 0.,  0.,  0.,  2.,  1.]])

In [184]: spnorm(b_csr)
Out[184]: 5.0990195135927845

In [185]: norm(b_csr.A)
Out[185]: 5.0990195135927845
于 2013-12-05T15:33:19.030 回答