问题描述
sparse_dtm = dok_matrix((num_documents,vocabulary_size),dtype=np.float32)
for doc_index,document in enumerate(data):
document_counter = Counter(document)
for word in set(document):
sparse_dtm[doc_index,word_to_index[word]] = document_counter[word]
地点:
- num_documents = n
- vocabulary_size = m
- data = 标记化列表的列表
sums = sparse_dtm.sum(1).tolist()
现在,我想做一个逐元素划分,其中 row_i
中 sparse_dtm
的每个单元格都被 sums[i]
划分。
一种天真的方法,使用传统的 Python 元素划分:
sparse_dtm / sums
导致以下错误:
TypeError: unsupported operand type(s) for /: 'csr_matrix' and 'list'
如何执行这种逐元素划分?
解决方法
如果我理解正确,你需要将每一行除以行的总和,对吗?
在这种情况下,您需要重塑总和
sparse_dtm / sparse_dtm.sum(1).reshape(-1,1)
例如,您也可以使用 Pandas DataFrame 来实现
row_num = 10
col_num = 5
sparse_dtm = np.ndarray((row_num,col_num),dtype=np.float32)
for row in range(row_num):
for col in range(col_num):
value = (row+1) * (col+2)
sparse_dtm[row,col] = value
df = pd.DataFrame(sparse_dtm)
print(df)
给予
0 1 2 3 4
0 2.0 3.0 4.0 5.0 6.0
1 4.0 6.0 8.0 10.0 12.0
2 6.0 9.0 12.0 15.0 18.0
3 8.0 12.0 16.0 20.0 24.0
4 10.0 15.0 20.0 25.0 30.0
5 12.0 18.0 24.0 30.0 36.0
6 14.0 21.0 28.0 35.0 42.0
7 16.0 24.0 32.0 40.0 48.0
8 18.0 27.0 36.0 45.0 54.0
9 20.0 30.0 40.0 50.0 60.0
然后将每一行划分为行的总和
df / df.sum(axis=1).values.reshape(-1,1)
给予
0 1 2 3 4
0 0.1 0.15 0.2 0.25 0.3
1 0.1 0.15 0.2 0.25 0.3
2 0.1 0.15 0.2 0.25 0.3
3 0.1 0.15 0.2 0.25 0.3
4 0.1 0.15 0.2 0.25 0.3
5 0.1 0.15 0.2 0.25 0.3
6 0.1 0.15 0.2 0.25 0.3
7 0.1 0.15 0.2 0.25 0.3
8 0.1 0.15 0.2 0.25 0.3
9 0.1 0.15 0.2 0.25 0.3
,
In [189]: M = sparse.dok_matrix([[0,1,3,0],[0,2,[1,0]])
In [190]: M
Out[190]:
<3x4 sparse matrix of type '<class 'numpy.int64'>'
with 4 stored elements in Dictionary Of Keys format>
In [191]: M.A
Out[191]:
array([[0,0]])
sum(1)
产生一个 (3,1) np.matrix
,可以直接在除法中使用:
In [192]: M.sum(1)
Out[192]:
matrix([[4],[2],[1]])
In [193]: M/M.sum(1)
Out[193]:
matrix([[0.,0.25,0.75,0. ],[0.,0.,1.,[1.,0. ]])
请注意,结果是密集的 np.matrix
,而不是稀疏的。
如果行总和为 0,这可能会出现问题,但您的构造可能不太可能。
我们可以通过首先将总和转换为稀疏来保留稀疏结果。我正在使用逆,因为没有稀疏的元素除法(所有那些 0):
In [205]: D=sparse.csr_matrix(1/M.sum(1))
In [206]: D
Out[206]:
<3x1 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>
In [207]: D.A
Out[207]:
array([[0.25],[0.5 ],[1. ]])
In [208]: D.multiply(M)
Out[208]:
<3x4 sparse matrix of type '<class 'numpy.float64'>'
with 4 stored elements in Compressed Sparse Row format>
In [209]: _.A
Out[209]:
array([[0.,0. ]])
sklearn
还添加了一些稀疏矩阵实用程序
In [210]: from sklearn import preprocessing
In [211]: preprocessing.normalize(M,norm='l1',axis=1)
Out[211]:
<3x4 sparse matrix of type '<class 'numpy.float64'>'
with 4 stored elements in Compressed Sparse Row format>
In [212]: _.A
Out[212]:
array([[0.,0. ]])