์์ฝ
- BallTree๋ ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ ๊ณต๊ฐ์ ๊ตฌ์ฒด(Ball)๋ก ๊ฐ์ธ ๊ณ์ธต์ ์ธ ์ด์ง ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ์ต๊ทผ์ ์ด์ ํ์ ์๊ณ ๋ฆฌ์ฆ์.
- ๋จ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ ๋ฐฉ์๊ณผ ๋ฌ๋ฆฌ ํ์ ๊ณผ์ ์์ ๋ถํ์ํ ์์ ๋ ธ๋๋ค์ ํจ์จ์ ์ผ๋ก ์ ๊ฑฐํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ง์์ง์๋ก ๊ณ์ฐ๋์ ํ๊ธฐ์ ์ผ๋ก ์ค์ฌ์ค.
- KD-Tree์ ๋นํด ์ด๊ธฐ ํธ๋ฆฌ ๊ตฌ์ถ ๋น์ฉ์ ๋ ๋ค์ง๋ง, ์ฐจ์๊ฐ ์ปค์ง์๋ก ๋ฐ์ดํฐ๋ฅผ ํจ์ฌ ๋น ๋ฅด๊ฒ ํ์ํ ์ ์๋ค๋ ์ฅ์ ์ด ์์.
- ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ๋จผ ํฌ์ธํธ๋ค์ ๊ธฐ์ค์ผ๋ก ์ฌ๊ท์ ์ผ๋ก ํ์ Ball์ ์์ฑํ๊ณ , ํ์ ์์๋ ์์ Ball์์ ๋ฆฌํ ๋ ธ๋๊น์ง ์ขํ๊ฐ๋ ๋ฐฉ์์ ์ฌ์ฉํจ.
- ํ์ด์ฌ์ sklearn ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฝ๊ฒ ๊ตฌํํ ์ ์์ผ๋ฉฐ, ํน์ ๋ฐ๊ฒฝ ๋ด์ ๊ฒฉ์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๋ฑ ๊ณต๊ฐ ๋ฐ์ดํฐ ๋ถ์์ ์ ์ฉํ๊ฒ ํ์ฉ๋จ.
1. ๊ฐ์
1.1 BallTree ์๊ณ ๋ฆฌ์ฆ์ด๋?
์ต๊ทผ์ ์ด์ ํ์(knn search)๊ณผ ์ ์ฌํ๋ฉฐ, ํน์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ tree ๊ตฌ์กฐ ์๊ณ ๋ฆฌ์ฆ
๋ชฉ์ : ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋น ๋ฅด๊ฒ ์ต๊ทผ์ ์ด์์ ํ์ ํต์ฌ ๋ด์ฉ: ๋ฐ์ดํฐ ๊ณต๊ฐ์ Ball๋ก ๊ฐ์ธ๋ ๋ฐฉ์์ธ ์ด์ง ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑ ์ฃผ์ ์ฉ๋: KNN, ์ ์ฌ๋ ๊ฒ์, ๊ณ ์ฐจ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
1.2 ์ฃผ์ ์ฉ์ด
| ์ฉ์ด | ์๋ฏธ |
|---|---|
| Ball | ์ค์ฌ์ ์ ์ ๊ฐ์ง๋ ๊ตฌ์ฒด(๋ฐ์ดํฐ ํฌ์ธํธ๋ ํด๋น Ball์ ์กด์ฌ) |
| Leaf Node | ์ค์ ๋ฐ์ดํฐ ํฌ์ธํธ๋ค์ด ์ ์ฅ๋ ํ์ ๋ ธ๋ |
| Internal Node | ๋ ๊ฐ์ ์์ Ball์ ๊ฐ๋ ๋
ธ๋ |
| Tree | Ball๋ค์ด ๊ฒ์ธต์ ์ผ๋ก ๊ตฌ์ฑ๋ ์ด์ง ํธ๋ฆฌ ๊ตฌ์กฐ |
2. ํน์ง
BallTree๋ KD-Tree์ ๋น๊ตํ์ฌ, ์ด๊ธฐ ํธ๋ฆฌ ๊ตฌ์ฑ ๋น์ฉ์ด ํฌ์ง๋ง ์ฐจ์๊ฐ ์ปค์ง์๋ก ๋ฐ์ดํฐ๋ฅผ ํจ์ฌ ๋น ๋ฅด๊ฒ ํ์ํ ์ ์๋ ์ฅ์ ์ด ์๋ค.
๋ฐ๋ฉด์, BallTree ๋ kd tree ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ฒ ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ค.
๋น๊ต: BallTree vs ๋จ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
- ๋จ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ: ๋ฐ์ดํฐ ์ ์ฆ๊ฐํ ์๋ก ๊ณ์ฐ๋ ๊ธฐํ๊ธ์์ ์ฆ๊ฐ
- BallTree: ํธ๋ฆฌ ๊ตฌ์กฐ ์์ฑ์ ํตํด, ํน์ ๋ ธ๋๊ฐ ์ง์ํ ๊ฑฐ๋ฆฌ๋ณด๋ค ํฌ๋ฉด ํด๋น ๋ ธ๋์ ์์ ๋ ธ๋๋ค์ ๋ชจ๋ ๋ฒ๋ฆผ โ ๊ณ์ฐ๋ ๊ฐ์!
3. ์๊ณ ๋ฆฌ์ฆ
๋ชฉ์ : Input Data์ ๊ฐ์ฅ ๊ฐ๊น์ด Point ํ์
- ๋๋คํ point ์ ํํ๋ ๊ณผ์ ์ ์ฌ๊ท์ ์ผ๋ก ์ํํ์ฌ Ball ์์ฑ
- Ball ๊ธฐ๋ฐ Tree ๊ตฌ์ฑ
- Input data๊ฐ ์ํ Ball์ ์ฐพ๋ ํธ๋ฆฌ ๋ ธ๋ ํ์ํ์ฌ ๊ฐ์ฅ ๊ฐ๊น์ด Ball ํ์
- ํด๋น Ball ์ ์๋ Point ์ค ๊ฐ์ฅ ๊ฐ๊น์ด Point ํ์
3.1 Ball ์์ฑ
๋๋คํ Point P1 ์ ํํ ํ, ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ๋จผ ํฌ์ธํธ P2 ์ P2์์ ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ๋จผ ํฌ์ธํธ P3 ์ ํ
P2์ P3๋ฅผ ์๋ ์ ์ ์์ฑํ์ฌ ํด๋น ์ ์ ์ค๊ฐ์ ์ ๊ธฐ์ค์ผ๋ก ์ ์ ๋๋ โ l1, l2
๋ค๋ฅธ Point๋ค์ ๋๋์ด์ง ๊ฐ ์ ์ ์์ ์ ๋ฐ์ ๋ด๋ฆผ(=projection), ๊ฐ ์ ๋ค์ ํฌ์๋ ์ ๋ค์ ์ถ ์ฑ๋ถ์ ํฉ์ ํ๊ท ์ ์๋ก์ด Ball์ ์ค์ฌ์ ์ผ๋ก ๊ฐ๊ฐ ์์ฑ
(๋จ, ์ฌ๊ธฐ์ P1์ ์ ์ธ๋๋ค. ์๋ํ๋ฉด ์ด๋ฏธ P1์ ์ค์ฌ์ผ๋ก ๋ชจ๋ ์ ์ ํฌํจํ๋ Ball1์ ๋ง๋ค์๊ธฐ ๋๋ฌธ์ ํ์ Ball ์์ฑ ์์๋ ์ ์ธ๋๋ค.)
๊ฐ๊ฐ ์๋กญ๊ฒ ์์ฑ๋ Ball์ ์ค์ฌ์ ์์ ์ค์ฌ์ ์์ฑ์ ํ์ฉ๋ ๊ธฐ์กด Point ์ค ๊ฐ์ฅ ๊ฑฐ๋ฆฌ๊ฐ ๋จผ Point์์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐ์ง๋ฆ์ผ๋ก ํ๋ Ball ์ ์์ฑ
3.2 Tree ๊ตฌ์ฑ
์ ๊ณผ์ ์ ์ฌ๊ท์ ์ผ๋ก ๋ฐ๋ณตํ์ฌ ์ต์ข Ball์ ์์ฑํ๋ค.
Ball์ ์๊ณ ๊ตฌ์กฐ์ ๋ง๊ฒ Tree๋ฅผ ๊ตฌ์ฑํ๋ค.
3.3 Ball ํ์
ํธ๋ฆฌ ๋
ธ๋ ํ์์ ํตํด Input Data(8,5)๊ฐ ์ํ Ball์ ์ฐพ์ผ๋ฉฐ, ๋จ๊ณ์ ์ผ๋ก ๊ฐ์ฅ ๊ฐ๊น์ด Ball ์ ์ ํ B1 - B3 - B6
3.4 ์ต๊ทผ์ Point ํ์
์ต์ข
Ball(B6) ๋ด Point๋ค ๊ณผ์ ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ๋ฅผ ์ฐ์ถํ ํ, ๊ฐ์ฅ ๊ฐ๊น์ด Point(8,3) ์ ํ
4. Python ์ฝ๋ ์์
๊ฒฉ์ ๋ฐ์ดํฐ ํ์ฉํ์ฌ, ๊ฐ ๊ฒฉ์๋ณ ๋ฐ๊ฒฝ ๋ด ์ํ ๊ฒฉ์ ๋ชฉ๋ก ์ฐ์ถ
from skleran.neighbors import BallTree
๋ชฉ์ : ๊ฐ ๊ฒฉ์ ์ค์ฌ์ ์ ๊ธฐ์ค์ผ๋ก ํน์ ๋ฐ๊ฒฝ ๋ด ์์นํ ๊ฒฉ์ ์ค์ฌ์ ์ ํด๋นํ๋ ๊ฒฉ์ ๋ชฉ๋ก ์ถ์ถ
๋จ๊ณ ๊ตฌ์ฑ
- ๊ฐ ๊ฒฉ์๋ณ ์ค์ฌ์ขํ ์์ฑ
geometry์ ๋ณด๊ฐ ์๋ ๊ฒฝ์ฐ,centroid๋ฉ์๋ ํ์ฉgeometry์ ๋ณด๊ฐ ์๊ณ ์๊ฒฝ๋ ์ ๋ณด๋ง ์๋ ๊ฒฝ์ฐ, ์ขํ๊ฐ array ํํ ์์ฑ(N, 2)
- ์ค์ฌ์ ๊ธฐ์ค BallTree ์ด๊ธฐ ์์ฑ
- ํน์ ๋ฐ๊ฒฝ ๋ด ์ธ๋ฑ์ค ์ถ์ถ
tree.query_radius(X, r, return_distance = False, count_only = False, sort_result = False)ํ์ฉX: ์ขํ๊ฐ arrayr: ๋ฐ๊ฒฝ(m)return_distance: ๊ฑฐ๋ฆฌ ๊ฐ ๋ฐํ ์ฌ๋ถcount_only: ๋ฐ๊ฒฝ ๋ง์กฑ ๊ฑด์๋ง ๊ฐ์ ธ์ค๋์งsort_result: ๊ฑฐ๋ฆฌ์ ์ธ๋ฑ์ค ๊ธฐ์ค ์ ๋ ฌ
from sklearn.neighbors import BallTree
import numpy as np
# 1. ๊ฐ ๊ฒฉ์๋ณ ์ค์ฌ์ขํ ์์ฑ
coords = np.array([(geom.centroid.x, geom.centroid.y) for geom in gdf.geometry]) ## geometry ์กด์ฌ
coords = np.vstack([gdf['x'].values, gdf['y'].values]).T ## ์ขํ๊ฐ๋ง ์กด์ฌ, (N,2) array ์์ฑ
# 2. BallTree ์ด๊ธฐํ (์ ํด๋ฆฌ๋์ ๊ฑฐ๋ฆฌ, ๋ฏธํฐ ๋จ์)
tree = BallTree(coords, metrid = 'euclidean')
# 3. ํน์ ๊ฑฐ๋ฆฌ ๋ฐ๊ฒฝ ์ด๋ด ์ธ๋ฑ์ค ์ถ์ถ (์. 3000 ๋ฏธํฐ)
neihbors_idx = tree.query_radius(coords, r = 3000) # ๊ฐ ๊ฒฉ์๋ณ ๊ฒฐ๊ณผ Index๋ง ๊ฐ์ ธ์ค๊ธฐ
# 4. ์ถ์ถ ์์
# 0๋ฒ์งธ index ๊ฒฉ์ ๊ธฐ์ค ๋ฐ๊ฒฝ 3000m ์ด๋ด์ ๊ฒฉ์๋ค
gdf.iloc[neihbors_idx[0]] ์ฐธ๊ณ ์ฌ์ดํธ