미국 교통부 교통 통계국에서 제공된 2011년 10월 한달 간의 비행기 출발/ 도착 정보를 이용하여 비행기 연착 추측 모델 구축하기
데이터 준비
기본적인 패키지 로딩
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
데이터 1 로딩
df_airport = pd.read_csv('./dataset/Airport Codes Dataset.csv')
print(df_airport.shape)
display(df_airport.head())
(365, 4)
데이터 2 로딩
df_flight = pd.read_csv('./dataset/Flight on-time performance.csv')
print(df_flight.shape)
display(df_flight.head())
(504397, 18)
정답값 확인
df_flight['ArrDel15'].value_counts() # 종속변수
ArrDel15
0.0 431461
1.0 68219
0: 비행기가 제시간에 도착함 / 1: 비행기가 15분정도 지연됨
결측치 확인
많은 개수의 결측치가 존재 하지만 갖고 있는 양에 비해서는 적은 양이기 때문에 결측치는 삭제한다.
또한 결측치가 범주형인 것도 있기 때문에 다른 값으로 채우는 것이 애매하다.
print(df_airport.isna().sum())
print()
print(df_flight.isna().sum())
DepDelay 3697
DepDel15 3697
CRSArrTime 0
ArrTimeBlk 0
ArrDelay 4717
ArrDel15 4717
Cancelled 0
데이터 전처리
공항정보 데이터를 출발 공항 정도로 수정. 출발지와 도착지를 구분하기 위함이다.
df_ori_airport = df_airport.rename(columns= {'city':'Ori-city', 'state': 'Ori-state','name':'Ori-airport'})
df_ori_airport.head()
비행 정보 데이터와 출발 공항 정보 데이터 병합
how = 왼쪽 데이터 사이즈에 맞춘다.
join_on 을 사용하였기 때문에 중복되는 컬럼값이 존재한다. 때문에, 중복되는 값을 지워준다.
merged_df1 = pd.merge(df_flight,df_ori_airport, left_on='OriginAirportID', right_on= 'airport_id', how = 'left') # 왼쪽데이터기준 공통된 것
print(merged_df1.shape)
display(merged_df1.head())
# 공항 ID중복 컬럼 삭제
merged_df1.drop('airport_id', axis = 1, inplace= True)
공항정보 데이터를 도착 공항 정도로 수정
df_dest_airport = df_airport.rename(columns= {'city':'Dest-city', 'state': 'Dest-state','name':'Dest-airport'})
df_dest_airport.head()
비행정보 데이터 + 도착 정보 데이터
처음 join했던 정보에 다시 join 하게 되며 출발지와 도착지를 구분 할 수 있게 되었다.
merged_df2 = pd.merge(merged_df1,df_dest_airport, left_on='OriginAirportID', right_on= 'airport_id', how = 'left') # 왼쪽데이터기준 공통된 것
print(merged_df2.shape)
display(merged_df2.head())
# 공항 ID중복 컬럼 삭제
merged_df2.drop('airport_id', axis = 1, inplace= True)
24개의 컬럼 중 학습에 사용할 14개 컬럼 선택
독립변수로 사용할 컬럼 14가지를 선택한다.
selected_col = ['DayOfWeek', 'Carrier', 'DepTimeBlk','DepDelay', 'DepDel15','ArrTimeBlk', 'ArrDelay',
'ArrDel15','Ori-city','Ori-state', 'Ori-airport', 'Dest-city', 'Dest-state', 'Dest-airport']
df_flight_info = merged_df2[selected_col]
df_flight_info.head()
결측치처리
df_flight_info = df_flight_info.dropna()
df_flight_info.isna().sum()
명목형 데이터의 유니크 값 개수 확인
dtype을 통해 만들어낸 df_flight_info() 함수의 컬럼별 타입이 'object' 인 것만을 구분한다.
obj_col = [col for col in df_flight_info.columns if df_flight_info[col].dtype == 'object']
# print(obj_col)
for col in obj_col:
print(f'컬럼명:{col:15s}, unique 개수: {df_flight_info[col].unique().size} ')
for col in [col for col in df_flight_info.columns if df_flight_info[col].dtype == 'object']:
print(f'컬럼명:{col:15s}, unique 개수: {df_flight_info[col].unique().size} ') 와 같은 의미 이다.
컬럼명:Carrier , unique 개수: 16
컬럼명:DepTimeBlk , unique 개수: 19
컬럼명:ArrTimeBlk , unique 개수: 19
컬럼명:Ori-city , unique 개수: 268
컬럼명:Ori-state , unique 개수: 53
컬럼명:Ori-airport , unique 개수: 279
컬럼명:Dest-city , unique 개수: 268
컬럼명:Dest-state , unique 개수: 53
컬럼명:Dest-airport , unique 개수: 279
라벨 인코딩
유니크 값이 많아 라벨 인코딩이 적합하다. 라벨 인코딩 학습과 적용을 바로 시킴
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
for col in [col for col in df_flight_info.columns if df_flight_info[col].dtype == 'object']:
df_flight_info[col] = encoder.fit_transform(df_flight_info[col])
<class 'pandas.core.frame.DataFrame'>
Index: 499680 entries, 0 to 504396
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 DayOfWeek 499680 non-null int64
1 Carrier 499680 non-null int32
2 DepTimeBlk 499680 non-null int32
3 DepDelay 499680 non-null float64
4 DepDel15 499680 non-null float64
5 ArrTimeBlk 499680 non-null int32
6 ArrDelay 499680 non-null float64
7 ArrDel15 499680 non-null float64
8 Ori-city 499680 non-null int32
9 Ori-state 499680 non-null int32
10 Ori-airport 499680 non-null int32
11 Dest-city 499680 non-null int32
12 Dest-state 499680 non-null int32
13 Dest-airport 499680 non-null int32
dtypes: float64(4), int32(9), int64(1)
memory usage: 40.0 MB
전부 명목형으로 변경된 것을 알 수 있다.
<문제를 풀때 데이터 전처리 오류 해결에서 가장 많이 걸리는 것을 알 수 있었다.. 앞에 배운 것들을 계속 기억해서 잘 꺼내 써야할텐데 기억이 잘 안나서 고민이다..>
데이터 분할 및 모델 생성
from sklearn.model_selection import train_test_split
x = df_flight_info.drop('ArrDel15',axis= 1)
y = df_flight_info['ArrDel15']
x_train,x_test,y_train,y_test = train_test_split(x,y, train_size= 0.8, stratify= y)
1. RandomForestClassifier(앙상블모형) 분류
model = RandomForestClassifier()
model.fit(x_train,y_train)
2. LogisticRegression(분류분석) 분류
model = LogisticRegression(solver='sag', max_iter= 600) # 확률적 경사 하강법
model.fit(x_train,y_train)
모델 평가
앙상블모형
from sklearn.metrics import accuracy_score, roc_auc_score
y_hat = model.predict(x_test)
print(f'Accuracy : {accuracy_score(y_test,y_hat):.3f}')
print(f'AUC :{roc_auc_score(y_test, model.predict_proba(x_test)[:,1]):.3f}')
Accuracy : 1.000
AUC :1.000
앙상블모형은 정확도와 auc 값이 매우 높은 값으로 도출 되었다.
분류 분석
# LogisticRegression
y_hat = model.predict(x_test)
print(f'Accuracy : {accuracy_score(y_test,y_hat):.3f}')
print(f'AUC :{roc_auc_score(y_test, model.predict_proba(x_test)[:,1]):.3f}')
Accuracy : 0.982
AUC :0.998
분류분석은 앙상블 모형에 비해 적은 값이지만, 그래도 높은 값을 도출한다.
Feature Importance # RandomForestClassifier()
Importance = { k:v for k,v in zip(x.columns, model.feature_importances_)}
df_importance = pd.DataFrame(pd.Series(importance),columns= ['Importance'])
df_importance.sort_values('Importance', ascending= False)
회귀계수(가중치) # LogisticRegression()
model.coef_를 통해 설명변수 X를 구성하는 각 특성별 가중치를 확인하기 앞서 차원을 1차원으로 줄여준다. # **
coef = model.coef_.squeeze(axis = 0)
odds_rate = np.exp(coef)
coef_df = pd.DataFrame({'가중치': coef, 'odd비': odds_rate}, index=x.columns)
coef_df.sort_values('가중치', ascending= False)
교차검증 # RandomForestClassifier()
from sklearn.model_selection import cross_validate
scores = cross_validate(model, x,y, cv = 5, scoring = ['accuracy', 'roc_auc_ovr'])
# 검증에 사용된 평가지표를 딕셔너리로
for k,v in scores.items():
print('Key',k)
print(f'mean value: {np.mean(v):.3f}')
print('='*30)
Key fit_time
mean value: 18.138
==============================
Key score_time
mean value: 1.317
==============================
Key test_accuracy
mean value: 1.000
==============================
Key test_roc_auc_ovr
mean value: 1.000
==============================
교차검증을 통해 과적합 발생도 일어나지 않았다는 것을 알 수 있다.
'국비 교육 > 머신러닝, 딥러닝' 카테고리의 다른 글
[머신러닝] 비지도 학습 알고리즘 - 군집분석 : K- 평균 군집 [실습] 온라인 판매 군집분석 (0) | 2023.11.25 |
---|---|
[머신러닝] 비지도 학습 알고리즘 - 군집분석 : K- 평균 군집 (0) | 2023.11.23 |
[머신러닝] 분류분석 : 앙상블 러닝 - Voting, Boosting 실습문제 (0) | 2023.11.23 |
[머신러닝] 분류분석 : 의사 결정 트리, 앙상블 러닝 - Bagging (0) | 2023.11.22 |