일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Docker
- programmers
- PYTHON
- 편스토랑 우승상품
- Baekjoon
- 코로나19
- 맥북
- 캐치카페
- 더현대서울 맛집
- 백준
- github
- ChatGPT
- 프로그래머스 파이썬
- SW Expert Academy
- gs25
- dacon
- 편스토랑
- 파이썬
- 자연어처리
- 금융문자분석경진대회
- hackerrank
- Real or Not? NLP with Disaster Tweets
- AI 경진대회
- Kaggle
- 우분투
- 프로그래머스
- leetcode
- Git
- 데이콘
- ubuntu
- Today
- Total
솜씨좋은장씨
설날 귀성/귀경시간을 예측해보자! - 01 데이터 수집 및 시각화를 통한 최적, 혼잡시간대 추측해보기 본문
설날 귀성/귀경시간을 예측해보자! - 01 데이터 수집 및 시각화를 통한 최적, 혼잡시간대 추측해보기
솜씨좋은장씨 2020. 1. 14. 16:14
사진출처
2019년 추석
T맵을 운영하고 있는 SKT와 카카오네비를 운영하고 있는 KAKAO에서 지난 5년간 축적된 빅데이터를 분석하여
귀성/귀경 시간을 예측하여 정보를 공개한 것을 보고 저도
고속도로 주요 톨게이트 사이의 소요시간 데이터를 모아 그래프를 그려 추측해본 적이 있었습니다.
아쉬웠던 점은 추석이 끝나가는 시점이어서 추석 1일 후, 2일 후의 귀경시간만 확인해보았고
아직 머신러닝/딥러닝을 활용하여 모델링을 해본 적이 없었기에
예측까지는 해보지 못하고 그래프를 그려 추측만 해보았던 점이 아쉬웠습니다.
다음 설날을 기약하며 글을 마쳤었습니다.
드디어 2020년 설날!
드디어 기약하던 설날이 코앞으로 다가왔습니다.
올해의 목표는!
과거 설날 데이터를 가지고
1. 데이터를 수집하여 그래프를 그려 데이터를 비교 해보는 것에 더불어 머신러닝/딥러닝을 활용하여 시계열 예측을 해보고
2. 카카오, SKT에서 예측한 데이터와 비교
3. 실제 소요시간과의 비교
해보는 것을 목표로 삼아보았습니다.
<2018년 데이터로 추측해본 2020년 귀성/귀경길 혼잡, 최적 시간대>
평일/휴일 비율이 비슷한 2018년 설 연휴의 데이터를 가지고 추측해본 시간대입니다.
< 데이터 수집 >
먼저 지난 추석에 데이터를 수집했던 방법에서 변수만 바꾸어 설날때의 데이터를 받아왔습니다.
귀경 소요시간
def getgoUpTimeData(startPageNo, endPageNo, Year):
info_df_daegeon = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
info_df_daegu = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
info_df_busan = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
info_df_gwangju = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
info_df_ganglung = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
info_df_mockpo = pd.DataFrame(columns=["출발지", "기준시간", str(Year)+"소요시간"])
daegeon = 0
daegu = 0
busan = 0
gwangju = 0
ganglung = 0
mockpo = 0
for pageNo in range(startPageNo, endPageNo):
startPoints = []
stdTimes = []
timeTOGOs = []
url = 'http://data.ex.co.kr/openapi/specialAnal/intercityLeadTime'
parameters = {"key":"test", "type":"xml", "numOfRows":"24", "pageNo":str(pageNo), "iYear":str(Year)}
req = requests.get(url, params=parameters)
xml_data = xmltodict.parse(req.text)
infomations = xml_data['data']['intercityLeadTimeLists']
for info in infomations:
if info['dirNm'] == '귀경방향':
if info['stUnitNm'] == "대전":
info_df_daegeon.loc[daegeon] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
daegeon = daegeon + 1
elif info['stUnitNm'] == "대구":
info_df_daegu.loc[daegu] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
daegu = daegu + 1
elif info['stUnitNm'] == "부산":
info_df_busan.loc[busan] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
busan = busan + 1
elif info['stUnitNm'] == "광주":
info_df_gwangju.loc[gwangju] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
gwangju = gwangju + 1
elif info['stUnitNm'] == "강릉":
info_df_ganglung.loc[ganglung] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
ganglung = ganglung + 1
elif info['stUnitNm'] == "목포":
info_df_mockpo.loc[mockpo] = [info['stUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
mockpo = mockpo + 1
return (info_df_daegeon, info_df_daegu, info_df_busan, info_df_gwangju, info_df_ganglung, info_df_mockpo)
귀성 소요시간
def getgoDownTimeData(startPageNo, endPageNo, Year):
info_df_daegeon = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
info_df_daegu = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
info_df_busan = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
info_df_gwangju = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
info_df_ganglung = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
info_df_mockpo = pd.DataFrame(columns=["도착지", "기준시간", str(Year)+"소요시간"])
daegeon = 0
daegu = 0
busan = 0
gwangju = 0
ganglung = 0
mockpo = 0
for pageNo in tqdm(range(startPageNo, endPageNo)):
startPoints = []
stdTimes = []
timeTOGOs = []
url = 'http://data.ex.co.kr/openapi/specialAnal/intercityLeadTime'
parameters = {"key":"test", "type":"xml", "numOfRows":"24", "pageNo":str(pageNo), "iYear":str(Year)}
req = requests.get(url, params=parameters)
xml_data = xmltodict.parse(req.text)
infomations = xml_data['data']['intercityLeadTimeLists']
# print(infomations)
for info in infomations:
if info['dirNm'] == '귀성방향':
if info['edUnitNm'] == "대전":
info_df_daegeon.loc[daegeon] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
daegeon = daegeon + 1
elif info['edUnitNm'] == "대구":
info_df_daegu.loc[daegu] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
daegu = daegu + 1
elif info['edUnitNm'] == "부산":
info_df_busan.loc[busan] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
busan = busan + 1
elif info['edUnitNm'] == "광주":
info_df_gwangju.loc[gwangju] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
gwangju = gwangju + 1
elif info['edUnitNm'] == "강릉":
info_df_ganglung.loc[ganglung] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
ganglung = ganglung + 1
elif info['edUnitNm'] == "목포":
info_df_mockpo.loc[mockpo] = [info['edUnitNm'], info['stdHour'], float(info['trtm'][0:5])]
mockpo = mockpo + 1
return (info_df_daegeon, info_df_daegu, info_df_busan, info_df_gwangju, info_df_ganglung, info_df_mockpo)
2019년 설날
날짜 | 도시 순서 | numOfRows | pageNo |
설날 3일전 (D-3) 귀성길 | 대전, 대구, 부산, 광주, 강릉 목포 | 24 | 48 ~ 54 |
설날 3일전 (D-3) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 54 ~ 60 |
설날 2일전 (D-2) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 60 ~ 66 |
설날 2일전 (D-2) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 66 ~ 71 |
설날 1일전 (D-1) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 71 ~ 77 |
설날 1일전 (D-1) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 77 ~ 83 |
설날 당일 (D) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 83 ~ 89 |
설날 당일 (D) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 89 ~ 95 |
설날 1일후 (D+1) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 95 ~ 101 |
설날 1일후 (D+1) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 101 ~ 107 |
설날 2일후(D+2) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 107 ~ 113 |
설날 2일후(D+2) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 113 ~ 119 |
설날 2일후(D+3) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 119 ~ 125 |
설날 2일후(D+3) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 125 ~ 131 |
2018년 설날
날짜 | 도시 순서 | numOfRows | pageNo |
설날 3일전 (D-3) 귀성길 | 대전, 대구, 부산, 광주, 강릉 목포 | 24 | 48 ~ 54 |
설날 3일전 (D-3) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 54 ~ 60 |
설날 2일전 (D-2) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 60 ~ 66 |
설날 2일전 (D-2) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 66 ~ 72 |
설날 1일전 (D-1) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 72 ~ 78 |
설날 1일전 (D-1) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 78 ~ 84 |
설날 당일 (D) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 84 ~ 90 |
설날 당일 (D) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 90 ~ 96 |
설날 1일후 (D+1) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 96 ~ 102 |
설날 1일후 (D+1) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 102 ~ 108 |
설날 2일후(D+2) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 108 ~ 114 |
설날 2일후(D+2) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 114 ~ 120 |
설날 2일후(D+3) 귀성길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 120 ~ 126 |
설날 2일후(D+3) 귀경길 | 대전, 대구, 부산, 광주, 강릉, 목포 | 24 | 126 ~ 132 |
설날 기간으로 제공되는 데이터는 작년 추석과 마찬가지로 2018년, 2019년 총 2년치의 데이터를 얻을 수 있었습니다.
< 수집한 데이터 그래프로 시각화 해보기>
작년과 마찬가지로 수집한 데이터를 그래프로 시각화 하여 확인해보았습니다.
def drawGraph(data_df_2018, data_df_2019, day, updown):
plt.rcParams['figure.figsize'] = (15, 8)
if updown == 0:
ax = data_df_2018.plot.line()
ax1 = data_df_2019.plot.line(ax = ax, grid=True)
ax1.set_title("2018년 / 2019년 설날 " + day +" 시간별 "+ "(" + data_df_2019.loc[0]['출발지'] +" -> 서울) 소요시간", size=25)
ax1.set_xticks(list(range(0,24)))
ax1.set_xlabel("시간 (00시~23시)", size=20)
ax1.set_ylabel('소요시간 (분)', size=20)
else:
ax = data_df_2018.plot.line()
ax1 = data_df_2019.plot.line(ax = ax, grid=True)
ax1.set_title("2018년 / 2019년 설날 " + day +" 시간별 "+ "( 서울 -> " + data_df_2019.loc[0]['도착지'] +") 소요시간", size=25)
ax1.set_xticks(list(range(0,24)))
ax1.set_xlabel("시간 (00시~23시)", size=20)
ax1.set_ylabel('소요시간 (분)', size=20)
1. 서울에서 대전까지 소요시간
서울 -> 대전 설날 3일 전 / 2일 전 / 1일 전
서울 -> 대전 설날 당일
서울 -> 대전 설날 1일 후 / 2일 후 / 3일 후
2. 서울에서 대구까지 소요시간
서울 -> 대구 설날 3일 전 / 2일 전 / 1일 전
서울 -> 대구 설날 당일
서울 -> 대구 설날 1일 후 / 2일 후 / 3일 후
3. 서울에서 부산까지 소요시간
서울 -> 부산 설날 3일 전 / 2일 전 / 1일 전
서울 -> 부산 설날 당일
서울 -> 부산 설날 1일 후 / 2일 후 / 3일 후
4. 서울에서 광주까지 소요시간
서울 -> 광주 설날 3일 전 / 2일 전 / 1일 전
서울 -> 광주 설날 당일
서울 -> 광주 설날 1일 후 / 2일 후 / 3일 후
5. 서울에서 강릉까지 소요시간
서울 -> 강릉 설날 3일 전 / 2일 전 / 1일 전
서울 -> 강릉 설날 당일
서울 -> 강릉 설날 1일 후 / 2일 후 / 1일 후
6. 서울에서 목포까지 소요시간
서울 -> 목포 설날 3일 전 / 2일 전 / 1일 전
서울 -> 목포 설날 당일
서울 -> 목포 설날 1일 후 / 2일 후 / 1일 후
7. 대전에서 서울까지 소요시간
대전 -> 서울 설날 3일 전 / 2일 전 / 1일 전
대전 -> 서울 설날 당일
대전 -> 서울 설날 1일 후 / 2일 후 / 3일 후
8. 대구에서 서울까지 소요시간
대구 -> 서울 설날 3일 전 / 2일 전 / 1일 전
대구 -> 서울 설날 당일
대구 -> 서울 설날 1일 후 / 2일 후 / 3일 후
9. 부산에서 서울까지 소요시간
부산 -> 서울 설날 3일 전 / 2일 전 / 1일 전
부산 -> 서울 설날 당일
부산 -> 서울 설날 1일 후 / 2일 후 / 3일 후
10. 광주에서 서울까지 소요시간
광주 -> 서울 설날 3일 전 / 2일 전 / 1일 전
광주 -> 서울 설날 당일
광주 -> 서울 설날 1일 후 / 2일 후 / 3일 후
11. 강릉에서 서울까지 소요시간
강릉 -> 서울 설날 3일 전 / 2일 전 / 1일 전
강릉 -> 서울 설날 당일
강릉 -> 서울 설날 1일 후 / 2일 후 / 3일 후
12. 목포에서 서울까지 소요시간
목포 -> 서울 설날 3일 전 / 2일 전 / 1일 전
목포 -> 서울 설날 당일
목포 -> 서울 설날 1일 후 / 2일 후 / 3일 후
<과거의 데이터를 가지고 최적의 시간 추측해보기>
2018년 설날 연휴
2일 전 | 1일전 | 당일 | 1일 후 | 2일 후 | |
날짜 / 요일 |
2018년 2월 14일 수요일 |
2018년 2월 15일 목요일 |
2018년 2월 16일 금요일 |
2018년 2월 17일 토요일 |
2018년 2월 18일 일요일 |
2019년 설날 연휴
2일 전 | 1일전 | 당일 | 1일 후 | 2일 후 | |
날짜 / 요일 |
2019년 2월 3일 일요일 |
2019년 2월 4일 월요일 |
2019년 2월 5일 화요일 |
2019년 2월 6일 수요일 |
2019년 2월 7일 목요일 |
2020년 설날 연휴
2일 전 | 1일전 | 당일 | 1일 후 | 2일 후 | |
날짜 / 요일 |
2020년 1월 24일 목요일 |
2020년 1월 25일 금요일 |
2020년 1월 26일 토요일 |
2020년 1월 27일 일요일 |
2020년 1월 28일 월요일 (대체) |
2020년의 설날 연휴는 평일/휴일의 배치가 2018년과 유사한 것을 볼 수 있습니다.
이에 시각화를 통한 도시간 이동에 소요시간이 가장 적게 드는
최적의 시간 추측은 2018년 데이터를 기준으로
설날 당일 2일 전 / 2일 후 이 5일 동안의 데이터에서
서울에서 지방으로 내려가는 귀성길은 설날 2일전 ~ 당일
지방에서 서울로 올라가는 귀경길은 설날 당일 ~ 2일 데이터를 가지고
당시에 가장 소요시간이 많이 걸린 시간과 적게 걸린 시간을 찾아 추측해보았습니다.
사용 코드
def findGoodTimeToGo(data_before2, data_before1, data_Dday, data_after1, data_after2, index, UpDown):
data_before2['DAY'] = ['BEFORE2'] * len(data_before2['2018소요시간'])
data_before1['DAY'] = ['BEFORE1'] * len(data_before1['2018소요시간'])
data_Dday['DAY'] = ['DDAY'] * len(data_Dday['2018소요시간'])
data_after1['DAY'] = ['AFTER1'] * len(data_after1['2018소요시간'])
data_after2['DAY'] = ['AFTER2'] * len(data_after2['2018소요시간'])
if UpDown == 1:
before2_1_Dday = pd.concat([data_before2, data_before1, data_Dday])
new_index = []
for i in range(len(before2_1_Dday)):
new_index.append(i)
before2_1_Dday.index = new_index
time_list = list(before2_1_Dday['2018소요시간'])
min_time = min(time_list)
max_time = max(time_list)
indexs = []
for i in range(len(before2_1_Dday['2018소요시간'])):
if before2_1_Dday['2018소요시간'].iloc[i] == min_time:
indexs.append(i)
elif before2_1_Dday['2018소요시간'].iloc[i] == max_time:
indexs.append(i)
temp_df = before2_1_Dday.loc[indexs]
elif UpDown == 0:
Dday_after1_2 = pd.concat([data_Dday, data_after1, data_after2])
new_index = []
for i in range(len(Dday_after1_2)):
new_index.append(i)
Dday_after1_2.index = new_index
time_list = list(Dday_after1_2['2018소요시간'])
min_time = min(time_list)
max_time = max(time_list)
indexs = []
for i in range(len(Dday_after1_2['2018소요시간'])):
if Dday_after1_2['2018소요시간'].iloc[i] == min_time:
indexs.append(i)
elif Dday_after1_2['2018소요시간'].iloc[i] == max_time:
indexs.append(i)
temp_df = Dday_after1_2.loc[indexs]
return temp_df
앞으로 추가로 데이터를 수집하여 머신러닝/딥러닝을 활용하여 예측을 해보고자 합니다.
읽어주셔서 감사합니다~
'Programming > Python' 카테고리의 다른 글
[Python] 공공api를 활용하여 내 주변 공적 마스크 판매처와 마스크 재고를 지도에 시각화해보자! (7) | 2020.03.14 |
---|---|
[Python]역대 로또 당첨 번호 csv로 저장하고 분석해보기! (feat.나눔로또API) (12) | 2020.01.18 |
[Python]Mac에서 Python을 활용하여 wav파일을 mp3파일로 변환하기! (0) | 2019.11.19 |
[Python]인스타그램 크롤링을 통해 #흑당버블티 분석해보기! (43) | 2019.10.09 |
[Python] 인스타그램 태그를 가져와 워드클라우드 만들기! (4) | 2019.10.03 |