Overview

경상북도 산사태 취약지역과 대피소 데이터를 수집·정제·시각화해, 대피소 부족·거리 문제·위치 부적절성 등 구조적 문제를 분석한 프로젝트입니다.

청송군을 대상으로 위험지도와 노인 복지시설 데이터를 결합해 신규 대피소 후보지를 재배치함으로써, 추가 인력 없이 평균 대피 거리를 줄일 수 있음을 제안합니다.

Platform: Python

First upload date: 2025-09-08


들어가며

2025년 6월 23일부터 8월 29일까지 SBS데이터사이언스와저널리즘아카데미 3기에 참여하여 데이터 분석을 배우고, 기사도 써보았습니다.

제 개인프로젝트 주제는 산사태 대피소 문제였고, 어떻게 데이터를 수집하고 분석하여, 기사를 작성하였는지 여기에 남겨보고자 합니다.

기사보러가기

Github 바로가기


분석 배경

최근 지구온난화로 한반도에 극한호우가 자주 발생하고 있죠. 이런 상황에서 폭우 피해만큼이나 우려되는 것이 바로 산사태입니다. 산간지방일수록 산사태는 점점 일상에 위협이 되어가고 있습니다.

산림청은 산사태를 피해 예방을 위해 사전대피를 매우 강조하고 있습니다. 장마철이면 심심치않게 산사태 경보 및 대피권고 재난안전문자가 울리곤 합니다. 대피방법 교육도 자주 합니다.

하지만, 정작 대피할 곳이 없다면 다 무슨 소용일까요?

산사태 피해 가능성이 높은 지역인 산사태 취약지역과 산사태 대피소 데이터를 가지고 경상북도의 산사태 대피소 실태를 분석해보았습니다.

데이터 수집 및 정제

2025 경상북도 산사태 취약지역 지정현황

6275 rows x 15 columns

산사태 취약지역의 위치정보, 유형, 지정면적 데이터가 보입니다.

위경도 좌표에는 일부 오류가 있어 GCP(Google Cloud Platform)를 활용해 googlemaps api key를 발급받아 지번주소를 새로운 위경도 좌표로 변환해주었습니다.

import googlemaps
import time
 
# Google Maps API 키 설정
gmaps = googlemaps.Client(key='Your Key')		
 
# 좌표 저장용 컬럼 추가
df_2025['위도_geo'] = None
df_2025['경도_geo'] = None
 
# 주소 컬럼 할당
addr = 'addr'
 
# 주소 → 위경도 변환
for idx, row in df_2025.iterrows():
	address = row[addr]
	try:
		geocode_result = gmaps.geocode(address)
		if geocode_result:
			location = geocode_result[0]['geometry']['location']
			df_2025.at[idx, '위도_geo'] = location['lat']
			df_2025.at[idx, '경도_geo'] = location['lng']
		else:
			print(f"[경고] 주소를 찾을 수 없음: {address}")
	except Exception as e:
		print(f"[에러] {address} 변환 실패: {e}")
	time.sleep(0.01)  # 과도한 요청 방지 (QPS 제한 고려)

지정면적 column의 결측은 평균값으로 대치하였습니다.

경상북도 산사태 대피소 지정현황

경상북도 산사태 대피소의 고유 id, 지번주소, 위경도 데이터 등이 들어있습니다.

EDA

위 두 데이터셋을 간단하게 folium 라이브러리를 활용하여 지도에 표시해보았습니다.

  • 육안으로 보이는 특징은
    1. 취약지역(빨강)에 비해 대피소(초록)가 적어 보인다
    2. 취약지역과 대피소가 멀어 보인다

정도가 있겠습니다. 실제로도 그럴지 좀 더 자세히 분석해보겠습니다.

1. 대피소 부족

경북지역 산사태 취약지역은 총 6275개, 대피소는 2239개소로 약 35% 비율입니다.

시군구 단위로 본다면 상당수가 40% 이하로, 전반적 대피소 부족 현상을 보이고 있습니다.

읍면동 단위로 분석한 결과, 극단적으로 대피소가 부족한 몇몇 지역을 확인할 수 있었습니다.

2. 너무 먼 대피소

harversine 라이브러리로 산사태 취약지역으로부터 가장 가까운 대피소까지의 직선거리를 구해보았습니다.

거리 평균 약 1.4km, 중위값 약 1.2km였으며, 6km 이상 떨어진 대피소도 존재했습니다.

이를 대한민국 노인 보행속도 평균 1.06m/s로 소요시간 환산 결과,

평균 약 22분, 중위값 약 19분이었으며, 1시간 이상 소요되는 대피소가 166개소 존재했습니다.

3. 너무 가까운 대피소

반대로 산사태 취약지역과 대피소가 맞붙어있는 경우도 있었습니다.

위 사진은 경산시의 한 대피소입니다. 산사태 취약지역과 대피소 간 거리는 불과 약 30m로, 네이버 로드뷰 확인 결과 산 바로 아래 위치해있어 산새태 피해 가능성이 매우 높아보입니다.

이렇듯 현행 산사태 대피소는 선정 및 관리에 허점을 보이고 있습니다.

법적 구속력, 예산 등 여러 이유가 있겠지만 가장 큰 원인은 행정 인력 부족이 아닐까 추측됩니다.

경북 산사태 취약지역의 수가 2024년 5396개에서 2025년 6275개로 큰 폭으로 느는 등, 취약지역의 수는 매년 엄청나게 증가하고 있습니다.

지자체는 연 2회 이상 산사태 취약지역과 대피소를 현지 점검해야 하기에, 행정 인력이 부족하여 대피소 지정에 신경쓰지 못하는 게 아닐까 싶습니다.

그럼 이 문제를 어떻게 타개하는 것이 좋을까요?

청송군 산사태 대피소 재배치

청송군은 취약지역으로부터 대피소까지의 거리 평균이 약 1.6km로 매우 먼 편이며, 지난 3월 발생한 산불 영향이 큰 지역이기에 분석 대상으로 삼았습니다.

경상북도 청송군 위험지도.tif

산사태 위험등급 1-5단계 값이 매핑되어있는 tif파일 입니다. rasterio 라이브러리를 활용하여 핸들링했습니다.

청송군 노인 복지시설 현황

이중 청송군 소재 복지센터 및 경로당 232곳을 후보지로 하였고

googlemaps 라이브러리를 활용하여 ‘소재지’ column을 위경도 좌표로 변환하였습니다. (자세한 방법은 api활용코드를 확인하세요)

재배치 결과

sklearn 라이브러리의 NearestNeighbors로 거리를 계산, 산사태 취약지약으로부터 0.2~1.5km 거리에 있으며, 산사태 위험등급이 3등급 이하인 지역에 위치한 최적의 대피소 후보지 99곳을 새로 선정해보았습니다. 자세한 코드는 여기서 확인하세요

그 결과 취약지역에서부터 신규 대피소 99개소까지의 거리는 기존 평균 약 1.6km에서 약 1.2km로 크게 줄었습니다.

추가적인 행정인력 투입 없이 문제를 해결할 수 있는 겁니다.


나가며

이건 제 첫 데이터 분석 프로젝트였습니다.

생각보다 도메인 지식을 쌓는 것도 오래 걸리고, 데이터를 수집하는 단계부터 막히는 부분이 많아 고생한 기억이 나네요.

데이터 분석의 목적이 기사 작성이다보니 raw데이터와 분석 과정의 신뢰성을 계속 신경쓰고, 배경지식도 꼼꼼히 조사할 필요가 있었습니다. (데이터 저널리즘에서 가장 중요한 요소라고 생각합니다)

그래도 힘든 과정을 뒤로하고 내가 만든 시각화 자료들을 보면 나름의 뿌듯함과 성취감이 드는 게 데이터 분석의 묘미가 아닐까 싶네요.

아래는 해당 프로젝트 발표PPT입니다. 공들여 만들었는데 발표 시간이 5분이라 아쉬워 여기에라도 올려봅니다. 긴 글 읽어주셔서 감사합니다. 발표ppt보러가기