빅분기 2유형

SeongGyun Hong·2024년 11월 24일

빅데이터 분석기사

목록 보기
14/16

1. 참고 영상 및 사이트

역시나 이번에도 감사합니다 민 기술사님...
감사합니다 감사합니다... 균짱짱님의 이모저모 티스토리

2. 풀이 및 순서

2.1 데이터 확인

데이터 타입
결측치
고유값
행, 열 갯수
등을 확인하는 과정이다.

  • 시험장에서는 csv 파일이 아예 들어가 있기도 해서 직접 데이터를 볼수도 있으니 굳이 df.head() 해서 확인하지 않아도 된다.

  • shape()를 잘 활용하면 굳이 매번 print로 끝까지 다 볼 필요 없다. 형태만 볼거라면
    shape() 애용하도록 하자.

  • 데이터 타입을 확인하고 df.info(), 비어 있는 값 또한 확인해서 df.isnull().sum() 적당히 비어있다면 평균 등의 값으로 채워주는 것이 좋다.

    • 다만, 이때 결측치가 특정 열에 많다면 해당 칼럼은 날리는 것도 고려한다.
      특히 범주형 변수인데 unique 많으면 해당 칼럼 날려도 좋다.
    • 그런데 이 시험이;; 때로 그냥 아무것도 안 한게 예측치가 더 좋을 때가 있어서 문제다 ;;

2.2 전처리

  • 결측치가 있는 경우 대개 처리해주느 것이 좋다.
  • 방법은 여러가지인데,
    • float 변수인 경우에 0 으로 채우거나
    • 결측치 이전의 값으로 fillna(method = 'ffill') 을 하거나
    • 평균값 또는 중앙값으로 채울 수도 있다.
    • 심지어 특정 칼럼에 결측치 걍 폭탄이다? 그러면 그냥 .dropna(axis =1)로 칼럼 단위로 날려버릴 수도 있다.
    • 환불금액 같은 류의 칼럼은 NaN이 곧 0을 뜻하므로 이런 거는 NaN을 0으로 채우는게 좋을 듯

수치형 변수의 스케일링 (선택)

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

# 수치형 변수 가려내기
num_columns = x_train.select_dtypes(exclude = 'object').columns

# 표준화 진행
x_train[num_columns] = scaler.fit_transform(x_train[num_columns])

# train에서 평균과 표준편차로 fit 해놨으면 이제 아래처럼...적용해라.. fit_transform 하지말고 ;;
# x_test에 대해서 또 fit 해버리면 안 되잖아!
x_test[num_columns] = scaler.transform(x_test[num_columns])

2.3 인코딩

대개 이번 시험에서는
범주형 데이터를 원-핫 인코딩하는 것을 말한다.
주로
pd.get_dummies() 방식과
from sklearn.preprocessing imoprt OneHotEncoder 방식이 있다.


다만, 이때 주의할 것이 있는데
train에서 피자, 치킨, 콜라, 사이다와 같은 것들이 나오다가
test에서 피자, 치킨, 콜라, 사이다,맥주
이렇게 나와버리면 ;;
에러가 떠버린다.
그래서 사전에 미리 범주형 변수들의 value들을 확인하는 것이 좋은데 아래와 같은 방식으로 가능하다

target = set(x_test['주구매상품']) - set(x_train['주구매상품'])
print(target)

pd.get_dummies()

  • 작동 방식:
    입력된 데이터프레임이나 시리즈에서 고유한 값들을 기준으로 즉시 원-핫 인코딩을 수행한다.
    결과는 DataFrame 형태로 반환되며, 각 고유 값이 열(column)로 변환되고 값은 0 또는 1로 표시된다.
  • drop_First = True 옵션을 사용하면 첫 번째 열을 제거하여 다중공선성(multicollinearity)를 줄일 수 있다.
  • 결측값(NaN) 처리 옵션인 dummy_na = True도 제공한다.
  • 빠르고 간단하며 별도의 fit 과정이 필요 없다. 또한 return 되는 값이 DataFrame 형식이기에 기존 데이터와 쉽게 병합이 가능하다.
    • 다만, 희소 행렬을 지원하지 않기에 메모리 낭비가 발생한다.

OneHotEncoder

  • from sklearn.preprocessing import OneHotEncoder 로 접근한다.
  • fit() 메서드로 학습 데이터의 고유 값을 학습한 뒤에, transform()으로 데이터를 반환한다.
  • 결과는 기본적으로 희소 행렬(Sparse Matrix) 형태로 반환되며, 메모리 효율적이다
    • 참고로 우리 시험은 1분이상 못돌림 ㅋㅋㅋ
  • handle_unknown = 'ignore' 옵션을 통하여 학습되지 않은 새로운 범주는 무시하거나 에러를 방지할 수 있다.
  • drop 파라미터로 특정 열을 제거할 수 있다.
  • 결과를 DataFrame으로 변환하려면 추가적인 코드가 필요하다.

LabelEncoder

  • 라벨 인코더는 범주형 데이터를 숫자형 데이터로 변환하는 전처리 기법이다.
  • 이진분류 말고 다중분류에서 적용하면 좋다.
  • 트리기반 모델에서는 숫자의 크기 차이가 모델 성능에 영향을 주지 않기에 적합하다.
    • 반대로 숫자 간의 대소관계가 없는 범주형 데이터에 관해서 숫자간 차이를 암묵적으로 생성하기에, 로지스틱 회귀, SVM과 같은 선형 모델에서는 성능 저하를 초래할 수 있다.
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
X_train['주구매상품'] = encoder.fit_transform(X_train['주구매상품'])
X_test['주구매상품'] = encoder.transform(X_test['주구매상품'])

아래는 onehotencoding 방법중 pd.get_dummies()에 관한 방법

x_train_dum = pd.get_dummies(x_train)

# x_train_dum의 열과 동일하게 x_test_dum의 열을 정렬한 후, 누락된 열은 0으로 채운다 (fill_value =0) 
x_test_dum = pd.get_dummies(x_test).reindex(columns = x_train_dum.columns, fill_Value = 0)
  • fill_value와 reindex를 잘 활용하여 x_train_dum과 x_test_dum의 열을 잘 맞춰줄 것

2.4 train, test 데이터 구분

  • 고유값, 예컨데 ID 칼럼의 경우에는 대개 없어도 된다.
x_train = train.drop(columns = ['ID', 'price'])
y_train = train['price']

# 이떄 자꾸 빼먹는데, train 수정할 때 test도 같이 수정해라
x_test = test.drop(columns = ['ID'])

cust_id = test.ID

# 그리고 이렇게 나누고 나면 항상 잘 나눴는지 shape으로 확인하자
# 칼럼도 잘 나눴는지 체크!
print(x_train.shape, y_train.shape, x_test.shape)
  • 원한다면, 특정 칼럼을 넣고 빼면서 train_dataset 별로 결과 차이를 봐도 된다.

stratify옵션
층간 추출로 라벨 비율 유지하면서 학습시킬 수도 있다. (분류에서 적용해볼 법함. 회귀는 층간이 안되니까 애초에 적용 X)

X_train, X_val, y_train, y_val = train_test_split(X_train, y, test_size = 0.2, stratify = y)

2.5 알고리즘 선택: 랜덤 포레스트

본 예제에서는 랜덤포레스트로 설명한다.

우선 아래와 같이 import 해준다.
회귀문제의 경우에는 아래와 같이
from sklearn.ensemble import RandomForestRegressor
분류문제 에서는 아래와 같이 한다.
from sklearn.ensemble import RandomForestClassifier

그리고 하나 더 추가할 것이 있는데, 바로 검증 모델이다.

f1_score, accuracy_Score, recall_score, roc_auc_score, precision_score 등을 불러오기 위해서는 아래와 같은 모듈이 필요하다.
문제에서 평가지표를 알려주는데 거기에 알맞게 써먹자.

from sklearn.metrics import mean_squared_error

그리고 root 해주기 위하여 아래도 넣어주자
import numpy as np


2.6 train_test_split

단순 학습 외에도 검증할 데이터가 필요하므로
학습데이터를 구분하여 나눠 검증데이터로 만들어 준다.

from sklearn.model_selection import train_test_split

X_train, X_validation, Y_train, Y_validation = train_test_split(x_train_dum, y_train, test_size = 0.2, random_state = 42)

2.7 모델 불러오기, 학습, 예측

model = RandomForestRegressor()
model.fit(X_train, Y_train)

pred_validation = model.predict(X_validation)
print('rmse:', np.sqrt(mean_squared_error(Y_validation, pred_validation))

학습도 검증도 잘 마쳤다면 이제 진짜 예측 진행해서 실제 제출까지 해보자.

prediction = model.predict(X_test_dum)

# 답안 제출
pd.DataFrame({'ID': cust_id, 'pred': prediction}).to_csv('result.csv', index = False)

만약 평가지표가 roc_auc_score 또는 확률이라면, 결과 예측에서 model.predict_proba(x_test_dum)[:1]을 사용해야 한다.

3. 빠른 풀이

# 1. train / test 통합
# 2. 결측치 처리
# 3. 수치형 변수 스케일링 (skip해도 된다.)
# 4. 범주형 변수 pd.get_dummies 이용하여 원핫인코딩
# 5. 데이터 분리: train / test 분리
# 6. train dataset으로 train / valid 나눠주기
# 7. 모델 학습 및 평가(검증데이터, 검증메트릭)
# 8. 실제 예측
# 9. 양식 맞춰 제출
profile
헤매는 만큼 자기 땅이다.

0개의 댓글