[Python] 텍스트로부터 CSR 행렬을 이용하여 Term-Document 행렬 만들기
Deep Learning (TF, Keras, PyTorch)/Natural Language Processing 2020. 9. 13. 23:39희소행렬(Sparse matrix)은 대부분의 값이 원소 '0'인 행렬, '0'이 아닌 원소가 희소(sparse)하게, 듬성듬성 있는 행렬을 말합니다. 반대로 밀집행렬(Dense matrix)은 대부분의 원소 값이 '0'이 아닌 행렬을 말합니다.
자연어처리 분석을 할 때 문서 내 텍스트를 컴퓨터가 이해할 수 있는 형태의 자료구조로 만들 때 텍스트 파싱을 거쳐 단어-문서 행렬(Term-Document matrix) (or 문서-단어 행렬, Document-Term matrix) 를 만드는 것부터 시작합니다.
문서별로 많은 수의 단어가 포함되어 있고, 또 단어별로 발생 빈도가 보통은 드물기 때문에, 문서에서 단어를 파싱하여 Term-Document 행렬을 만들면 대부분은 희소행렬(Sparse matrix)을 얻게 됩니다.
이번 포스팅에서는
(1) 문서별 단어로 부터 CSR 행렬(Compressed Sparse Row matrix) 을 만들고,
(2) CSR 행렬을 이용해 NumPy array의 Term-Document 행렬 만들기
를 해보겠습니다.
단, 이번 포스팅의 주 목적은 문서로부터 문서-단어 CSR 행렬을 만들고 --> 이를 NumPy array의 Term-Document 행렬을 만드는 과정에 집중해서 소개하는 것으로서, 텍스트 파싱하는데 필요한 세부 절차(가령 문장 분리, 대문자의 소문자로 변환, Stop words 생략 등)는 생략합니다.
(텍스트를 단어 단위로 파싱해서 one-hot encoding 하는 방법은 https://rfriend.tistory.com/444 포스팅 참조하세요.)
(1) 문서별 단어로 부터 CSR 행렬(Compressed Sparse Row matrix) 을 만들기 |
먼저, NumPy와 SciPy 모듈을 importing 하겠습니다.
import numpy as np from scipy.sparse import csr_matrix
|
아래와 같이 리스트 [] 하나를 문서(Document) 하나로 간주했을 때, 총 3개의 문서를 가진 "docs" 로 부터 단어(Term)를 파싱해서 단어집(Vocabulary) 사전형(dictionary)을 만들고, 압축 희소 행기준 행렬(Compressed Sparse Row matrix) 을 만들기 위해 필요한 indptr, indices, data 객체를 for loop 문을 써서 만들어보겠습니다.
참고로, CSR 행렬 소개, SciPy.sparse.csr_matrix() 메소드 소개, NumPy 희소행렬을 SciPy 압축 희소 행기준 행렬 (Compressed Sparse Row matrix) 로 변환하는 방법은 https://rfriend.tistory.com/551 포스팅을 참고하세요.
# To construct a CSR matrix incrementally docs = [["python", "is", "a", "programming", "language"], ["programming", "is", "fun"], ["python", "is", "easy"]] indptr = [0] indices = [] data = [] vocabulary = {} for d in docs: for term in d: index = vocabulary.setdefault(term, len(vocabulary)) indices.append(index) data.append(1) indptr.append(len(indices)) |
* reference: https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html
위의 실행결과로 얻은 단어집(Vocabulary)을 Key : Value 쌍으로 출력을 해서 살펴보겠습니다. 3개의 문서에 총 7개의 단어가 있군요. (문서별로 중복되는 단어(term)가 존재함)
for k, v in vocabulary.items(): print(k, ':', v) [Out] python : 0 is : 1 a : 2 programming : 3 language : 4 fun : 5 easy : 6 |
위에서 얻은 indptr, indices, data 를 가지고 SciPy.sparse.csr_matrix() 메소드를 이용하여 압축 희소 행기준 행렬(CSR matrix)을 만들어보겠습니다.
term_document_csr_mat = csr_matrix((data, indices, indptr), dtype=int) term_document_csr_mat [Out] <3x7 sparse matrix of type '<class 'numpy.int64'>' with 11 stored elements in Compressed Sparse Row format> print(term_document_csr_mat) [Out] (0, 0) 1 (0, 1) 1 (0, 2) 1 (0, 3) 1 (0, 4) 1 (1, 3) 1 (1, 1) 1 (1, 5) 1 (2, 0) 1 (2, 1) 1 (2, 6) 1 print('-- SciPy Compressed Sparse Row matrix --') print('indptr:', term_document_csr_mat.indptr) print('indices:', term_document_csr_mat.indices) print('data:', term_document_csr_mat.data) -- SciPy Compressed Sparse Row matrix -- indptr: [ 0 5 8 11] indices: [0 1 2 3 4 3 1 5 0 1 6] data: [1 1 1 1 1 1 1 1 1 1 1] |
(2) CSR 행렬을 이용해 NumPy array의 Term-Document 행렬 만들기 |
위의 (1)번에서 만든 SciPy CSR(Compressed Sparse Row) matrix를 csr_matrix.toarray() 또는 csr_matrix.todense() 메소드를 사용해서 NumPy array 행렬로 변환해보겠습니다. 이로부터 Term-Document Matrix를 만들었습니다.
# converting SciPy CSR matrix to NumPy array term_document_arr = term_document_mat.toarray() # or todense() term_document_arr [Out] array([[1, 1, 1, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 1, 0],
[1, 1, 0, 0, 0, 0, 1]]) |
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요.