Scikit-Learn으로 시작하는 머신러닝 : 머신러닝 기초 정리

0

Machine-Learning

목록 보기
2/4

reference : 파이썬 머신러닝 완벽 가이드

reference: https://scikit-learn.org/stable/modules/classes.html
- from Scikit-learn Docs

정리하지 않으면 까먹는다.....

머신러닝 공부 정리하기

기계 학습 또는 머신 러닝은 경험을 통해 자동으로 개선하는 컴퓨터 알고리즘의 연구이다. 인공지능의 한 분야로 간주된다. 컴퓨터가 학습할 수 있도록 하는 알고리즘과 기술을 개발하는 분야이다.
데이터의 핵심은 표현과 일반화에 있다. 표현이랑 데이터의 평가이며, 일반화란 아직 알 수 없는 데이터에 대한 처리이다. 이는 전산 학습 이론의 한 분야이기도 하다.
- from 위키백과

머신러닝은 숨겨진 패턴을 인지해서 해결하는 것입니다.
머신러닝 알고리즘은 데이터를 기반으로 통계적인 신뢰도를 강화하고 예측 오류를 최소화하기 위한 다양한 수학적 기법을 적용해 데이터 내의 패턴을 스스로 인지하고 신뢰도 있는 예측 결과를 도출해 냅니다.


머신러닝의 분류

지도학습

  • 분류
  • 회귀
  • 추천 시스템
  • 시각/음성 감지/인지
  • 텍스트 분석, NLP

비지도학습

  • 클러스터링
  • 차원 축소
  • 강화학습

머신러닝 파이프라인

(Data ingestion) ➡️ Data validation ➡️ Data Preprocessing ➡️ Model training ➡️ Model analysis and validation ➡️ (Model deployment)

실제로는 대회에서 만나는 깔쌈한 데이터가 아닌 정제되지 않은 데이터를 마주하기 때문에 대부분의 시간을 data preprocessing에 쓴다고 합니다. ㅠ_ㅠ

( ) 친 부분은 조금 다른 영역이라고 생각해서 표시해뒀습니다.
Analysis와 Engineer 영역의 차이 정도라고 생각합니당,,,

(validation 파트가 조금 애매하다고 생각하네여.. 둘 다 하겠져..?)

Preprocessing

사람들마다 preprocessing하는 방법이 다르겠지만 제가 공부한 바로는
pandas를 이용한 데이터 핸들링 - DataFrame 활용, 크기가 큰 데이터의 경우에는 dask등의 라이브러리 별도 사용을 통해 데이터를 불러온다.

  • null 값 확인
  • 데이터 확인하기
    • data visualization
    • skewed data 체크하기
    • info, describe 등 확인해보기
  • feature engineering
  • scaling, transformation 등 진행
  • encoding

이 외에도 다양한 기법들이 많지만 기본적으로 이정도를 진행하는 것 같습니다.

about Model

그럼 이제 모델에 데이터를 학습시켜봅시다.
처음에 이 부분이 굉장히 헷갈렸는데 도와줄 수 있는 사람이 주변에 없어서 애먹었던 기억이 있네요

쉽게 말해 기초적인 머신러닝 순서는 (제가 이해한)

데이터 불러오기 ➡️ 데이터 확인하기 ➡️ 전처리 ➡️ 모델 선택 ➡️ 모델에 학습시키기 ➡️ 학습된 모델이 정확도를 얼마나 가지는지 확인하기 ➡️ 모델의 정확도가 괜찮다? ➡️ 사용

데이터 불러오기 ➡️ 데이터 확인하기 ➡️ 전처리 ➡️ 모델 선택 ➡️ 모델에 학습시키기 ➡️ 학습된 모델이 정확도를 얼마나 가지는지 확인하기 ➡️ 모델의 정확도가 만족할 만한 수준이 아닌 것 같다. ➡️ 전처리 혹은 모델 선택 파트로 돌아가기

정도입니다. 이 큰 그림을 이해했어야 하는데 이 큰 그림을 이해하는데 너무 오래 걸렸어요.. 기초부터 배운 게 아니고 주먹구구식으로 욱여넣다보니 ㅠ_ㅠ;

어쨌든 전체적인 파이프라인은 저렇습니다. 그렇다면 모델의 선택(model selection)과 모델 학습 및 성능 확인이 중요한 이슈가 되겠져!

모델의 선택은 뒷단에서 scikit-learn 라이브러리 내에서 제공하는 다양한 것들을 살펴보기로 하고,
먼저 학습 데이터와 테스트 데이터를 나눠야겠죠!

scikit-learn에서는 train_test_split을 제공합니다.


train_test_split에 대해

굉장히 헷갈렸던 기억이 있어서 꼼꼼히 기억해두고자.. 칼럼을 나눴습니당

먼저, 내가 모델에 학습시키고자 하는 거대한 데이터셋을 들고옵니다.
이 데이터셋을 몽땅 학습시켜서 모델을 쓰면 좋겠지만, 그러면 이 모델이 공부를 잘 했는지 확인할 시험지가 없죠?

생각해보면, 문제가 100개인데, 100개의 문제를 다 풀고 들어가서 그 중 20개가 시험으로 나온다라고 한다면 누구라도 100점을 맞을 수 있습니다.
따라서 문제 100개를 시험 문제 20개, 공부할 문제 80개 이런식으로 나눠줘야 한다는 겁니다.

이렇게 data를 train(공부) dataset 과 test(시험) dataset 으로 나눠주는 게 바로 train_test_split입니다! 두둥!!

 이걸 이해를 못해서 힘들었던 나날들...
 

따라서 dataset을 train과 test로 나눠주는데, 여기서 이 비율에 따라서도 모델의 성능이 달라집니다. 데이터 갯수가 작거나 겹치는 데이터가 많을수록 큰 영향을 받겠지요? 또 나눌때마다 시험지와 문제지가 달라지면 모델의 성능이 달라지는 경향이 있을 수 있을 것입니다.
따라서 이 크기를 조금씩 바꿔주는 것, 그리고 seed를 고정해주는 것과 같은 행위들을 통해 이를 일정수준 완화시키곤 합니다.


Model 선택하기

머신러닝의 🌸꽃🌸이죠 다양한 모델들
저는 뭔가 접해보지 못한 모델을 코드공유해주셨을 때 굉장히 두근거립니당..
모델마다의 특징이 워낙 많아서여.. 그래서 이 모델 선택은 취향껏..능력껏...ㅎ_ㅎ

캐글이나 데이콘 code sharing 돌아다녀보시면 굉장히 다양한 모델들이 있어요!
for beginner 등의 제목으로 공유되는데 이런 코드들을 직접 검색해보고 특징을 공부하고 적절한 데이터에 접목해보는 게 머신러닝 공부인 것 같아요!

training 및 모델 성능 평가(Performance Evaluations)

모델을 학습시키는거야 뭐.. 모델의 일이라 부가적인 것들을 빼면 어렵지 않은데, 이 shape를 맞춰주는 게 또 약간 정신없긴 합니다만.. 그래도 열심히 공부하니까 되긴 되더라구요 ㅠ

근데 제가 굉장히 헷갈렸던 부분이 하나 더 있는데 바로 성능 평가였습니다.
성능의 평가 지표에는 굉장히 많은 방법들이 있습니다. 물론 커스텀할수도 있더라구요..
대표적으로는

분류평가지표회귀평가지표
정확도MSE
정밀도RMSE
Recall결정계수
F1 Score
AUC

등이 있습니다. 이러한 기본적인 eval metrics는 sklearn.metrics를 통해 제공됩니다!

RMSE는 sklearn에서 지원하지 않는 걸로 알고 있습니다.. 
저는 그렇게 배웠기에 루트를 씌워서 만들어서 썼던 것 같아요 (?)

앞서 말한 다양한 평가 지표들로 이 모델이 얼마만큼의 성능을 내고 있는가를 평가할 수 있어요.

쉽게 말해
데이터를 공부용과 시험용으로 나눠서, 공부용을 모델에 학습시키고, 시험을 치게 한 다음에 그 점수를 내는 것, 근데 점수를 낼 때 다양한 평가지표를 통해 다른 점수를 낼 수 있다.
예를 들어, 반만 틀린 문제를 0.5점을 줄 것이냐, 틀리게 할 것이냐, 맞게 할 것이냐의 차이에 따라 점수가 달라질 수 있다는 것이죠!

이거 이해하는 게 뭐 어렵다고 땅을 팠는지.. 정리하니 또 기억이 새록새록 나네용 'ㅅ'

그외..

그 외에는 말 그대로 한번 실행하는데 꼭 필요하진 않지만 모델의 성능을 높이기 위해 하는 것들이 있습니다.
바로 파라미터 튜닝 및 Kfold, ensemble, stacking 등인데요..
이런 것들은 차근차근 필요하다고 느낄 때마다 구글링하며 배워나갈 수 있습니다!


사이킷런으로 시작하는 머신러닝

Scikit-learn이란?

  • simple and efficient tools for predictive data analysis
  • accessible to everybody, and reusable in various contexts

data analysis를 위한 쉽고 효과적인 툴을 포함하고 있으며, 사용하기 편리하고 파이써닉한 개발 라이브러리입니다.

최근에는 Tensorflow, Keras 등 딥러닝 전문 라이브러리의 강세로 인해 대중적인 관심이 줄어들고는 있지만 여전히 많은 데이터 분석가가 의존하는 대표적인 파이썬 ML 라이브러리
- from 파이썬 머신러닝 완벽 가이드

쉽게 말해, 앞서 말한 머신러닝을 통한 분석을 할 수 있게 쉽고 다양하며 수학적인 툴들을 제공해줍니다.
모두 코드를 하나하나 쳐서 만들어야 하는 게 아니라 임포트 한 줄이면 엄청난 수식 베이스의 머신러닝 분석 기법들을 사용할 수 있게 해준다는 것!


Preprocessing에 대해 제공하는 툴들

train_test_split

아까 설명했던대로 학습지와 시험지를 나누는 것입니다. model_selection 모듈에서 제공합니다

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(data, target, test_size(or train_size), random_state=24)

기본적으로 학습데이터(타겟값을 뺀), 타겟 데이터, 트레인 혹은 테스트 사이즈 설정(최대 1), 랜덤 시드 파라미터를 넣어 나눕니다.
random_state는 앞서 설명했듯, 나눌 때마다 데이터 세트가 바뀌지 않게 고정해주는 역할을 합니다.

반환되는 형태는 튜플입니다.

더 다양한 파라미터 및 툴은 https://scikit-learn.org/stable/modules/classes.html
sklearn docs를 읽어보시기 바랍니다!


추가! 교차 검증(Cross-validation)

교차 검증은 러프하게 머신러닝을 한번 돌리는데 필요하진 않지만, 모델의 훈련을 잘 하기 위해 필요합니다. 성능 향상에 필요하다는 의미!
따라서 교차 검증도 정리해봅니다!

KFold Cross-validation
시도횟수데이터 세트1데이터 세트2데이터 세트3데이터 세트4데이터 세트5
1회학습학습학습학습검증
2회학습학습학습검증학습
3회학습학습검증학습학습
4회학습검증학습학습학습
5회검증학습학습학습학습

각 시도횟수마다 검증 데이터셋이 변화하는 게 보이시나여!
이게 바로 K=5인 경우의 K-Fold cross-validation입니다.
이 다섯가지의 예측 평가를 평균하여 사용합니다.

추가적으로

Stratified K-Fold

도 정리해봅니다!

이 방법은 말 그대로 값을 나눠서 fold 하겠다는 겁니다.
예를 들어 1인지 0인지를 분류(classification)하는 모델이 있을 때, 정답이 1인 데이터가 100만개, 정답이 0인 데이터가 5000개 정도의 차이를 가지고 있다고 하면 (실제로는 말도 안되지만 ㅠ) 아무렇게나 fold하면 당연히 정답이 1인 데이터만 많이 뽑는 횟수가 많겠져..
이를 방지하기 위해 정답이 1인 데이터와 정답이 0인 데이터를 적절한 비율로 잘 뽑아서 fold하겠다는 것입니다.

최근에 진행했던 기업 프로젝트에서도 실제 판매 데이터의 대부분이 하나의 제품에 몰려 있어서 
모델이 무지성으로 하나의 제품만 뱉어주는(?) 이 아니라 추천해주는 ML모델을 마주한 적이 있습니다.
그럴 때 이런 fold를 사용할 수 있겠져..? 물론 이런 경우는 언더샘플링을 하던가 해야겠지만요..
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold

Encoding

다음은 인코딩입니다. 인코딩도 처음엔 굉장히 어려웠는데, 지금도 어려워요 (,,,)
sklearn에서는 Label encoder, One-hot encoder, ordinal encoder을 제공합니다.

인코딩이라는 것은, str 형태로 된 데이터 친구들은, 사람은 읽을 수 있지만 컴퓨터는 읽을 수 없으니 이러한 데이터를 컴퓨터가 읽을 수 있게 숫자 값으로 변환해주는 과정입니다.
따라서 데이터가 숫자만으로 이루어진 게 아니라 범주형 변수 등으로 이루어져 있다면 인코딩을 사용해주시는 게 좋습니다.
인코딩의 세계가 또 복잡하기 때문에...

Label Encoder
One-hot Encoder

https://scikit-learn.org/stable/modules/classes.html
참고합시다!

from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OrdinalEncoder

Feature Scaling

서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 피처 스케일링(feature scaling)이라고 합니다. 대표적인 방법으로 표준화(Standardization)정규화(Normalization) 이 있습니다.

표준화(Standardizaion)
표준화란 데이터의 피쳐 각각이 평균이 0이고 분산이 1인 가우시안 정규 분포를 가진 값으로 변환하는 것을 의미합니다.

정규화(Normalization)
정규화는 서로 다른 피처의 크기를 통일하기 위해 크기를 변환해주는 개념입니다.
예를 들어 피처 A는 거리로서 0~100km 데이터이고, 피처 B는 금액으로서 0~100,000,000₩ 단위라면, 이 둘을 비교할 수 있는 수준의 단위로 만들어줘야 할 것입니다. 이를 정규화를 통해 진행합니다.

사이킷런에서의 Normalizer모듈은 선형대수에서의 정규화 개념이 적용되어 개별 벡터의 크기를 맞추기 위해 변환하는 것을 의미합니다.
개별 벡터를 모든 피처 벡터의 크기로 나누는 것이 사이킷런의 정규화 모듈이므로, 
일반적으로 칭하는 정규화와 표준화에 맞추어 설명하고자 한다고 파이썬 머신러닝 완벽 가이드 저자님께서 말씀해주셨습니다. 
저도 처음 알게 된 내용이었어요! 오호랑.. 다음엔 사이킷런 normalizer를 써보는걸로..

대표적인 피쳐 스케일링 클래스인 StandardScaler와 MinMaxScaler에 대해 설명합니다!

StandardScaler

무지성으로 적용해도 욕먹지 않을 수 있을(..가능성이 높은) 스케일러입니다.

개별 피처를 평균이 0이고 분산이 1인 값으로 변환해줘서 가우시안 정규 분포를 따르도록 변환하는 것입니다.
특히 SVM, Linear Regression, Logistic Regressor 모델은 데이터가 가우시안 분포를 지니고 있다고 가정하기 때문에 사전에 이를 진행하는 것이 중요합니다!

이런 걸 알려면 .. 공부를 열심히 해야 ㅠ_ㅠ 한 번 공부했음에도 다시 보니 생소하네요..
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(data)
scaled_data = transform(data)

동일하게 아래의 코드로도 실행이 가능합니다.
fit 과 transform을 따로 하던 것을 fit_transform으로 합쳐준 것 뿐.. 반환하는 형태가 조금 달랐나? 하여튼 fit_transform이 안될 때가 있고 뭐 그런 차이가 조금 있었는데 지금은 그냥 일단 해보고 안되면 다른 방법으로 시도하고 있습니다 (?야매)

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

scaler.fit_transform(data)

MinMaxScaler

데이터값을 0과 1 사이의 범위 값으로 변환하고, 데이터의 분포가 가우시안 분포가 아닐 경우에 MinMaxScale을 적용할 수 있다고 설명하고 있습니다.

✔️ 앞서 설명드린 StandardScaler와 이 MinMaxScaler는 데이터 값의 range와 최대, 최소값을 사용하기 때문에 이상치의 영향을 많이 받습니다.
이상치, 혹은 혼자 튀는 값이(?) 있을 경우에는 Robust Scaler를 사용해서 튀는 값의 영향을 최소한으로 줄여주는 것도 생각해봄직합니다.

물론 데이터가 많으면 그냥 날리는 게 마음 편했습니다,, 
하지만 공부할 때는 큰 데이터를 볼 일이 잘 없었어서..
from sklearn.preprocessing import MinMaxScaler

scaler - MinMaxScaler()
train_scaled = scaler.fit_transform(data)

✔️ 제가 또 데'배아'이던 시절에 여기서 실수를 많이 했는데 ㅠㅠ 책에도 나와있는데 왜 이해를 못했는지 모르겠지만...

Scaling을 적용하기 전에 train_test_split을 해버리면 어떻게 될까요?
나눠진 train dataset과 test dataset의 data range나 min,max값이 항상 같다고 보기가 어렵습니다.
따라서 같은 데이터라도 scaling되는 값이 달라져버리겠죠. 그러면 모델이 학습을 하고 문제를 제대로 맞추기가 힘듭니다.
따라서 Scaling은 train, test dataset을 나누기 전에 한번에 해주거나 range를 맞춰주는 게 좋은데, range를 맞추려면 고도의 python 스킬이 필요할 것 같으므로 저는 scaling을 진행하고 split을 해주는 편입니다 ^0^


Model에 대해 제공하는 툴들

정말 글을 하루종일 썼네요 드디어 모델 학습 및 평가입니다.

기본적으로 fit, predict에 대한 이해를 하시면 충분합니다.

땅파던 저는 이거 이해하는데도 며칠이 걸렸다는 흐잉 ㅠ

fit, predict, accuracy_score

모델이 학습을 하는 방법은 뭘까요
여기서 굉장히 띠용했는데 되게 쉽더라구요,, 학습시키는 거는..

그냥 fit 이거 하나 입력해주면 됩니다 ;ㅅ;

그럼 모델이 시험지를 푸는 방법은?

그냥 predict하나 입력해서 OMR답안지를 만든 다음,

accuracy_score를 통해서 채점할 수 있습니다. (정확도 계산!)

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(data, label, train_size = 0.8, random_state = 24)

model = RandomForestClassifier(random_state = 24)
model.fit(X_train, y_train)
preds = model.predict(X_test)
accuracy = accuracy_score(y_test, preds)

print('accuracy: {0:.4f}'.format(accuracy))

위의 코드는 첫줄부터 모델을 임포트해오고,
두번째 줄에서 accuracy_score, 채점 기계(?)를 임포트해오고,
세번째 줄에서는 train_test_split을 임포트해오고,
네번째 줄은 train_test_split을 진행하여 데이터를 시험지와 문제지로 나누며,
다섯번째 줄은 앞으로 내가 사용할 model을 선언,
여섯번째 줄은 fit을 통해 학습을 진행하고,
일곱번째 줄은 predict를 통해 시험지를 풀게 만들고,
여덟번째 줄은 accuracy_score를 통해 시험지와 답을 비교해서 채점한 다음에
마지막 줄에서 print accuracy를 통해 정확도를 리턴해주는 코드입니다!

완전 간단!! 까먹지 않기!!! 자주 좀 읽자!!!!

다양한 모델들에 대해...

흔히 우리가 아는 다양한 모델들은

베이즈 모델, 랜덤 포레스트, 결정트리(Decision Tree), GradientBoosting, XGBoost, LGBM, Catboost 등이 있겠죠..?
각각의 모델들은 제각기 다른 특성을 가지고 있으므로 하나의 데이터를 잘 관찰해서 어떤 모델을 적용할지 결정하는 게 데이터의 설명력에 큰 영향을 미칩니다.

앞서 설명했던 fit, predict가 전부가 아니고 train(학습할 때 쓰임), get_clf_eval(), eval(), predict_proba() 등 다양한 방법으로 학습, 평가, 예측을 시행할 수 있으니 이런 부분에 대해서는 다음에 또 정리해보겠습니다!


모델의 예측력을 높이는 다양한 방법

Parameter tuning

대표적으로 파라미터 튜닝이 있는데 이건 여기에 추가해야 할 것만 같습니다..

parameter tuning이란?
각각의 모델이 그냥 끌고와서 사용하기만 하면 되는 게 아니라, 깊이, 너비, learning_rate 등의 파라미터에게 영향을 받습니다.
이것도 처음에 이해하기 힘들었는데, 쉽게 말하자면

모델이 그냥 pure한 상태에서 학습을 해도 괜찮지만, 나는 더 성능 좋은 모델을 만들고 싶으니까 더 학습을 많이 하게 할래! 근데 Overfitting이 걱정되니까 early_stopping_rounds를 줘서 이만큼 비슷하게 학습하면 그만하게 할래!

라는 생각을 했을 때(...) 성능을 올리기 위해 반복 수행하는 횟수를 변화시키던가, 깊이를 지정하던가, 하나의 트리가 가질 수 있는 최대 리프의 갯수 등을 직접 지정해주고, 너무 많이 학습해서 과적합이 나면 안되니까 이쯤 되면 멈춰! 라고 early_stopping_rounds를 걸어주는 등의 파라미터 튜닝을 할 수 있다는 이야깁니다..

이 파라미터들은 각 모델의 docs를 참고하시면 defualt 값과 함께 자세히 설명되어 있으니 docs를 참고하시면 되고, 인간이란 나태한 존재라(,,저만) 이 하이퍼 파라미터 튜닝을 자동으로 해주는 다양한 툴들도 개발했으니, 그것이 바로 GridSearch, RandomGridSearch 및 Optuna와 같은 툴입니다.

이것도 나중에 한번 정리해봐야겠다,,, 

긴 글 읽어주셔서 감사합니다.

profile
분명히 처음엔 데린이었는데,, 이제 개린이인가..

2개의 댓글

comment-user-thumbnail
2024년 2월 19일

사이킷런을 배우고 있는데 전체적인 설명이 있어서 이해가 잘 되네요 ㅠ 좋은 포스팅 감사합니다

1개의 답글