AI 기반 버스 운행행태 분석을 통한 스마트 교통복지 연구

기계학습 기반 버스운전 패턴 분석을 통한 스마트 시티 교통복지 실현

연구 개요

본 연구는 2025 파란학기 블루익스트림 프로젝트에서 도출된 장애인 이동권 제약이라는 절박한 사회 문제에 대한 깊은 공감에서 시작되었습니다. 실태조사를 통해 확인된 바와 같이, 장애인 승객들은 버스의 급정거 및 급가속과 같은 난폭 운전 행태로 인해 심각한 불안감과 사고 위험에 노출되어 있으며, 이는 궁극적으로 그들의 자율적이고 안전한 이동을 심각하게 제한하는 요인으로 작용합니다. 이러한 문제 의식 아래, 본 연구는 공공 BIS 데이터의 잠재력을 최대한 활용하여 이러한 난폭 운전 패턴을 정량적으로 측정하고 분석함으로써, 교통 약자의 복지를 획기적으로 향상시킬 수 있는 실질적인 정책적 개입의 가능성을 모색하고자 합니다.

이론적 배경

  • 스마트 시티 교통 데이터 분석: 실시간 BIS 데이터는 도시 내 교통 흐름을 파악하는 핵심 자료일 뿐만 아니라, 잠재된 운전 행태 문제점을 진단하는 데 중요한 통찰을 제공합니다.
  • 기계학습 기반 운전자 행태 분석: XGBoost 등 분류 모델과 SHAP을 통한 해석 가능성 확보는 단순히 예측을 넘어 정책 결정자들에게 신뢰할 수 있는 근거를 제시할 수 있게 합니다.

연구 방법

  • 1단계 - 데이터 수집:
    서울시 BIS(Open API)를 활용하여 버스의 실시간 위치(GPS) 정보를 수집합니다. 수집 항목에는 맵매칭x좌표, 맵매칭y좌표, 버스 ID, 노선 ID, 정류소 도착여부부, 차량내부 혼잡도 등의 정보가 포함됩니다.

    ① 구현 방식:
    - Python의 requests 라이브러리를 사용해 RESTful API로부터 실시간 데이터를 JSON 형태로 요청합니다.
    - 응답 데이터를 수신한 후, pandas 데이터프레임으로 변환하여 1차 정제(형 변환, 중복 제거 등)를 수행한 뒤 로컬 CSV 또는 PostgreSQL에 저장합니다.

    ② 예외 처리:
    - 네트워크 오류나 API Rate Limit에 대비하여 try-except 구문으로 예외를 처리하며, 실패 시 최대 3회 재시도합니다.
    - API 응답 코드 429(Too Many Requests) 수신 시, 일정 시간 대기 후 재호출하는 백오프 전략(backoff strategy)을 적용합니다.
    - 로그 파일을 통해 API 호출 실패 내역, 수집된 레코드 수, 중복 데이터 여부 등을 기록하여 추후 분석 및 점검이 가능하게 합니다.

    ③ 데이터 저장:
    - 단기 수집 결과는 CSV 또는 SQLite에 저장 후 일별로 백업하며, 중장기 운영 시 PostgreSQLPostGIS 확장을 활용해 공간 정보 기반 질의를 지원합니다.
    - 데이터는 날짜별 파티셔닝을 통해 효율적으로 저장되며, 정기적으로 누락 데이터 유무를 확인하는 스케줄링 스크립트도 별도 관리됩니다.

    ④ 확장성:
    Apache Kafka는 대규모 분산 환경 및 실시간 스트림 처리에 유리하지만, 초기 연구 단계에서는 데이터의 신속한 확보와 분석 효율성에 집중하기 위해 경량화된 방식을 채택했습니다. 하지만 연구가 발전하여 실시간 경고 시스템 등으로 확장될 경우, 이러한 기술들을 적극적으로 검토할 예정입니다.
  • 2단계 - ETL 및 DB 관리:
    BIS Open API로부터 수집된 원시 JSON 데이터를 pandas를 이용해 정형화한 후, 데이터 전처리 및 공간좌표 기반 분석에 용이한 PostgreSQL 데이터베이스에 저장하는 과정을 수행합니다.

    ① Extract:
    - 수신한 JSON 포맷의 데이터를 DataFrame 형태로 변환합니다.
    - key-value 구조의 중첩된 속성은 평탄화(flatten)하여 각 열(column)으로 분리하고, 시간 필드는 UTC 기준으로 통일합니다.

    ② Transform:
    - 이상치 제거: 위도·경도 값이 비정상 범위(예: 서울 시 경계 밖, 또는 GPS 오류로 인한 순간적인 튀는 값)인 레코드는 과감히 필터링하여 데이터의 신뢰성을 확보합니다.
    - 결측값 처리: GPS 누락이나 정류장 ID가 비어 있는 경우는 해당 row를 삭제하거나 'unknown'으로 대체하는 등 분석 목적에 부합하도록 일관된 전략을 적용합니다.
    - 추가 파생 컬럼 생성: 시간대 구분, 요일, 주말 여부 등의 파생 피처는 운전 행태에 영향을 미치는 시간적 패턴을 발견하는 데 필수적인 통찰을 제공합니다.
    ③ 데이터베이스 스키마 설계:
    - 정규화를 통해 bus_location, bus_route, bus_stop, weather_info 등 주제별 테이블로 나눕니다.
    - 각 테이블은 foreign key로 연동되며, bus_id, timestamp 기준의 다중 인덱스를 생성하여 질의 효율을 높입니다.

  • 3단계 - 속도 및 가속도 계산:
    수집된 GPS 데이터는 시간 순으로 정렬된 후, 각 위치 간의 이동 거리를 계산하여 속도 및 가속도를 산출합니다.

    ① 거리 계산 (Distance):
    - 각 레코드는 (X, Y) 좌표를 포함하고 있으며, 연속된 두 지점 간의 거리(Δs)는 haversine 공식을 사용해 구면 거리(km)로 환산됩니다.
    - Haversine 공식은 지구 곡률을 고려하므로, 단거리 도시 내 이동에서도 정밀한 거리 측정이 가능합니다.

    ② 속도 계산 (Speed):
    - Δs (거리)를 시간 간격 Δt = 5초 (0.00139시간)로 나누어 시속(km/h) 또는 초속(m/s) 기준 속도를 계산합니다.
    - 예시: Δs = 0.025km, Δt = 5초 → v = 0.025km / (5/3600)h = 18km/h
    - 이상치 필터링을 위해 순간 속도가 IQR 75% 를 초과하는 경우는 이상치로 간주하여 제거합니다.

    ③ 가속도 계산 (Acceleration):
    - 연속된 두 시점의 속도 값의 차이를 시간 간격으로 나누어 가속도 a (m/s²)를 계산합니다.
  • 4단계 - 라벨링:
    전 단계에서 계산한 가속도 값을 바탕으로 운전 행태를 이진 분류(Label) 형태로 변환합니다.

    ① 기준 설정:
    - 가속도 a ≥ 초당 11.3km/h: 급가속 이벤트로 간주하여 label = 1 (위험)
    - 가속도 a ≤ 초당 -8Km/h: 급정거 이벤트로 간주하여 label = 1 (위험)
    - 초당 -8Km/h < a < 초당 11.3km/h: 정상 운전으로 간주하여 label = 0 (정상)

    ② 기준 근거:
    - 한국교통안전공단의 연구 보고서 및 수십 년간 축적된 버스 블랙박스 사고 영상 분석 자료에서 제시된 평균적인 급가속/급감속 수치 기준을 선행 연구의 결과로써 적극 반영하였습니다. - 특히 대중교통 이용자의 체감 안전에 가장 직접적으로 영향을 미치는 가속도 구간을 기준점으로 설정함으로써, 실질적인 교통 복지 향상이라는 연구 목표에 부합하는 라벨링을 수행했습니다.
    ③ 라벨링 방식:
    - 전처리된 시계열 데이터의 각 시점마다 해당 시점의 가속도 값을 기준으로 label 컬럼을 부여합니다.
    - 이벤트 탐지 후, 이벤트 지속시간이 2초 미만인 경우는 노이즈 가능성이 높아 제거하거나 label = -1 (무시)로 별도 처리 가능합니다.

    ④ 불균형 문제 대응:
    - 모델 학습 시 발생할 수 있는 편향을 최소화하기 위해 SMOTE 또는 Class Weight 조정을 통해 학습 시 균형을 적극적으로 보완하고, 이로 인해 소수 클래스(위험 운전)의 예측 성능을 극대화할 것입니다.
    ⑤ 활용 목적:
    - 이 라벨은 이후 모델 학습 시 Target 변수로 사용되며, 각 시점이 ‘위험 운전인지 아닌지’를 예측하는 지도학습 기반의 분류 모델 학습에 직접 적용됩니다.
  • 5단계 - 피처 엔지니어링:
    위험 운전 행태에 영향을 줄 수 있는 다양한 외생적·내생적 요인들을 포괄적으로 반영하여, 모델의 예측력을 극대화할 수 있는 주요 피처(feature)를 구성합니다.
    ① 시간 기반 변수:
    - hour: 시각 정보 (0~23)
    - weekday: 요일 정보 (0=월 ~ 6=일)
    - 혼잡 시간대 여부 (is_peak_hour): 출퇴근 시간(7~9시, 17~19시)을 1로 설정

    ② 위치 기반 변수:
    - near_station: 버스 위치와 정류장 좌표 간 Haversine 거리가 50m 이하인 경우 1, 그렇지 않으면 0
    - segment_id: 노선 상 동일 정류장 간 구간을 식별하는 고유 ID (정류장쌍 기반)

    ③ 속도 기반 변수:
    - avg_speed_1min: 직전 1분간 이동 평균 속도
    - std_speed_1min: 직전 1분간 속도 표준편차
    - acceleration: 현재 시점 가속도 값

    ④ 혼잡도 및 날씨 변수:
    - congestion_level: 시군구 단위 대중교통 승하차 인원(서울열린데이터 광역혼잡도 API 활용)
    - precipitation, temperature: 기상청 초단기 실황 데이터를 정류장 위치 기준으로 매칭

    ⑤ 외부 데이터 통합 방법:
    - 정류장 ID를 기준으로 시간대별 승하차량 데이터를 merge하고,
    - 버스 위치의 시군구 정보를 기반으로 날씨, 혼잡도 데이터를 정확히 조인함으로써, 다양한 소스의 데이터를 유기적으로 결합하여 현실 세계의 복잡한 운전 환경을 반영합니다.
    ⑥ 기타 고려 사항:
    - 모든 피처는 StandardScaler 또는 MinMaxScaler로 정규화하여 XGBoost 입력에 적합하게 전처리
    - 실시간 분석을 고려하여 이동 평균 계산 및 외부 데이터 병합 로직을 window-based streaming 구조로 설계할 수 있음
  • 6단계 - 모델 훈련:
    수집·정제된 학습 데이터를 기반으로 XGBoost Classifier를 이용해 이진 분류 모델을 학습합니다. 주어진 문제는 '급가속/급정거 여부'를 예측하는 이진 분류(binary classification)이며, 입력 피처는 시간대, 평균 속도, 혼잡도, 정류장 위치, 날씨 등 구조화된(tabular) 특성이 많은 데이터로 구성되어 있습니다.
    ① 주요 하이퍼파라미터 조정:
    - eta (학습률): 모델이 한 번에 얼마나 크게 업데이트할지를 결정. 작은 값(예: 0.1)을 사용하여 과적합 방지
    - max_depth: 트리의 최대 깊이로, 과적합을 조절하며 복잡도 제어
    - subsample: 각 트리를 만들 때 사용할 샘플 비율로, 과적합 방지에 효과적
    - scale_pos_weight: 클래스 불균형을 보정하기 위해 양성 클래스에 가중치를 부여

    ② 데이터 불균형 처리:
    급가속/급감속 이벤트는 전체 운행 데이터 중 소수에 불과할 것이므로 class imbalance 문제가 존재합니다. 이를 해결하기 위해 가중치 조정, SMOTE 오버샘플링 기법, undersampling 전략을 실험적으로 비교합니다.

  • 7단계 - 모델 평가:
    K-Fold Cross Validation을 사용하여 모델의 일반화 성능을 평가합니다.

    ① 평가 방식:
    - K = 5 또는 10으로 설정하여 전체 데이터를 5~10개로 분할
    - Fold 기준은 bus_id 단위로 그룹핑하여 동일 차량의 데이터가 훈련 세트와 테스트 세트에 중복되지 않도록 구성
    - 이렇게 하면 특정 차량의 주행 특성이 과적합되는 것을 방지하고, 모델이 새로운 차량에도 일반화될 수 있는지를 검증 가능
    ② 사용 지표:
    - Precision: 위험 운전이라고 예측한 것 중 실제 위험 운전인 비율
    - Recall: 실제 위험 운전 중 모델이 잡아낸 비율
    - F1-Score: Precision과 Recall의 조화 평균, 불균형 데이터셋에 적합
    - ROC AUC: 이진 분류 모델의 전체 성능을 확인하기 위한 면적 지표

  • 8단계 - 해석:
    학습된 XGBoost 모델에 대해 SHAP(SHapley Additive exPlanations) 값을 계산하여, 각 피처가 모델 예측에 어떤 영향을 미쳤는지를 분석합니다.

    ① 사용 방법:
    - shap.Explainer(model).shap_values(X)를 통해 각 예측에 대한 SHAP 값을 계산
    - shap.summary_plot(): 전체 피처의 중요도와 영향 방향을 요약해 시각화
    - shap.dependence_plot(feature, shap_values, X): 개별 피처의 값 변화가 예측에 어떤 영향을 미치는지 시각적으로 분석

    ② 분석 목적:
    - 평균 속도, 정류장 인접성, 혼잡도 등의 피처가 위험 운전 예측에 얼마나 기여하는지 분석하여 정책 개입 지점 도출
    - 예: "혼잡도가 높은 출퇴근 시간대에 급정거 가능성이 높음" → 운전자 교육 시간 집중 배치 근거 마련

    ③ 확장 가능성:
    - 해석 결과를 정책 리포트나 대시보드에 시각적으로 통합하여 관리자 또는 의사결정권자에게 직관적인 피드백 제공 가능
    - 예: “해당 노선은 오후 6시경 특정 정류장에서 반복적인 급정거 발생” → 운행 스케줄 조정 근거 제공

기대되는 결과

  • 1. BIS 기반 위험 운전 탐지 모델 구축 및 위험 시간·위치 식별
  • 2. 혼잡도, 기상 등 외부 요인이 운전 행태에 미치는 영향 분석
  • 3. 지자체 대상 운전자 교육·배차 조정 등의 정책적 근거 제시
  • 4. 장애인 등 교통약자 중심의 교통복지 정책 설계 지원