자격증/빅데이터분석기사

[빅데이터분석기사] 작업 2유형 작성패턴 - 분류문제

Ddolgom 2022. 11. 21. 14:11
반응형

빅데이터 분석기사의 2유형은 전체 100점 배점중 40점을 차지하는 한 문제가 나온다.

필답형 문제 (30점)이나 1유형 (30점)을 만점을 받을 자신이 있으면 날려도 되지만, 

보통 그렇게 하기 힘든 부분이다.

그래서 꼭 부분점수라도 받아야 하는 파트이다.

 

머신러닝 모델링을 하여 결괏값을 내는 것 이외에도 마지막에 저장을 해서 제출하여야 한다.

(1유형은 print함수로 결과값만 스크린에 출력하면 된다.)

 

현재까지의 기출이나 교재를 봤을때의 정형화 시킨 공식은 다음과 같다.

사람마다 작성법이 달라지고 코딩 스타일이 다르므로 이 틀에서 살만 덧붙이면 될 것 같다.

 

정형화 공식 (4개파트로 나눌 수 있다.)

1. 데이터 가져오기

2. 결측치 확인 및 대체하기(제거하기)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

3. 라벨 인코딩 (범주형 -> 수치형)

4. 원핫 인코딩 (범주형 ->수치형) 

 *  3, 4 부분에서 수치형 -> 범주형 같은 경우에는 binning의 과정을 해야 된다. (회귀(예측) 문제일 경우)

5. 파생변수 생성

6. 스케일링 (1. StandardScaler 2. MinMaxScaler) 1은 범주형 데이터일 경우 2는 수치형일 경우 변환해준다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

7. 데이터 분리 (train_test_split)

8. 모형학습 (1. 일반 단일 모형 2. 앙상블(결합모형)) --> 문제에서 요구하는대로 취사선택한다. RandomForest 모델을 쓰면 2번 앙상블도 충족되므로 일반적으로 많이 사용한다.

9. 모형평가 (score내서 제대로 학습이 되었는지 확인하는 부분)

10. 하이퍼파라미터 튜닝 (아직까지 출제된적은 없으나, 출제범위이므로 가장 기본적인 GridSearchCV활용)

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

11. 예측값 저장 (index=False로 시험제출 폼에 맞추어서 내야 채점이 제대로 된다. )

12. read_csv로 저장된 데이터 폼 확인

 

분류문제 기준으로 작성한 공식이지만, 회귀는 인코딩 부분과 모형학습과 모형평가 지표가 달라지게 된다. 

내일 업데이트 할 예정이다.

 

여기서 진행되는 변수들은 임의로 작성한 부분이다. 

df -> dataframe, 그리고 가상의 데이터에서의 sex ,species같은 열들은 실제 시험에서 나온 데이터들로 가정을 하고

진행을 하는 것이고, 필요할때마다 바꾸면 된다.

 

 

1. 데이터 가져오기

가장 기본적인 일이다. 먼저 필요한 라이브러리를 불러 온다. (판다스, 넘파이)

시각화 파트는 공식적으로 없다. 그래서 seaborn 이나 matplotlib을 import 할일은 없다고 봐도 된다.

 

후반부에 진행되는 모델링에서 필요한 라이브러리는 그때 불러온다.

import pandas as pd
import numpy as np # 넘파이 같은 경우에는 수학함수를 쓰기 위해서 미리 불러오는 것이 좋다.
# 데이터 파일 읽어오기

# 1. train, test 데이터 분리가 되어 있지 않은 경우
df = pd.read_csv('/data/train.csv') # 판다스의 read_csv 기능을 쓴다. 괄호 안은 파일의 경로이다. 


# 2. train, test 데이터 분리가 되어 있는 경우
x_train = pd.read_csv('data/x_train.csv')
x_test = pd.read_csv('data/x_test.csv')
y_train = pd.read_csv('data/y_train.csv')

# 3. 만약 한글이 들어간 데이터라면
df = pd.read_csv('/data/train.csv', encoding = 'cp949') # encoing = 'cp949'를 넣어준다. (따옴표 주의, 대문자 CP949를 넣어도 상관없다.)

 

# 데이터 형태와 정보 파악 (3종 세트)

print(df.shape) # 행과 열을 파악한다. (shape는 함수가 아니다. ()없음에 주의)

print(df.info()) # 데이터의 info를 확인하기 데이터 타입이 숫자형(float, int)인지 문자형(object)인지 확인할 수 있다. 라벨, 원핫 인코딩전에 필수다.

print(df.describe()) # 데이터의 기본적인 통계값들을 도출하는 것으로 숫자형 데이터의 열의 갯수, 평균값, 표준편차, 사분위수를 확인할 수 있다.

 

2. 결측치 확인 및 대체하기(제거하기)

위와 같은 기본적인 과정을 거쳤으면 본격적인 가공이 시작되는 가장 중요한 부분이다. 일반적으로 데이터를 만드는 일을 하게 되면 데이터의 양이 많을 경우 누락되는 데이터가 나오게 되며 빅분기 시험 특성상 결측 데이터는 무조건 있다고 봐도 무방하다.

 

# 결측치 확인

print(df.isnull().sum()) # 결측치 확인하는 코드이다. 열별로 한번에 확인이 가능하다.

# isnull()함수와 동일한 역할을 하는 함수는 isna()이다. 아무거나 써도 무방하다.

 

결측치 확인이 되면, 처리하는 방식이 3가지가 있다. 

 

(1) 결측치 모조리 통으로 제거

(2) 평균값이나 중앙값을 구해서 대체

(3) 가장 많이 분포하는 값들을 넣기 (최빈값 넣기)

 

보통은 1번은 절대 시험에서 추천되지 않는 방법이다.

결측 데이터가 많으면 왜곡이 일어나게 되며, 데이터의 형태가 달라질수도 있다.

실무에서도 다루는 데이터의 도메인 지식을 가진 사람과 상의를 해서 지우라고 하는 것 아니면 보통은 통 삭제는 권장되지 않는 것 같다.

 

2번이나 3번으로 처리를 하게 되며, 보통은 시험에서 어떠한 식으로 대체를 하라는지 안내가 나오게 되며, 설령

안내가 없더라도 중앙값을 쓸지 평균값을 쓸지 최빈값을 쓸지 파악이 된다. 데이터의 형태를 보고 파악하면 된다.

(최솟값과 최댓값의 차이가 큰, 쏠려있는 데이터면 보통 중앙값을 많이 활용한다.)

 

중앙값으로 채우는 예시이다.

 

# 결측치가 나온 열들의 중복없는 고유 데이터확인과 종류별 갯수 확인이 필요하다.

df['sex'].unique() # unique()함수 같은 경우 결측치를 포함하며, 중복을 제외한 데이터의 종류를 ndarray로 반환


df['sex'].value_counts() # value_counts()함수는 결측치를 포함하지 않으며, 데이터 종류별 개수를 series로 반환

 

# 결측치 중앙값으로 채우기
missing = ['bill_length_mm','bill_depth_mm', 'flipper_length_mm','body_mass_g'] # 결측값이 있는 열들을 list에 담기 

# missing 변수안에 리스트화 시켜서 넣으면 한번에 처리가 가능하다. 만약 중앙값 이외에 처리가 필요한 부분이 생기면 수동으로 해주는 것이 좋다.


# for 문으로 한번에 처리
for i in missing:
	df[i] = df[i].fillna(df[i].median())
df['sex'] = df['sex'].fillna('Male') # 성별 결측치는 중앙값이 아니라 분포가 조금 더 많은 Male로 처리한다.

결측치를 채우는데 무조건 써야하는 함수는 fillna() 이다. 필수적으로 외워야할 부분이며,

fillnull()이라는 함수는 없으니 주의를 해야 한다. (필나로 외우면 된다. 필라 짝퉁 필나~)

# 결측치가 제대로 채워졌는지 확인해야 한다. 앞서 3종 세트로 소개했던 부분들을 다시 활용하면 된다.

df.isna().sum()

df.info()

# 둘중에 아무 코드나 입력하면 결측치 값이 0이 나오거나 기존 데이터의 행값에 맞게 다 채워져 있으면 된다.

 

3. 라벨 인코딩

머신러닝에서 학습을 용이하게 하기 위해서는 숫자형으로 변환이 필요하다. 

from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder() # encoder 변수에 저장

label = ['species','island','sex'] # 한번에 처리를 위한 list화

df[label] = df[label].apply(encoder.fit_transform) # apply 함수를 적용해서 한방에 바꾸기

# df[컬럼].apply(함수명)으로 사용하면 된다.

 

# 열별로 하나씩 라벨인코딩을 적용시키는 방법 (정석 방법)

from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder()

print(encoder.fit_transform(x['am'])) 'am'열에 대해서만 라벨인코딩을 하는 방법
# 제대로 변환되었는지 확인하는 방법

df.dtypes # 문자형 object에서 정수형 int64로 바뀐것을 확인

4. 원핫 인코딩

원핫 인코딩이란 카테고리별로 이진 특성(0, 1)을 만들어 해당하는 특성만 1, 나머지는 0으로 만드는 방법이다.

pandas의 get_dummies() 함수를 써야 한다.

 

# 데이터 변환, 더미처리 (원핫 인코딩)

import pandas as pd

category = ['island','sex'] # 연속형이 아니라서 범주형으로 변환, (species는 종속변수라서 놔두기)


for i in category:
	df[i] = df[i].astype('category')
    
df = pd.get_dummies(df) # 원핫 인코딩


df.head() # 변환이 제대로 되었는지 확인​

 

 

5. 파생변수 생성 (구간화(비닝))

파생변수를 생성한다. 쉽게 얘기해서 추출하고자 하는 열에서 새로운 정보를 추출하여 의미 있는 데이터를 생성하는 과정이다.

여기에서는 구간화를 진행해 볼 것이다. 수치형(연속형)값들을 이산형 또는 범주형으로 변환하는 것으로

pandas에서 제공하는 cut()함수나 qcut()함수를 사용하여 수행할 수 있다.

cut()함수와 qcut()함수의 차이는 cut()함수는 값을 기반으로 하고 qcut()함수는 분위수 기반으로 한다.

여기에서는 qcut()함수를 사용한다. (q의 유례는 사분위수 quantile()함수에서 유래가 되었다.)

# 파생변수 pd.qcut 사용

df['body_mass_g_qcut'] = pd.qcut(df['body_mass_g'], 5, labels=False) # 5구간으로 나눈다는 의미
df.head() # 확인

df['body_mass_g_qcut'].value_counts() # 5구간으로 잘 나누어 졌는지 확인

 

6. 스케일링

파생변수까지 생성해주었으면 데이터셋을 train, test로 나누어서 모델학습을 하기 전에 스케일링을 해주어야 한다.

스케일링을 수행하는 이유는 머신러닝 결과가 왜곡되지 않고, 특정한 독립변수를 무시하지 않게 하기 위함이다.

예시를 들면 교육소비 지출액과 학점으로 취업여부를 판별하는 분류모델을 만든다고 가정했을때,

학점은 만점이 4.5 교육소비 지출액은 개인마다 편차가 있겠지만, 10만원 단위에서 100만원 단위까지 있을 것이다.

스케일자체가 다르기 때문에 MinMaxScaler를 활용하게 된다면 0을 min으로 1을 max로하여 스케일을 맞추어서 데이터를 머신러닝 모델에 넣어주게 되면 결괏값이 좀더 정확하게 나올 것이다.

 

많이 사용되는 스케일링의 종류는 크게 2가지가 있다.

1. StandardScaler (평균값 : 0, 표준편차 : 1)

2. MinMaxScaler (최솟값 : 0, 최댓값 : 1)

StandardScaler는 범주형 데이터일 경우 MinMaxScaler는 수치형일 경우 활용되는데,

 

MinMaxScaler의 단점은 이상치에 민감하다는 것이다. 그렇지만, 수치형일 경우 많이 활용되며 

실제 아래 예시는 MinMaxScaler를 사용한 것이다.

from sklearn.preprocessing import MinMaxScaler

scale_list = ['bill_length_mm','bill_depth_mm','flipper_length_mm','body_mass_g']

scaler = MinMaxScaler()

df[scale_list] = sclaer.fit_transform(df[scale_list]) # fit과 transform 함수로 떼어서 작성해도 된다.

df.head() # 데이터 확인

 

7. 데이터 분리 (train_test_split)

머신러닝 모델링을 수행하기 전에 데이터 분리를 진행하여야 한다.

지금 여기서는 독립변수(x)와 종속변수(y)의 분리가 되어 있지 않다.

우선은 분리를 진행하여야 한다.

x = df.iloc[: 1:] # species를 제외한 모든 데이터 (독립변수이자 학습 데이터)
y = df['species'] # species (종속변수이자 정답 데이터)

print(df.iloc[:,1:].shape) # 제대로 분리되었는지 확인

print(df['species'].shape) # 열이 나오지 않아야 한다.
# sklearn 안에 있는 train_test_split 함수로 분리

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size= 0.2, random_state=1, stratify = df['species'])

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

random_state = 1 같은 경우에는 호출할 때마다 동일한 학습/테스트용 데이터 세트를 생성하기 위해 주어지는 난수 값으로따로 주지 않아도 되는 하이퍼 파라미터다. stratify는 종속변수인 species를 기준으로 층화추출을 위해 설정하는 값이다.

설정을 안해줘도 결괏값이 나오기는 하지만, 설정을 해주면 성능이 조금더 높게 나온다고 알려져 있다.

 

8. 모형학습

(1) 일반 단일 모형

(2) 앙상블 (단일모형의 결합)

 

train, test를 분리하고 나면 이제 모델 학습이 시작된다. 

일반 단일 모형과 앙상블중 요구하는 것으로 하면 되는데, 보통은 RandomForest 모델을 사용한다.

RandomForest 같은 경우에는 성능도 좋고 모델 자체가 앙상블이라서 많이 사용되고 있다.

 

# 모형 학습

# 1번째 모형

from sklearn.ensemble import RandomForestClassifier # 랜덤 포레스트는 배깅 계열이다.

model1 = RandomForestClassifier() # 하이퍼 파라미터는 default값으로 되어 있다.

model1.fit(x_train, y_train) # 문제지와 정답지를 같이 넣어서 학습시켜주는 과정이다.

pred1 = model1.predict(x_test) # 새로운 문제 (테스트 데이터를 넣어서 예측)


print(pred1)

 

 

# 2번째 모형

from sklearn.ensemble import AdaBoostClassifier # 부스팅 계열 

model2 = AdaBoostClassifier() 

model2.fit(x_train, y_train)

pred2 = model2.predict(x_test)

print(pred2)

 

 

# 3번째 모형 (LightGBM)

from lightgbm import LGBMClassifier 

model3 = LGBMClassifier()

model3.fit(x_train, y_train)

pred3 = model3.predict(x_test)

print(pred3)

 LightGBM 같은 경우에는 sklearn안에 있지 않고 따로 분리가 되어있는 모델이다.

최근에 빅데이터 분석기사 실기장에 설치되었는 것을 확인하는 글이 있었는데, LightGBM 같은 경우 최근에 나온 모델이고

XGBoost와 함께 부스팅 계열 알고리즘에서 가장 각광받고 있다.

가장 큰 장점은 XGboost보다 가벼운 모델이라서 실제 모델링을 수행하는데 1분이 초과되면 안되는 시험장에 특성에 맞는 성능좋은 모델이라고 생각한다.

하지만, 적은 데이터 세트에 적용할 경우 과적합이 발생하기 쉬우나, 빅데이터 분석기사 특성상 결과 파일만 형식에 맞게 잘 제출하면, 성능가는 상관없이 고득점이 가능하므로 (아직까지는..) 필자는 이 모델로 작업유형 2에 활용하려고 한다.

 

# 앙상블 기법 --> 2가지 모형 결합

from sklarn.ensemble import VotingClassifier

clf = VotingClassifier(estimators = [('rf',model1), ('ad',model2)], voting = 'hard') 

# voting soft : 확률, voting hard : 정수형으로 투표 결과를 반영

clf.fit(x_train, y_train)

pred4 = clf.predict(x_test)

마지막 모델링 기법은 앙상블 기법으로 skelarn.ensemble 모듈안에 있는 VotingClassifier를 활용한다.

 

주요 하이퍼파라미터에서는 estimators를 넣어서 모델 두개 (랜덤포레스트와, 에이다부스트)를 넣어주었고, voting 방식도

hard와 soft 두 가지가 있는데, hard방식으로 하였다.

 

x_train, y_train 데이터로 학습하고 x_test로 평가하는 방식은 일반 단일모델을 활용할때와 똑같은 방식으로 

코드를 작성하면 된다.

 

9. 모형평가 (score내서 제대로 학습이 되었는지 확인하는 부분)

# 모형 평가
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report # 분류 관련된 정보가 한방에 출력

print('랜포 정확도', accuracy_score(y_test, pred1))
print('에이다 부스트 정확도', accuracy_score(y_test, pred2))
print('LightGBM 정확도', accuracy_score(y_test, pred3))
print('하드보팅 정확도', accuracy_score(y_test, pred4))

 

10. 하이퍼파라미터 튜닝 (아직까지 출제된적은 없으나, 출제범위이므로 가장 기본적인 GridSearchCV활용)

# 하이퍼 파라미터 튜닝

from sklearn.model_selection import GridSearchCV

params = {'n_estimators' : [50, 100], 'max_depth' : [4, 6]} 

model5 = RandomForestClassifier()

clf = GridSearchCV(estimator = model5, param_grid = params , cv = 3)

clf.fit(x_train, y_train)

print ('최적의 하이퍼 파라미터는?', clf.best_params_)

머신러닝에서 하이퍼 파라미터란 사용자가 직접 입력가능한 설정옵션이라고 생각하면 된다.

각 모델마다의 하이퍼 파라미터는 엄청 많고, 최적화된 값을 넣으면 성능이 소폭 상승하는데, 

빅데이터 분석기사 같은 경우에 시험 범위에는 들어가지만 그냥 default값으로 해도 상관이 없다.

옵션으로 하는 방식으로 그리드 서치를 활용하였는데, 랜덤 서치나 베이지안 최적화 같은 방법은 

하이퍼 파라미터를 찾을시 시간이 1분을 초과할 확률이 크므로 사용하는 것은 비추천이다.

 

 

11. 예측값 저장 (index=False로 시험제출 폼에 맞추어서 내야 채점이 제대로 된다. )

# 데이터 프레임으로 바꾸고 열의 이름도 시험에서 요구하는 방식으로 바꾸기
pd.DataFrame({'id':y_test.index, 'pred':pred3}).to_csv('/content/00300.csv', index = False)

유형 1과는 다르게 csv파일로 저장을 해야한다.

기본적으로 pd안에 있는 DataFrame 변환 함수로 열의 이름과 데이터를 배치하고 to_csv 함수를 통해서

csv 파일로 저장해야 한다. 

보통 파일이름은 수험번호로 하는 점도 잊으면 안된다. 

그리고 가장 주의할 점은 index = False를 주어야 된다. 

채점을 하는 알고리즘이 index가 열로 추가되어 들어가면, 채점 자체가 불가능하고 0점 처리가 될수도 있다.

 

12. read_csv로 저장된 데이터 폼 확인

최종적으로 csv를 읽어서 확인해야 한다.

final = pd.read_csv('/content/00300.csv') # 데이터 읽어서 확인
print(final)

 

주의할 점은 Colab하고 다르기 때문에 print()함수를 써서 일일이 확인을 해야한다는점, 

인터프리터 형식으로 되어 있지 않아서 좀 불편한 점을 감수해야한다는 것,

그리고 계산이 느리고 출력이 느리다는 점이다.

 

회귀모형 분석에서 언급하겠으나, 불필요한 열의 제거와 다중공선성의 문제 해결을 위한 열의 선별적 삭제는 

옵션이다. 실무에서는 꼭 거쳐야하는 과정이지만, 빅데이터 분석기사에서는 모형의 성능을 조금이라도 올려야하는 캐글대회나 데이콘 대회가 아니다. 일단 모델링을 하여 결과값만 요구하는 프레임에 맞추어 제출을 하면 만점이 나온다고 한다.

 

시험 연차가 쌓이면 시험의 성향이 안정화되면서 좀더 많은 것을 요구하며 어려워 질수도 있겠지만,

 

현재의 추세에서는 위의 틀만 외워서 응용할 수준까지만 된다면, 만점까지는 모르겠으나 합격권 점수를 받는 것은 무리가 없을 것이다.

반응형