Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 사이킷런
- 파이썬
- 딕셔너리
- 제어문
- 머신러닝
- 데이터분석
- AIFFEL
- 아이펠
- 속성
- 카카오
- 제로베이스 데이터사이언스
- 후기
- 재귀함수
- 스크랩
- 기사
- NLP
- 함수
- TensorFlow
- AI
- 코딩도장
- 데이터사이언스 스쿨
- 추천시스템
- 파이썬코딩도장
- Set
- numpy
- Python
- 딥러닝
- 데이터사이언티스트
- 자연어처리
- 클래스
Archives
- Today
- Total
뮤트 개발일지
AIFFEL 아이펠 16일차 본문
나의 첫 번째 캐글 경진대회, 무작정 따라해보기
Baseline
# 필요할 라이브러리 임포트 하기
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import warnings
warnings.filterwarnings("ignore")
import os
from os.path import join
import pandas as pd
import numpy as np
import missingno as msno
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import KFold, cross_val_score
import xgboost as xgb
import lightgbm as lgb
import matplotlib.pyplot as plt
import seaborn as sns
# 경로 재설정
data_dir = os.getenv('HOME')+'/aiffel/kaggle_kakr_housing/data'
train_data_path = join(data_dir, 'train.csv')
sub_data_path = join(data_dir, 'test.csv') # 테스트, 즉 submission 시 사용할 데이터 경로
# 데이터 불러오기
data = pd.read_csv(train_data_path)
sub = pd.read_csv(sub_data_path)
print('train data dim : {}'.format(data.shape))
print('sub data dim : {}'.format(sub.shape))
>>> train data dim : (15035, 21)
>>> sub data dim : (6468, 20)
# 학습 데이터에서 라벨 제거하기
y = data['price']
del data['price']
# 데이터 전처리를 위해 학습데이터와 테스트 데이터 합치기
train_len = len(data)
data = pd.concat((data, sub), axis=0)
# 결측치 확인하기
msno.matrix(data)
# 1. id 컬럼이 결측치인지 확인합니다.
null_check = pd.isnull(data['id'])
print(null_check)
# 2. 결측치인 데이터만 뽑아냅니다.
null_data = data.loc[null_check, 'id']
null_data.head()
# 3. 결측치인 데이터의 개수를 셉니다.
print('{}: {}'.format('id', len(null_data.values)))
# 모든 컬럼에 적용하기
for c in data.columns:
print('{} : {}'.format(c, len(data.loc[pd.isnull(data[c]), c].values)))
# id, date 컬럼 처리하기
# id 컬럼 삭제
sub_id = data['id'][train_len:]
del data['id']
# date 컬럼 필요한 부분까지만 나타내기
data['date'] = data['date'].apply(lambda x : str(x[:6]))
# 각 변수들 분포 확인
fig, ax = plt.subplots(9, 2, figsize=(12, 50)) # 가로스크롤 때문에 그래프 확인이 불편하다면 figsize의 x값을 조절해 보세요.
# id 변수(count==0인 경우)는 제외하고 분포를 확인합니다.
count = 1
columns = data.columns
for row in range(9):
for col in range(2):
sns.kdeplot(data=data[columns[count]], ax=ax[row][col])
ax[row][col].set_title(columns[count], fontsize=15)
count += 1
if count == 19 :
break
# 치우친 칼럼들을 정규분포에 가깝게 만들기
skew_columns = ['bedrooms', 'sqft_living', 'sqft_lot', 'sqft_above', 'sqft_basement', 'sqft_lot15', 'sqft_living15']
for c in skew_columns:
data[c] = np.log1p(data[c].values)
# 다시 확인
fig, ax = plt.subplots(4, 2, figsize=(12, 24))
count = 0
for row in range(4):
for col in range(2):
if count == 7:
break
sns.kdeplot(data=data[skew_columns[count]], ax=ax[row][col])
ax[row][col].set_title(skew_columns[count], fontsize=15)
count += 1
# 다시 학습 데이터, 테스트 데이터로 나누기
sub = data.iloc[train_len:, :]
x = data.iloc[:train_len, :]
블랜딩Blending: 여러 가지 모델을 사용해서 결과를 섞는 기법
모델은 부스팅 계열인 gboost, xgboost, lightgbm 세 가지를 사용한다.
gboost = GradientBoostingRegressor(random_state=2019)
xgboost = xgb.XGBRegressor(random_state=2019)
lightgbm = lgb.LGBMRegressor(random_state=2019)
models = [{'model':gboost, 'name':'GradientBoosting'}, {'model':xgboost, 'name':'XGBoost'},
{'model':lightgbm, 'name':'LightGBM'}]
교차 검증
def get_cv_score(models):
kfold = KFold(n_splits=5).get_n_splits(x.values)
for m in models:
CV_score = np.mean(cross_val_score(m['model'], X=x.values, y=y, cv=kfold))
print(f"Model: {m['name']}, CV score:{CV_score:.4f}")
get_cv_score(models)
>>> Model: GradientBoosting, CV score:0.8598
>>> Model: XGBoost, CV score:0.8860
>>> Model: LightGBM, CV score:0.8819
def AveragingBlending(models, x, y, sub_x):
for m in models :
m['model'].fit(x.values, y)
predictions = np.column_stack([
m['model'].predict(sub_x.values) for m in models
])
return np.mean(predictions, axis=1)
y_pred = AveragingBlending(models, x, y, sub)
print(len(y_pred))
y_pred
* 여러 모델을 입력하면 각 모델에 대한 예측 결과를 평균 내어준다. models 딕셔너리 안에 있는 모델을 모두 x와 y로 학습시킨 뒤 predictions에 그 예측 결과값을 모아서 평균한 값을 반환한다.
# submission 파일 구성에 따라 id, price 컬럼 만들기
result = pd.DataFrame({
'id' : sub_id,
'price' : y_pred
})
# submission 파일 저장
my_submission_path = join(data_dir, 'submission.csv')
result.to_csv(my_submission_path, index=False)
점수 향상을 위해 여러가지 모델 사용하기
: XGBRegressor, LGBMRegressor, GradientBoostingRegressor, RandomForestRegressor
random_state=2020
gboost = GradientBoostingRegressor(random_state=random_state)
xgboost = XGBRegressor(random_state=random_state)
lightgbm = LGBMRegressor(random_state=random_state)
rdforest = RandomForestRegressor(random_state=random_state)
models = [gboost, xgboost, lightgbm, rdforest]
def get_scores(models, train, y):
df = {}
for model in models:
model_name = model.__class__.__name__
X_train, X_test, y_train, y_test = train_test_split(train, y, random_state=random_state, test_size=0.2)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
df[model_name] = rmse(y_test, y_pred)
score_df = pd.DataFrame(df, index=['RMSE']).T.sort_values('RMSE', ascending=False)
return score_df
하이퍼파라미터 설정하기
- 그리드 탐색 사용
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100],
'max_depth': [1, 10],
}
model = LGBMRegressor(random_state=random_state)
grid_model = GridSearchCV(model, param_grid=param_grid, \
scoring='neg_mean_squared_error', \
cv=5, verbose=1, n_jobs=5)
grid_model.fit(train, y)
# 모델 결과 저장
grid_model.cv_results_
# 정보 확인
params = grid_model.cv_results_['params']
params
score = grid_model.cv_results_['mean_test_score']
score
# 음수였던 점수 바꾸기
results['RMSE'] = np.sqrt(-1 * results['score'])
results
# 이름 바꾸기 (우리가 구한 RMSE는 사실 RMSLE 였다)
results = results.rename(columns={'RMSE': 'RMSLE'})
results
# RMSLE가 낮은 순서대로 정렬
results = results.sort_values('RMSLE')
results
위의 코드를 함수로 표현
# 코드 입력
def my_GridSearch(model, train, y, param_grid, verbose=2, n_jobs=5):
# GridSearchCV 모델로 초기화
grid_model = GridSearchCV(model, param_grid=param_grid, scoring='neg_mean_squared_error', \
cv=5, verbose=verbose, n_jobs=n_jobs)
# 모델 fitting
grid_model.fit(train, y)
# 결과값 저장
params = grid_model.cv_results_['params']
score = grid_model.cv_results_['mean_test_score']
# 데이터 프레임 생성
results = pd.DataFrame(params)
results['score'] = score
# RMSLE 값 계산 후 정렬
results['RMSLE'] = np.sqrt(-1 * results['score'])
results = results.sort_values('RMSLE')
return results
제출을 위한 함수 만들기
def save_submission(model, train, y, test, model_name, rmsle=None):
# 모델학습
model.fit(train, y)
# 모델 예측
prediction = model.predict(test)
# 모델 스케일 되돌리기
prediction = np.expm1(prediction)
# 파일 가져오기
data_dir = os.getenv('HOME')+'/aiffel/kaggle_kakr_housing/data'
submission_path = join(data_dir, 'sample_submission.csv')
submission = pd.read_csv(submission_path)
# 내가 만든 값 덮어씌우기
submission['price'] = prediction
# csv 파일로 저장하기
submission_csv_path = '{}/submission_{}_RMSLE_{}.csv'.format(data_dir, model_name, rmsle)
submission.to_csv(submission_csv_path, index=False)
https://github.com/pjk7565/AIFFEL/blob/main/Exploration5/kaggle.ipynb
'AIFFEL' 카테고리의 다른 글
AIFFEL 아이펠 18일차 (0) | 2022.01.25 |
---|---|
AIFFEL 아이펠 17일차 (0) | 2022.01.25 |
AIFFEL 아이펠 15일차 (0) | 2022.01.24 |
AIFFEL 아이펠 14일차 (0) | 2022.01.17 |
AIFFEL 아이펠 13일차 (0) | 2022.01.13 |