KT AIVLE SCHOOL 5기/Mini Project

[Mini Project] 3월 20 ~ 22일 미니프로젝트 2차 후기

JJong-suk 2024. 4. 17. 11:07

그동안 배운 데이터 분석과 수집을 이용하여 미니프로젝트 2차를 수행하였다.

20일 부터 22일 총 3일동안 진행하였다.

서울시의 버스 정류장, 유동인구, 주민등록인구, 업종 등록 데이터을 통해 어느 지역에 노선을 추가하면 좋을지 고민하는 것이 이번 주제이다.나는 이 주제를 수행하기 위해 다음과 같이 진행하였다.


[3월 20일 첫째날]

1) 버스 정류장 데이터

미니프로젝트 1차와 마찬가지로 원활한 의사소통을 위해 전농교육장을 예약하였다.

지난번 같은 조였던 조원, 회식 때 인사나눴던 조원, 처음 보는 조원 여러명이 섞였지만 간단한 인사 후 프로젝트에 돌입하였다.

지금 생각해보면, 다들 성격들이 좋고 말도 잘 통해서 프로젝트 또한 서로서로 도우며 잘 수행했던 것 같다.간단히 프로젝트를 복습하면,첫째날은 버스정류장과 유동인구의 데이터를 분석하는 것이다.먼저, Crisp-dm에 따라 비즈니스 파악을 하면 문제는 '어느 지역에 노선수를 추가해야 할까?' 이므로 '어떤 feature가 노선수에 영향을 줄까?'를 생각해보았다. (버스 정류장 데이터의 경우 승객수가 영향을 줄 것이라 생각하였다.)그 후, 각 데이터가 어떻게 생겼는지 파악하고 우리에게 필요한 데이터로 가공하는 과정을 거친다.

info()를 통해 데이터가 결측치가 없는 것을 확인하였지만 null값이 아닐 뿐 다른 값으로 결측치가 표현되어 있다.

또한, head()를 통해 전체적인 데이터를 구조를 이해하였고 지역구별 노선수를 묶어 데이터를 가공할 필요를 느꼈다. 

그리고 서울시 뿐만 아니라 다른 지역의 노선도 몇몇 포함되어 있는 것을 확인하였고, 서울시만의 버스노선 데이터 추출을 하기 위한 가공을 진행할 필요 역시 느낄 수 있었다.

지역구별 노선수는 버스정류장 ARS번호를 통해 묶을 수 있는데, 예를 들어 버스정류장 ARS번호가 01로 시작하면 이는 종로구를 의미한다.

slice_bus1 = slice(1)
slice_bus2 = slice(2)
df['자치구'] = [str(data)[slice_bus2] if len(data)==5 else str(data)[slice_bus1] 
						for data in df['버스정류장ARS번호']]

ARS번호는 최대 5자리로 이루어져 있기 때문에 길이에 따라 슬라이스가 다름을 느꼈고 ARS번호의 길이에 따라 슬라이스 객체를 다르게 생성하여 '자치구'라는 컬럼을 생성할 수 있었다.

그 후, null값으로 표현되지 않고 '~'값으로 표현된 결측치들을 replace하여 결측치를 제거하였다.

결국 자치구별로 버스정류장의 갯수를 파악할 수 있었다. (컬럼명 수정을 깜박했다...)

이후, 서울의 버스 정류장 데이터만 포함하고 있는 데이터와 조인을 진행하여 서울시 지역구별 버스 노선수를 완전히 구해낼 수 있었다.

최종적으로 각 컬럼들을 이용하여 다양한 파생변수를 만들었고 최종 데이터프레임은 다음과 같다.

 

2) 유동인구 데이터

데이터를 살펴보면 다음과 같다.

이 데이터셋에서는 노선수에 영향을 주는 것이 무엇이 있을까 생각해 보면 이동시간이 영향을 줄 것이라 생각하였다.

여기서도 결측치를 다르게 표현하였는데, 이동인구(합)에서 '*'로 표현되어 중위값인 1.5로 대체해주었다.

df = df[(seoul_moving['출발 시군구 코드'] < 20000) & (df['도착 시군구 코드'] < 20000)]

위와 마찬가지로 서울 지역의 데이터만 고르기위해 출발 시군구 코드와 도착 시군구 코드가 20000보다 작은 값들을 골라주었다.

그 후, 총 이동시간과 총 이동인구 등을 각각 평균 이동 시간과 이동인구를 통해 컬럼을 추가해 주었다.

첫째날을 마무리 하면서 두 데이터를 가지고 어느 지역에 노선수를 추가해볼까를 고민해 보았다.

그 전에 나는 첫째날 진행한 두 데이터프레임을 자치구를 가지고 조인을 진행하여 고민하였다.

대표적인 분석 예시 하나만 들어보면 다음과 같다.가설 : 총 이동인구와 정류장 수는 관계가 있을까? (즉, 관계가 있다면 총 이동인구가 많은 곳에 정류장 수가 많이 존재할까?)

import scipy.stats as spst
feature = '총 이동인구'
target = '정류장수'
spst.pearsonr(df[feature], df[target])
=> PearsonRResult(statistic=0.39575554443434996, pvalue=0.050198531398316655)

위 가설을 증명하기 위해 regplot과 피어슨 상관계수를 조사해보았다.

그 결과 pvalue의 값은 0.05와 거의 유사하여 귀무가설을 기각하기에 충분하다고 알 수 있었고 보통의 선형관계를 갖는 것을 알 수 있었다.

 

[3월 21일 둘째날]

1) 주민등록인구 데이터

위 데이터를 보았을 때, 남성과 여성의 인구 정도의 feature만 필요하다고 느꼈고 첫째날에 비해 수월한 전처리를 진행하였다.

위의 행은 필요없다고 느껴 2번째 행부터 시작하며 데이터를 읽어왔고 필요한 컬럼만 불러 다음과 같은 데이터프레임을 구성하였다.

2) 업종등록 데이터

첫번째 데이터와 마찬가지로 첫번째 행은 필요없어보였으며, 특정 컬럼만을 뽑을 필요가 있었다.

특정 컬럼도 기준이 필요하여 버스정류장 설치에 필요한 업종데이터만을 고려하였고, 종사자 수가 많은 업종을 중점으로 생각하였다.

하지만 택시운송업의 경우 자차로 택시를 하시는 분이 있다고 생각하였고 이를 고려하여 택시운송업을 제외한 상위 5개의 종사자 수를 가지는 컬럼을 기준으로 하였다. (택시의 경우 추가 데이터로 다음과 같은 의견에 뒷받침할 근거를 찾을 필요가 있다!)

따라서 다음과 같이 최종데이터프레임을 형성하였다.

이후, 첫째날과 마찬가지로 데이터분석을 진행하였다.

모두 수치형데이터 이므로 선형관계를 생각해보았고, 다른 변수를 설명하는 변수 사이의 관계를 파악할 수 있었다.

 

[3월 22일 셋째날]

마지막날은 첫째날과 둘째날 도출한 데이터들을 최종적으로 합치고 가설을 세우고 이를 증명해보는 과정으로 진행되었다.

데이터프레임들을 합치기 전에 단변량분석을 통해 각 변수들이 어떤 값들을 갖는지 대충 파악할 수 있었다.

여러가지 가설이 많았지만 하나만 정리해서 본다면,

가설 : 노선수와 승 / 하차 총 승객수는 관련이 있을 것이다.

그에 따른 결과는 모두 pvalue의 값이 0.05보다 작아 대립가설을 생각해 볼 수 있었고, 상관계수 또한 강한 양의 상관관계를 갖는 것을 볼 수 있었다.

따라서 승 / 하차 총승객수와 노선수는 관련이 있는 것을 알 수 있었다.

그 후, 어떤 자치구에 노선수가 필요할지 생각해 보았고 시각화를 진행하였다.

승차 총 승객수만 생각해본다면 다음과 같이 강동구, 송파구, 강서구, 관악구, 강남구 순으로 나타났다.

하차 총 승객수를 고려하지 않은 이유는 각 변수끼리의 상관관계를 파악하였을 때 승차 총 승객수와 하차 총 승객수는 거의 같다고 나오기 때문에 결과가 유사할 것이라 생각하였다.

실제로 그래프 또한 유사하게 나왔다.

이처럼 다양한 가설을 더 추가하여 총 4개 정도의 가설을 정리하여 제출하였다!

프로젝트 끝!!!

 


이번 미니프로젝트에서 사실 크게 와닿은 것이 있다.

학부시절 팀프로젝트 진행당시 한달이라는 시간이 부여되었지만 충분한 데이터분석을 하지 않고 모델링만 한 기억이 있다.

데이터분석에 충분한 시간을 쏟지 못하고 모델링을 진행하다보니 좋은 결과를 얻지 못하고 과적합한 결과만 나온 것이 떠오른다.

왜 교수님께서 파레토법칙을 강조하셨는지 알 수 있었다.

2차 미니프로젝트와 같이 충분한 데이터 분석을 하여야 각 변수별로 중요한 변수를 추출하고 의미없는 변수들을 가지고 새로운 변수를 파생하거나 사용하지 않는 등 다양한 활용을 할 수 있을 것이라 생각이 들었다.

KT 에이블 스쿨은 학부시절 배우지 못한 깊숙한 부분까지 배울 수 있어 매우 의미깊은 시간이라 생각한다.

2차 미니프로젝트는 좀 더 중요하게 생각하며 계속해서 복습하며 가설을 더 만들어보면 더욱 유익할 것이라 생각하며 글을 마친다.