[부스트캠프 AI Tech 7기] Spatial Weight Matrix

jinnk0·2024년 10월 25일

AI 부스트캠프 7기 과정 중 두번째 프로젝트를 진행하는 과정에서 모델링 관련하여 고민했던 내용을 정리해보고자 한다.

이번 수도권 아파트 전세가 예측 프로젝트를 진행하면서, 데이터 샘플의 위도, 경도에 대한 공간적인 관계에 대해 종속변수인 전세가에 대한 공간적 자기 상관이 존재할 것이라는 가설을 세웠다.

즉, 거리가 가까운 이웃끼리는 전세가가 비슷할 것이라고 예상하고 이를 모델에 반영해보기 위해 공간적 가중치 행렬(Spatial Weight Matrix)을 사용해보기로 했다.

Spatial Weight Matrix

공간적 자기 상관

상관(Correlation)은 서로 다른 두 변수가 상관 관계를 갖고 동일한 규칙으로 변화하는 것을 말한다. 자기 상관은 시간 또는 공간적으로 연속된 일련의 관측치들 간의 상관관계를 의미한다. 따라서 공간적 자기 상관은 공간적인 근접성에 의해 관측치, 즉 종속변수들 간의 상관관계를 갖는 것을 말한다.

거리 기반 가중치 측정

공간적 자기 상관은 공간적인 근접성을 전제로 하기 때문에, 공간적인 근접성을 판단할 기준이 필요하다. 나는 거리를 기준으로 공간적인 근접성을 판단하기로 했다. 여기서 문제가 된 것은, 그렇다면 모든 샘플 간의 거리를 측정해야 한다는 것이다. 그런데 데이터셋의 크기가 상당히 큰 편이기 때문에, 모든 데이터 샘플 간의 거리를 측정하는 것은 자원의 한계가 있었다.

그래서 공간 분할 알고리즘을 이용해 계산해야 하는 범주를 좁혀보기로 했다. 공간 분할 알고리즘에는 대표적으로 KD Tree와 Ball Tree가 있는데, 나는 그 중에 Ball Tree 알고리즘을 선택했다.

Ball Tree & KD Tree

Ball Tree와 KD Tree는 모두 고차원 데이터에서 효율적으로 근접 이웃을 탐색하거나 거리 계산을 하기 위해 사용되는 알고리즘이다. 다만 사용 목적과 차원의 크기에 따라 적합한 알고리즘이 달라질 수 있어서 이를 비교해보기로 했다.

비교 항목Ball TreeKD Tree
작동 방식중심점과 반경을 기준으로 분할각 차원의 중간값을 기준으로 분할
거리 함수유클리드, 하버사인 거리와 같은 다양한 거리 함수 사용 가능유클리드 거리 계산에 최적화
차원의 크기에 따른 효율고차원에 효과적이고, 저차원에서는 KD Tree보다 느릴 수 있음저차원(2, 3차원)에 특히 효율적, 고차원일수록 차원의 저주로 인해 성능이 저하될 수 있음

나는 위도, 경도를 기준으로 근접 이웃을 탐색할 예정이기 때문에 고차원의 데이터는 아니지만, 위도, 경도에 따른 거리 계산에는 하버사인 거리 함수가 보다 정확하고 Ball Tree는 저차원에서도 KD Tree와 많은 성능 차이를 보이지 않기 때문에 최종적으로 Ball Tree 알고리즘을 이용하게 되었다.

Ball Tree 알고리즘 사용 예시

from sklearn.neighbors import BallTree

data = ... # 분할할 데이터
tree = BallTree(data, metric='haversine') # metric에 사용할 거리 함수 지정

distance, indices = tree.query(data, k=n) # k : 찾고자 하는 근접 이웃 수

'''
distance : k개의 근접 이웃을 거리가 가까운 순으로 data 샘플 포인트와의 거리 반환
indices : 거리가 가까운 k개의 근접 이웃의 인덱스
'''

청크 분할과 희소 행렬

공간적 가중치 행렬을 전체 크기로 생성하여 사용하기에는 데이터셋의 크기가 너무 컸다. out of memory로 인해 공간적 가중치 행렬을 메모리에 올릴 수 있는 크기로 분할해서 사용할 필요가 있었고, 이를 다시 희소 행렬로 변환하여 더욱 메모리 사용량을 줄였다. 최종적으로 청크 단위로 분할한 뒤, 이를 csr_matrix를 이용해 희소 행렬로 변환하고, 이를 pkl 파일로 저장하여 필요할 때 해당하는 부분만 로드하여 사용하는 것으로 공간적 가중치 행렬을 생성했다.

공간적 가중치 행렬 생성 클래스 코드

0개의 댓글