AI/Data Science

희소행렬을 효율적으로 저장하는 COO, CSR 형식

Linuxias 2024. 3. 30. 14:20
반응형

희소행렬(Sparse Matrix)은 대부분의 원소가 0으로 채워진 행렬을 의미합니다. 이러한 행렬은 데이터의 특성에 따라 매우 큰 메모리를 차지할 수 있습니다. 따라서, 이러한 희소행렬을 저장하고 효율적으로 다루기 위해 COO(Coordinate List)와 CSR(Compressed Sparse Row) 형식이 주로 사용됩니다.

데이터 포맷에서 "희소행렬"과 "COO(Coordinate List)", "CSR(Compressed Sparse Row)" 형식은 주로 희소 행렬(행렬 내 대부분의 요소가 0인 경우)을 저장하고 효율적으로 다루기 위해 사용됩니다.

  1. 희소행렬(Sparse Matrix):
    • 일반적인 행렬과 달리, 대부분의 원소가 0으로 구성되어 있습니다.
    • 이러한 행렬은 메모리를 효율적으로 사용하기 위해 특별한 형식으로 저장됩니다.
    • 희소 행렬은 크게 COO 형식과 CSR 형식으로 저장됩니다.
  2. COO(Coordinate List) 형식:
    • COO 형식은 희소 행렬을 (행, 열, 값)의 좌표 리스트로 표현합니다.
    • 예를 들어, (i, j, v)는 행렬의 i행 j열에 값 v가 있다는 것을 의미합니다.
    • 이 형식은 행렬의 구조를 보존하면서도 메모리 사용을 최적화할 수 있는 장점이 있습니다.
  3. CSR(Compressed Sparse Row) 형식:
    • CSR 형식은 각 행의 시작 위치와 해당 행의 원소들을 연속된 배열로 표현합니다.
    • 희소 행렬을 압축하여 저장하므로 메모리 사용을 최적화할 수 있습니다.
    • CSR 형식은 주로 행별로 순회할 때 효율적입니다.

따라서, 데이터 포맷에서 희소행렬을 저장하고 다룰 때 COO 형식과 CSR 형식이 사용되며, 각 형식은 행렬의 특성과 다루는 작업에 따라 선택됩니다.

대부분 0으로 채워진 행렬을 희소 행렬(Sparse matrix)라고 했습니다. 그렇다면 반대로 대부분 값이 0이 아닌 값으로 채워진 행렬을 밀집 행렬(Dense Matrix) 하고 합니다.

데이터 전처리 과정 중 사용하는 One-Hot Encoding을 적용하면 희소 행렬을 만들게 됩니다. 만약 범주형 데이터가 매우 많다면 이런 희소행렬로 인해 데이터의 크기가 매우 커지게 되고 메모리 낭비가 심해집니다. 특히 행렬 크기가 증가함에따라 연산 시간도 오래 걸립니다.

이런 문제를 개선하기 위해 행렬 형식을 변환해줘야 하는데, 대표적으로 위에서 설명한 COO와 CSR 형식입니다. 희소 행렬을 COO와 CSR 형식으로 변환하면 메모리를 적게 사용하면서 연산이 빠릅니다. COO보다는 CSR이 메모리 효율과 연산 측면에서 좀 더 나은 성능을 보이므로 COO 형식보다는 CSR 형식을 많이 사용합니다.

아래는 간단한 예시입니다.

import numpy as np
from scipy.sparse import coo_matrix, csr_matrix

# COO 형식의 희소행렬 생성
data = np.array([3, 1, 2, 5])  # 값
row = np.array([0, 1, 2, 1])   # 행
col = np.array([0, 1, 2, 2])   # 열
coo_matrix_example = coo_matrix((data, (row, col)), shape=(3, 3))

print("COO 형식의 희소행렬:")
print(coo_matrix_example.toarray())
print()

# CSR 형식으로 변환
csr_matrix_example = csr_matrix(coo_matrix_example)

print("CSR 형식의 희소행렬:")
print(csr_matrix_example.toarray())

예를 들어 연속형, 범주형 데이터가 혼재된 상태에서 범주형 데이터의 One-Hot Encoding 된 데이터들을 다시 붙히는 예제는 아래와 같습니다.

import numpy as np
from scipy.sparse import csr_matrix, hstack

# 간단한 희소 행렬 생성
data1 = [1, 2, 3]
data2 = [4, 5, 6]
row = [0, 1, 2]
col1 = [0, 1, 2]
col2 = [0, 1, 2]

sparse_matrix1 = csr_matrix((data1, (row, col1)), shape=(3, 3))
sparse_matrix2 = csr_matrix((data2, (row, col2)), shape=(3, 3))

# 두 희소 행렬을 수평으로 쌓기
result = hstack([sparse_matrix1, sparse_matrix2])

print("Resultant Sparse Matrix:")
print(result.toarray())

 

반응형