我有一个大小为(n x m(的稀疏矩阵:
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
- 词汇_大小=m
- data=标记化列表列表
此外,我有一个长度为n
:的列表
sums = sparse_dtm.sum(1).tolist()
现在,我想做一个元素分割,其中sparse_dtm
中row_i
的每个单元被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,0,2,0],[1,0,0,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, 1, 3, 0],
[0, 0, 2, 0],
[1, 0, 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. , 0. ],
[1. , 0. , 0. , 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.25, 0.75, 0. ],
[0. , 0. , 1. , 0. ],
[1. , 0. , 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.25, 0.75, 0. ],
[0. , 0. , 1. , 0. ],
[1. , 0. , 0. , 0. ]])