[멋사][AI] TIL - RMSLE, emp

티나(Tina)·2022년 11월 9일

멋사AI

목록 보기
21/41

221108

601 실습

인코딩하는 방법

  • one-hot-encoding => pd.get_dummies()
  • ordinal-encoding => category 데이터타입으로 변경하면 ordinal encoding 을 할 수 있다.

year-month-code 피처 추가

  • 점수(rmsle)가 43 -> 47로 높아짐. 성능이 안좋아졌다.
  • 도움이 안되는 피처..ㅜ 상관관계가 0.31 정도로 높았지만 이 피쳐를 추가하면 점수가 안좋아진다.
  • 신호와 소음을 구분해서 어떤 피처가 도움이 될지를 찾아내는데, EDA, 도메인지식을 활용하여 자전거 대여수에 영향을 줄만한 피처를 찾아야 한다.

Q. year-month-code를 넣으니 피처 중요도는 높다고 나오는데 성능 자체가 떨어졌으면 쓸만한 피처가 아니라는 건가요

A. 해당 모델이 학습을 할 때 중요한 역할을 했다고 알려주지만 피처 중요도가 모델의 성능을 설명하지는 않습니다. 모델의 성능은 모의고사를 보는 과정과 유사한 cross validation 점수가 올라갔는지 내려갔는지를 확인해 봅니다. (스코어 측정 방법에 따라 점수가 올라가야지 좋은 성능을 낸다고 판다하는 측정지표도 있고 내려가야 좋은 측정지표도 있으니 구분해서 보세요.)

  • 점수가 높아야 좋은 지표 : Accuracy, r2 score

  • 점수가 낮아야 좋은 지표 : MAE, MSE, RMSE, RMSLE

602

상대경로, 절대경로

  • 상대경로는 현재 경로를 기준으로 하는 경로 예) ./ 현재경로를 의미합니다. ../ 상위 경로를 의미합니다.
  • 절대경로는 전체 경로를 다 지정하는 경로 예) 윈도우 C: 부터 시작하는 경로입니다.
  • 현재 경로에서 ./ 쓰는 것과 아무것도 안 쓰는것과 같은 위치를 나타냅니다.
    절대경로를 사용하면 다른 사람의 컴퓨터에서 동작하지 않기 때문에 되도록이면 상대경로를 사용하는 것을 권장합니다.

RMSLE

  • log 를 count 값에 적용하게 되면 한쪽에 너무 뾰족하게 있던 분포가 좀 더 완만한 분포가 된다.
  • 데이터에 따라 치우치고(skewed) 뾰족한 분포가 정규분포에 가까워지기도 한다. (치우친건 왼쪽 오른쪽 상관없다.)
  • log를 취한 값을 사용하게 되면 이상치에도 덜 민감하게 된다.
  • np.log1p : log(1 + x) 1을 더해준 로그
  • np.log1p(train["count"]) = np.log(train["count"] + 1)

Q. 왜 정규분포가 되면 머신러닝이나 딥러닝에서 좋은 성능을 낼까요?
A. 값을 볼 때 한쪽에 너무 치우쳐져 있고 뾰족하다면 특성을 제대로 학습하기가 어렵기 때문에 정규분포로 되어 있다면 특성을 고르게 학습할 수 있다.

emp

np.log(y) : log_e y = x
np.exp(x) : e^x = y

  • np.exp 는 지수함수 이다.
  • np.log로 로그를 취했던 값을 다시 원래의 값으로 복원할 수 있다.
  • log를 취할 때는 1을 더하고 로그를 취했는데 지수함수를 적용할 때는 반대의 순서대로 복원해야순서가 맞다.
  • count == np.expm1(np.log1p()) 같은 값입니다.
# 로그 취한것
train["count_log1p"] = np.log(train["count"] + 1)

# 지수함수로 로그 해제
np.exp(train["count_log1p"]) - 1

# 둘이 값이 같다!!
train["count"] == np.exp(train["count_log1p"]) - 1
  • -1을 해줘야 하는 이유
# 이를 x 라하자 
x = `log_e ('count' + 1)` == np.log(train["count"] + 1)

exp(x) = e^x = 'count' + 1

'count' = exp(x) - 1 = np.exp(train["count_log1p"]) - 1
  • neg_root_mean_squared_error(RMSE) : rmse 와 동일하지만 y_train의 count에 미리 log를 취해 주었기 때문에 RMSLE 로 계산하는 것과 같다.
from sklearn.model_selection import RandomizedSearchCV

param_distributions = {"max_depth": np.random.randint(3, 10, 10), 
                       "max_features": np.random.uniform(0, 1, 10)}

reg = RandomizedSearchCV(model, 
                         param_distributions=param_distributions, 
                         scoring="neg_root_mean_squared_error",
                         n_iter=10, cv=5, n_jobs=-1,
                         verbose=2, random_state=42)
reg.fit(X_train, y_train)

reg.best_estimator_

# neg_root_mean_squared_error 로 되어 있어서 스코어가 음수로 나온다.
rmsle = abs(reg.best_score_)
rmsle
  • 큰 값이 좋은 지표도 있고, 작은 값이 좋은 지표도 있는데 rmsle 은 작은 값이 좋은지표이다.
  • rmsle 값을 음수로 만들면 정렬할 때 절대값이 작은 값부터 (더 좋은 지표) 나오기 때문에 sklearn 에서 음수값으로 scoring 을 제공 하는 것 같다.

위에서 구한 reg.bestestimator 로 cross_val_predict 를 해야 점수를 직접 구해볼 수 있다.
위에서 이미 RMSLE 점수를 구해봤기 때문에 굳이 점수를 따로 구해보지 않아도 되지만,
만약, 사이킷런에서 제공하고 있지 않은 측정 지표로 측정을 해야 한다면 직접 cross_val_predict 값을 구해서 측정해 볼 수도 있다.

701

  • 결측치 탐색
train_null =  train.isnull().sum()
train_null_sum = train_null[train_null != 0].sort_values(ascending=False)
train_null_mean = train.isnull().mean()

pd.concat([train_null,train_null_mean], axis=1).loc[train_null_sum.index]
  • sactter plot 에 선 그리기
_ = sns.scatterplot(data=train, x=train.index, y="SalePrice")
plt.axhline(500000, c="k", ls=":")
- color or c: color
- linestyle or ls: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}

이상치

train 의 이상치는 제거하면 되는데, test의 이상치는 제거 할 수 없다.
그럴때 어떻게 예측을 하는게 좋을까??

-> 분할해서 예측한다. 스케일링을 해준다.

희소값

  • 희소값이 많으면 해석이 어렵도 머신러닝 성능을 낮출 수 있다.
# 범주형데이터에서, unique 종류가 많은 상위 10개 추출해보기
train.select_dtypes(include="object").nunique().nlargest(10)
  • 희소한 값에 대해서 one-hit-encoding을 하게 되면 오버피팅이 일어 날 수 있다.
  • 너무 희소한 행렬이 생성되기 때문에 계산에 많은 자원이 필요하다.
  • 희소한 값을 처리하고자 한다면, 1) 아예 희소값을 결측치 처리하거나
  • 2) 희소한 값을 "기타" 등으로 묶어줄 수도 있다.
profile
열심히 사는 중

0개의 댓글