TIL/머신러닝

11.15 머신러닝 주택가격, 벤츠

monawa 2022. 11. 16.
728x90

append

< 0702-house-feature_engineering-predict >

복습 내용 

 

skew

 

왜도 첨도

Skewness (왜도)

왜곡 정도를 말한다. 데이터 분포의 대칭성이 얼마나 결핍되었는지를 측정한다. 완전히 대칭인 분포는 skewness가 0이다.

 

Positive Skewness는 오른쪽 꼬리가 왼쪽보다 더 길 때를 의미하고 평균(Mean)과 중위수(Median)가 최빈값(Mode)보다 크는 것을 의미합니다.

  • Positive Skew : Mode – Median – Mean 순으로 존재 / 긴꼬리가 오른쪽

Negative Skewness 왼쪽 꼬리가 오른쪽보다 더 길 때를 의미하고 평균(Mean)과 중위수(Median)가 최빈값(Mode)보다 작는 것을 의미하게 됩니다

  • Negative Skew : Mean - Median – Mode 순으로 존재 / 긴꼬리가 왼쪽

 

Kurtosis / 첨도

분포에 존재하는 특이치(outlier)의 척도다.

Mesokurtic : 이 분포는 정규 분포와 유사한 첨도 통계량을 가지고 있다. 분포의 극단값이 정규 분포 특성과 유사하다는 뜻이다.

Leptokurtic (Kurtosis > 3) : 분포가 길고, 꼬리가 더 뚱뚱하다. 피크는 Mesokurtic보다 높고 날카롭기 때문에 데이터는 꼬리가 무겁거나 특이치(outlier)가 많다는 것을 의미한다.

Platykurtic (Kurtosis < 3) : 분포는 짧고 꼬리는 정규 분포보다 얇다. 피크는 Mesokurtic보다 낮고 넓으며, 이는 데이터가 가벼운 편이나 특이치(outlier)가 부족하다는 것을 의미한다.
이유는 극단값(extream value)이 정규 분포의 극단값보다 작기 때문이다.

 


log transform

왜도로 로그 변환 필요 여부 확인

왜도가 특정 이상인 값 == 분포가 치우쳐짐

=> 로그 변환을 해주자 

왜도가 큰 값(임의로 절대값이 2보다 큰) 중에 수치형/범주형 나누기

  • 왜도와 첨도를 줄여준다
  • 분포가 좀 더 정규분포에 가까워진다
  • skew() 확인
  • sort_values(ascending=False) 2보다 큰것
  • hist() 분포를 통해 수치형/범주형 확인

: 범주형태의 데이터를 제외하고 로그변환을 해주세요!

: 범주형태인지는 nunique() , select_dtypes() 등을 활용해 볼 수 있습니다.

: 같은 변수에 담아줄 때 로그 변환이 여러 번 되지 않도록 셀 실행을 여러 번 하지 않는 것에 유의합니다.

: 실수를 할 것 같으면 다른 변수에 담아주어도 됩니다.

 

bin이 따로따로 떨어져 있는 수치형 변수들 제거

  1. log features에서 nunique 값이 20(임의로 정함)보다 작은 피쳐들(== bin의 개수가 적다)을 빼서, 범주형이 아닌 정말 수치형 변수인 것들만 남김
  2. 그 후에 최종적으로, log1p 취하기

결측치

  • 결측치 많을 때, 삭제하는 방법도 있지만 이것이  무조건 나은 방법은 아닐수있다 
  • => 이상치, 특이값을 찾는다면 오히려 특정 값이 신호가 될 수 있음
  • 범주형 데이터 : 결측치가 많더라도 채우지 않고 인코딩해주면 나중에 없는 값은 0으로 채워지게 된다.
    =>
    그대신 희소한 행렬이 생성된다.
  • 수치 데이터 : 잘못 채웠을 때 오해할 수 있음 -> 주의 필요

수치형 변수 대체할 때 주의점

  • 수치형 변수를 대체할 때는 원래의 값이 너무 왜곡되지 않는지도 주의가 필요하다.
  • 중앙값(중간값), 평균값 등의 대표값으로 대체할 수도 있지만, 회귀로 예측해서 채우는 방법도 있다.
  • 당뇨병 실습에서 했던 인슐린을 채울 때 당뇨병 여부에 따라 대표값을 구한 것처럼 여기서도 다른 변수를 참고해서 채워볼 수 있다.

0702 실습 지금까지의 진행 흐름
1. 다양한 변수의 타입을 확인해보고 hist를 활용해 카테고리형 변수와 연속형 변수를 구분해줍니다.
2. 분류해준 연속형 변수를 hist를 통해서 분포를 확인해봅니다.
3. 왜도와 첨도를 확인하여 분포가 치우쳐진 연속형 변수를 확인합니다.
(모델 학습 결과를 더 끌어올리기 위해서 입니다.)
4. 분포가 치우쳐진 변수를 확인 후 추출하여 로그 변환을 진행해줍니


모델에 사용할 범주형 변수 선택

  • 범주형 변수 중에 결측치가 있는지 확인 해보고 어떤 범주형 변수를 선택해서 모델에 사용할지 의사결정을 하게된다.
  • 정렬하고 결측치가 있는 데이터를 제거하기 위해 슬라이싱을 사용한다.
    💡 범주형 데이터는 원핫인코딩 작업을 하기 때문에 결측치를 남겨두어도 상관없다.
    왜? 없는 값은 변수로 생성하지 않기 때문

log를 취한 값을 정답값으로 지정한 이유?

집값의 높고 낮음에 상관없이 예측에 모두 영향을 받게 하기 위해 log를 취한다.
원래 예측값은 RMSLE 인데 로그를 이미 적용해 주어서 RMSE로 계산한다.

1) 2억 => 4억으로 예측
2) 100억 => 110억으로 예측

MAE : 1) 2억차이, 2)10억, 오차의 절대값
MSE : 1) 4억차이, 2)100억차이, 오차가 크면 클수록 값은 더 벌어집니다.
RMSLE : 1) np.log(2) => 0.69, 2) np.log(10) => 2.30
로그값은 작은 값에서 더 패널티를 주고 값이 커짐에 따라 완만하게 증가합니다.

append()와 extend()의 차이점

과자를 봉지쨰 넣을꺼냐 뜯어서 넣을거냐의 차이

append() extend()
봉지과자를 통쨰로 넣음 봉지과자를 뜯어서 낱개로 넣음
in
a =[]
a.append ([1,2,3])
a

out
 [ [ 1,2,3]]
in
a = []
a.extedn ([1,2,3])
a

out
[1,2,3]

여기서 말하는 과자의 봉지는 iterable 혹은 컨테이너라고 부릅니다.

list.append(x)는 리스트에 전달받은 요소(x)를 추가하는 메서드이며,

list.extend(iterable)은 순환 가능한 요소(iterable)를 인자로 받으며, 해당 컨테이너 안에 있는 모든 요소들을 리스트에 추가합니다

 

단 log를 적용한 값 제출 시 주의할 점

리더보드에 있는 점수와 동일한 스케일 점수를 미리 계산해 보기 위해서는 로그 적용한 값으로계산해 주지만 제출할 때는 지수함수를 적용해서 원래 스케일로 복원하여 제출합니다.
주의! 

내부에서 평가할 때는 제출받은 값에 로그를 취해서 점수를 평가하는데 제출할 때는 지수함수를 적용해서 제출해야 한다.

submit["SalePrice"] = np.expm1(y_predict)

 


수치형과 범주형 데이터에 할수있는 전처리 방법 

수치형

  • 결측치 대체(Imputation)
    • 수치형 변수를 대체할 때는 원래의 값이 너무 왜곡되지 않는지도 주의가 필요합니다.
    • 중앙값(중간값), 평균값 등의 대표값으로 대체할 수도 있지만,
    • 당뇨병 실습에서 했던 회귀로 예측해서 채우는 방법도 있습니다.
    • 당뇨병 실습에서 했던 인슐린을 채울 때 당뇨병 여부에 따라 대표값을 구한 것 처럼
    • 여기에서도 다른 변수를 참고해서 채워볼 수도 있습니다.
  • 스케일링 - Standard, Min-Max, Robust
  • 변환 - log
  • 이상치(너무 크거나 작은 범위를 벗어나는 값) 제거 혹은 대체
  • 오류값(잘못된 값) 제거 혹은 대체
  • 이산화 - cut, qcut

범주형

  • 결측치 대체(Imputation)
  • 인코딩 - label, ordinal, one-hot-encoding
  • 범주 중에 빈도가 적은 값은 대체하기

 

수치형과 범주형 데이터에서 전처리할 수 있는 방법이 다르기 때문에 EDA 과정에서 데이터를 꼼꼼히 탐색하는 것이 중요!


선형회귀 (Linear Regression)

: 종속 변수 y와 한 개 이상의 독립 변수 X와의 선형 상관 관꼐를 모델링하는 회귀분석 기법

 

선형회귀 특징
1) 다른 모델들에 비해 간단한 작동 원리를 가지고 있다.
2) 학습 속도가 매우 빠르다.
3) 조정해줄 파라미터가 적다.
4) 이상치에 민감하다.
5) 데이터가 수치형 변수로만 이루어져 있을 경우, 데이터의 경향성이 뚜렷할 경우 사용하기 좋다.

 

데이터 타입 바꾸기 (ordinal encoding => one-hot-encoding 실습 목적)

수치 데이터의 nunique 구해서 어떤 값을 one-hot-encoding 하면 좋을지 찾아봅니다. : 수치 데이터를 그대로 ordinal encoding 된 값을 그대로 사용해도 되지만 범주 값으로 구분하고자 하면, category 나 object 타입으로 변환하면 one-hot-encoding 할 수 있습니다.

 

나머지 수치형 변수 모두 중앙값으로 대체 :

수치형 변수를 대체할 때는 원래의 값이 너무 왜곡되지 않는지도 주의가 필요합니다.

:중앙값(중간값), 평균값 등의 대표값으로 대체할 수도 있지만, 당뇨병 실습에서 했던 회귀로 예측해서 채우는 방법도 있습니다. 

당뇨병 실습에서 인슐린을 채울 때 당뇨병 여부에 따라 대표값을 구한 것처럼 여기에서도 다른 변수를 참고해서 채워볼 수도 있습니다.

 

 

squared features (Polynomials)

다항식 전개(Polynomial Expansion)에 기반한 파생변수 생성. 주어진 다항식의 차수 값에 기반하여 파생변수를 생성할 수 있습니다 

머신러닝 모델은 label에 대해서 설명력이 높은 한 두가지 Feature에 의지할 때보다 여러가지 Feature에 기반할 때 성능이 더 뛰어나기 때문에, 머신러닝 모델을 이용할 때 이 과정이 유용할 수 있습니다.

:소수의 Feature에 기반하게 되면 과대적합이 일어날 확률이 높아집니다. : 다항식 전개에 기반해서 파생변수를 만들게 되면 머신러닝 모델이 여러 Feature에 기반하게 되어 안정성이 높아집니다

 


 

기타 알게된거 

 

???plt.show()를 안쓰면... 그래프가 안뜨고 쓰면 가끔 그래프가 두개씩 나오는경우는 뭘까???

plt.show()는 그래프를 보여주는 역할을 합니다.

기존 주피터 에서는 그래프를 보여주는게 기본값이 아니였습니다 

그런데 마지막 줄에 그래프를 그리는 코드가 있다면 보여주는 것이 기본 값으로 변경이 되었습니다.

그래서 plt.show()를 했을 때 주피터 버전에 따라 중복 출력이 될 수도 있는데 이때는 plt.show()를 지워주시면 됩니다.

 


 

참고자료

 

https://dining-developer.tistory.com/17

 

728x90

댓글