TypeError:无法将类型为<class'scipy.sparse.csr.csr_matrix'>的对象转换为Tensor

问题描述

我正在尝试使用张量流来计算350k句子之间的余弦相似度。

我的句子首先使用sklearn进行向量化:

doc =  df['text']
vec = TfidfVectorizer(binary=False,norm='l2',use_idf=False,smooth_idf=False,lowercase=True,stop_words='english',min_df=1,max_df=1.0,max_features=None,ngram_range=(1,1))
X = vec.fit_transform(doc)
print(X.shape)
print(type(X))

这很好用,我得到了稀疏矩阵,然后我尝试了两种方法将稀疏矩阵转换为密集矩阵。

(1)我尝试过:

dense = X.toarray()

这仅适用于少量数据(大约10k句子),但随后在实际计算中失败。

(2)我一直在尝试以这种方式转换输出X,但是在执行第一步K时会得到相同的错误消息:

K = tf.convert_to_tensor(X,dtype=None,dtype_hint=None,name=None)
Y = tf.sparse.to_dense(K,default_value=None,validate_indices=True,name=None)

任何解决这个谜题的技巧都将不胜感激。还高兴地考虑将我的计算分批处理,如果这样做在大小上应该更有效?

解决方法

您需要用SciPy制作一个TensorFlow稀疏矩阵。由于您的矩阵似乎是CSR格式,因此您可以按照以下步骤进行操作:

import numpy as np
import scipy.sparse
import tensorflow as tf

def sparse_csr_to_tf(csr_mat):
    indptr = tf.constant(csr_mat.indptr,dtype=tf.int64)
    elems_per_row = indptr[1:] - indptr[:-1]
    i = tf.repeat(tf.range(csr_mat.shape[0],dtype=tf.int64),elems_per_row)
    j = tf.constant(csr_mat.indices,dtype=tf.int64)
    indices = np.stack([i,j],axis=-1)
    data = tf.constant(csr_mat.data)
    return tf.sparse.SparseTensor(indices,data,csr_mat.shape)

# Test
m = scipy.sparse.csr_matrix([
    [0,1,0],[0,[2,3,4],],dtype=np.float32)
tf_mat = sparse_csr_to_tf(m)
tf.print(tf.sparse.to_dense(tf_mat))
# [[0 0 1 0]
#  [0 0 0 0]
#  [2 0 3 4]]