화이트 모드로 보시길 권장합니다
이 글은 [kaggle Learn Courses] 시리즈로
kaggle에서 제공하는 Data Science가 되기 위한 기술을 배울 수 있는
" Learn Courses "에 대한 내용을 정리한 글이다.
사전준비
데이터셋 준비
kaggle에서 제공하는 'Melbourne Housing Snapshot'데이터셋을 사용한다.
아래 사이트에서 csv형태의 데이터셋을 다운로드할 수 있다.
https://www.kaggle.com/datasets/dansbecker/melbourne-housing-snapshot
Melbourne Housing Snapshot
Snapshot of Tony Pino's Melbourne Housing Dataset
www.kaggle.com
import pandas as pd # pandas library를 불러온 뒤 pd라는 이름으로 지정
melb_data = pd.read_csv('./melb_data.csv') # 데이터셋 불러옴
melb_data.columns # Melbourne Housing Snapshot columns 확인
위 코드를 통해 'Melbourne Housing Snapshot' 데이터셋을 melb_data 변수에 저장 후, 데이터셋의 컬럼을 확인할 수 있다.
Index(['Suburb', 'Address', 'Rooms', 'Type', 'Price', 'Method', 'SellerG',
'Date', 'Distance', 'Postcode', 'Bedroom2', 'Bathroom', 'Car',
'Landsize', 'BuildingArea', 'YearBuilt', 'CouncilArea', 'Lattitude',
'Longtitude', 'Regionname', 'Propertycount'],
dtype='object')
각 컬럼명에 대한 뜻은 아래 '더 보기'를 눌러 확인할 수 있다.
Suburb : 주택이 위치한 동
Address : 주택의 주소
Rooms : 주택에 있는 방의 개수
Type : 주택의 종류를 의미하며 실제 데이터 셋에는 h, u, t만 존재하기에 이 세 가지에 대해서만 정리하겠다.
h - 주택(house), 오두막집(cottage), 빌라(villa), 다가구주택(semi), 테라스(terrace)
u - 2~3층 다세대 아파트(unit), 듀플렉스하우스(duplex)
t - 연립주택(townhouse)
Price : 가격
Method : 주택의 부동산 상태를 의미한다.
S - 매각된 부동산 SP - 이전에 판매된 부동산; PI - 속성이 전달되었습니다. PN - 공개되지 않은 사전 판매; SN - 공개되지 않은 판매; NB - 입찰 없음; VB - 공급업체 입찰; W - 경매 전에 철회; SA - 경매 후 판매; SS - 경매 가격 미공개 후 판매. N/A - 가격 또는 최고 입찰가를 사용할 수 없습니다.
SellerG : 부동산 중개인
Date : 판매 날짜
Distance : C.B.D와의 거리
Postcode : 우편번호
Bedroom2 : 'Domain.com.au'이외의 사이트에서 가져온 방 정보
Bathroom : 화장실 개수
Car : 자동차 주차 공간의 수
Landsize : 토지 면적
BuildingArea : 건물 크기
YearBuilt : 건축 연도
CouncilArea : 지역 행정 구역
Lattitude : 위도
Longtitude : 경도
Regionname : 지역 이름
Propertycount : 재산수
--------------------
y = melb_data.Price # Price(가격)을 y로 지정
# train_datset으로 사용하기 위해 melb_data에서 Price열을 제거
melb_predictors = melb_data.drop(['Price'], axis=1)
#select_dtypes : datatype에 따른 열 선택 함수
# exclude 매개변수 : exclude에 넣은 값을 제외한 열 선택
x = melb_predictors.select_dtypes(exclude=['object']) # object(문자열) 형식을 제외한 열 선택하여 x로 지정
위 코드를 통해 모델을 학습시키기 위한 x, y데이터를 설정해 준다.
scikit learn에서 제공하는 ' train_test_split '인 데이터 분할 함수를 이용해 train, validation dataset으로 분할한다.
아래 코드는 x, y변수에 저장된 데이터셋을 train, validation으로 분할하는 코드이다.
# scikit learn에서 제공하는 데이터 분할 함수 train_test_split 함수를 불러온다
from sklearn.model_selection import train_test_split
# x, y데이터를 train, validation용으로 분할한다
# train dataset은 전체 80%, validation dataset은 전체 20%로 설정한다
X_train, X_valid, y_train, y_valid = train_test_split(x, y, train_size=0.8, test_size=0.2,random_state=0)
X_train의 구조와 X_valid의 구조는 아래와 같다.
X_train.shape, X_valid.shape
------< result >------
((10864, 12), (2716, 12))
결측치 제거 데이터셋으로 학습한 모델 평가
각각의 결측치 처리 방식으로 처리한 데이터셋으로 학습한 모델들을 평가해야 하기에 모델 평가를 위한 함수를 만든다.
데이터셋으로 모델을 학습시켜야 하기에 scikit learn에서 제공하는 RandomForestRegressor 모델을 사용한다.
RandomForestRegressor(랜덤포레스트)란 의사결정트리를 랜덤 하게 나온 것을 투표하여 결정하는 것이다.
랜덤포레스트에 대한 자세한 설명은 추후 ' AI Model ' 카테고리에 추가될 예정이다.
아래 코드를 통해 scikit learn에서 제공하는 ' RandomForestRegressor ' 모델을 불러온다.
from sklearn.ensemble import RandomForestRegressor
학습한 모델을 평가하기 위해 평균절대오차( MAE;Mean Absolute Error ) 방식을 사용한다.
( MAE에 대한 설명은 아래 글에서 확인할 수 있다. )
https://smcjungbumc.tistory.com/entry/AI-Friends-School-5차시-인공지능의-성능-평가-및-개선-방법
[AI Friends School 5차시] 인공지능의 성능 평가 및 개선 방법
화이트 모드로 보시길 권장합니다 [AI Friends School] 시리즈는 MicroShcool에서 진행하는 온라인 인공지능 학습 학교이다. AI Friends School 강의 내용을 말하기 전, AI Friends School에선 어떠한 것을 배우는
smcjungbumc.tistory.com
아래 코드를 통해 scikit learn에서 제공하는 MAE 계산 함수 ' mean_absolute_error '함수를 불러온다.
from sklearn.metrics import mean_absolute_error
train, validation dataset을 받아 랜덤포레스트 모델을 학습시키고, 학습된 모델을 MAE방식으로 평가하는 함수를 만든다.
# score_dataset 이라는 모델평가 함수를 만든다.
def score_dataset(X_train, X_valid, y_train, y_valid):
# n_estimators : 의사결정트리의 수를 설정한다.
model = RandomForestRegressor(n_estimators=10, random_state=0)
model.fit(X_train, y_train) # 모델을 train dataset으로 학습시킨다.
preds = model.predict(X_valid) # 모델의 예측값을 preds 변수에 저장한다.
return mean_absolute_error(y_valid, preds) # MAE값을 return 한다.
결측치 처리 방법
Approach 1
결측치 제거 방법
가장 간단한 방법이다.
결측치가 포함된 행 혹은 열을 제거하는 방법이다.
아래는 결측치가 포함된 열을 제거한 것이다.
위와 같이 결측치가 포함된 열 전체를 제거할 경우 이 데이터셋의 중요한 정보들이 함께 누락될 가능성이 있다.
아래는 결측치가 포함된 열을 ' cols_with_missing ' 변수에 List형태로 저장한다.
cols_with_missing = [col for col in X_train.columns if X_train[col].isnull().any()]
------< result >------
['Car', 'BuildingArea', 'YearBuilt']
위 코드에서 생성한 결측치가 포함된 열의 이름을 저장한 변수를 이용해 결측치가 포함된 열을 제거한다.
아래는 결측치가 포함된 열을 제거하는 코드이다.
# 결측치가 포함된 열 이름이 저장되어 있는 cols_with_missing을 이용해 결측치가 있는 열을 제거한다.
reduced_X_train = X_train.drop(cols_with_missing, axis=1)
reduced_X_valid = X_valid.drop(cols_with_missing, axis=1)
결측치 제거 방식으로 데이터를 전처리 한 후, 모델을 학습시켜 평가한다.
모델 학습, 평가는 '사전 준비'에서 만든 score_dataset 함수를 사용한다.
print(score_dataset(reduced_X_train, reduced_X_valid, y_train, y_valid))
------< result >------
183550.22137772635
결측치 제거 방식을 적용한 데이터셋으로 모델을 학습 후, MAE 방식으로 평가한 결과 값이 위와 같이 나왔다.
Approach 2
A Better Option: Imputation( 결측치 대체 방법 )
결측치를 다른 값으로 imputation대체하는 방법이다.
열에 따른 평균값 등으로 대체한다.
대부분의 대체값이 정확하진 않지만 결측치가 포함된 열 전체를 제거하는 것보단 정확한 모델을 만들 수 있다.
결측치를 평균값으로 대체하는 방법은 imputation(대체) 방법 중 가장 간단하며 효과적인 방법이다.
데이터셋에 따라 '회귀 imputation'과 같은 복잡한 imputation기술이 더 나은 결과를 제공할 수도 있다. 하지만 정교한 머신러닝 모델의 경우 평균값으로 대체하는 것보다 이점이 없다.
아래는 결측치를 평균 값으로 대체하기 위해 scikit learn에서 제공하는 'Simpleimputer' 함수를 사용한다.
from sklearn.impute import SimpleImputer
'Simpleimputer'는 결측치를 평균값으로 대체해 주는 함수이다.
아래 코드를 통해 Simpleimputer로 결측치를 평균값으로 대체해 준다.
# Imputation
my_imputer = SimpleImputer()
# dataset에 포함된 결측치를 평균값으로 대체한 뒤, imputed_X_train변수에 DataFrame형태로 저장한다.
imputed_X_train = pd.DataFrame(my_imputer.fit_transform(X_train))
imputed_X_valid = pd.DataFrame(my_imputer.transform(X_valid))
# imputed변수 컬럼이 번호로 되있이게 컬럼명을 다시 설정해준다.
imputed_X_train.columns = X_train.columns
imputed_X_valid.columns = X_valid.columns
위 코드에서 생성한 결측치가 컬럼별 평균값으로 대체된 변수들로 모델을 학습 후, MAE로 평가한다.
print(score_dataset(imputed_X_train, imputed_X_valid, y_train, y_valid))
------< result >------
178166.46269899711
Approach 3
An Extension To Imputation( 확장된 Imputation 방법 )
imputation 방법은 대체로 좋은 효과를 보인다. 하지만 대체된 값은 실제 값보다 높거나 낮으며 정확하지 않다.
결측치를 대체할 경우 해당 열의 특정 행 값을 바꿨다는 것을 표시하는 열을 추가하여 모델 학습에 사용한다.
이 방법은 경우에 따라 모델의 능력이 향상될 수 있지만, 전혀 도움이 되지 않는 경우도 있다.
# 원본 데이터에 영향이 가지 않도록 데이터셋 복사
X_train_plus = X_train.copy()
X_valid_plus = X_valid.copy()
# 결측치 여부를 새로운 컬럼을 생성하여 저장
# 결측치가 포함된 열의 각 행 결측치 포함 여부에 따라 true, false로 나타냄
for col in cols_with_missing:
X_train_plus[col + '_was_missing'] = X_train_plus[col].isnull()
X_valid_plus[col + '_was_missing'] = X_valid_plus[col].isnull()
위 코드를 통해 각 열의 특정 값이 결측치라는 것을 true, false로 나타내는 열을 추가.
my_imputer = SimpleImputer() # SimpleImputer() 함수를 변수 my_imputer에 저장
# 결측치를 평균값으로 대체
imputed_X_train_plus = pd.DataFrame(my_imputer.fit_transform(X_train_plus))
imputed_X_valid_plus = pd.DataFrame(my_imputer.transform(X_valid_plus))
위 코드를 통해 scikit learn에서 제공하는 SimpleImputer 함수로 데이터셋의 결측치를 평균값으로 대체한다.
아래 코드를 통해 번호로 바뀐 열의 이름을 다시 설정해 준다.
imputed_X_train_plus.columns = X_train_plus.columns
imputed_X_valid_plus.columns = X_valid_plus.columns
위 코드에서 생성한 각 컬럼의 특정 행에 원래는 결측치가 포함되어 있다는 것을 표시해 주도록 전처리한 후, 모델을 학습시켜 평가한다.
print(score_dataset(imputed_X_train_plus, imputed_X_valid_plus, y_train, y_valid))
------< result >------
178927.503183954
위 결과를 보면 Approach 3의 결과가 Approach 2보다 낮다는 것을 볼 수 있다.
# 데이터셋의 구조
print(X_train.shape)
# 결측치가 포함된 열의 결측치 개수 출력
missing_val_count_by_column = (X_train.isnull().sum())
print(missing_val_count_by_column[missing_val_count_by_column > 0])
------< result >------
(10864, 12)
Car 49
BuildingArea 5156
YearBuilt 4307
dtype: int64
위 코드의 결과를 보면 'Melbourne Housing Snapshot'데이터셋에는 총 10864개의 행이 있으며 'BuildingArea'혹은 'YearBuilt'의 경우 절반가량의 데이터가 결측치인 것을 알 수 있다. 결측치가 포함된 열 3개를 모두 제거하게 될 경우 해당 열의 모든 유용한 데이터가 날아갈 수 있다. 때문에 '결측치 제거' 방법보다 '결측치 대체'방법이 효과적이다.
'kaggle > Learn-Intermediate Machine Learning' 카테고리의 다른 글
[kaggle : Intermediate Machine Learning] 1. 소개 (0) | 2023.05.04 |
---|