지도학습
- 지도 학습은 정담(label)을 컴퓨터에 미리 알려 주고 데이터를 학습시키는 방법
- 지도 학습에는 분류와 회귀가 존재
분류 - 주어진 데이터를 정해진 범주에 따라 분류
회귀 - 데이터들의 특성을 기준으로 연속된 값을 그래프로 표현하여 패턴이나 트렌드를 예측할 때 사용
분류와 회귀 차이
구분 | 분류 (Classification) | 회귀 (Regression) |
목표 | 입력 데이터를 미리 정의된 여러 범주 중 하나로 분류 | 연속적인 값을 예측 |
출력 값 | 이산적 값 (카테고리) | 연속적 값 (숫자) |
예시 | 이메일이 스팸인지 아닌지 분류, 손글씨 숫자 인식 | 주택 가격 예측, 온도 예측 |
알고리즘 예시 | 로지스틱 회귀, 의사 결정 트리, 랜덤 포레스트, 서포트 벡터 머신(SVM), k-최근접 이웃(K-NN), 신경망 | 선형 회귀, 다항 회귀, 의사 결정 트리, 랜덤 포레스트, 서포트 벡터 머신(SVM), 신경망 |
평가 지표 | 정확도, 정밀도, 재현율, F1 스코어, AUC-ROC | 평균 제곱 오차(MSE), 평균 절대 오차(MAE), R² 스코어 |
응용 분야 | 스팸 필터링, 질병 진단, 이미지 분류, 음성 인식 | 주택 가격 예측, 주가 예측, 날씨 예측, 경제 데이터 분석 |
데이터 유형 | 범주형 데이터 | 연속형 데이터 |
모델 출력 예시 | 클래스 레이블 (예: '스팸', '비스팸') | 실수 값 (예: 150.75) |
k-최근접 이웃
- k-최근접 이웃은 새로운 입력(학습에 사용하지 않은 new 데이터)를 받았을 때 기존 클러스터에서 모든 데이터와 인스턴스 기반 거리를 측정한 후 가장 많은 속성을 가진 클러스터에 할당하는 분류 알고리즘
- 과거 데이터를 사용하여 미리 분류 모형을 만드는 것이 아니라, 과거 데이터를 저장해 두고 필요할 때마다 비교를 수행하는 방식
- k 값의 선택에 따라 새로운 데이터에 대한 분류 결과가 달라질 수 있음에 유의 해야함
- k-최근접 이웃은 직관적이며 사용하기 쉽기 때문에 초보자가 쓰면 좋음
- 훈련 데이터를 충분히 확보할 수 있는 환경에서 사용하면 더 좋음
캘리포니아 주택 가격 예측 (California Housing Dataset)
import numpy as np from sklearn.datasets import fetch_california_housing from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsRegressor from sklearn.metrics import mean_squared_error, r2_score |
- 캘리포니아 주택 데이터셋을 로드함
- X는 특성 데이터(즉, 입력 변수)이고, y는 타겟 데이터(즉, 예측하려는 주택 가격)
# 1. 데이터 로드 housing = fetch_california_housing() X, y = housing.data, housing.target |
훈련 데이터와 테스트 데이터로 분리
- test_size=0.2는 데이터의 20%를 테스트 세트로 사용하고, 나머지 80%를 훈련 세트로 사용
- random_state=42는 데이터 분할 시 랜덤성을 고정하여 동일한 분할을 재현 가능
# 2. 데이터 분할 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
특성을 정규화함
- fit_transform 메서드를 사용하여 훈련 세트에 맞춰 정규화하고 변환
- transform 메서드를 사용하여 테스트 세트를 변환합니다. 훈련 세트의 정규화 기준에 맞추어야함
# 3. 데이터 정규화 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) |
k-NN 회귀기를 훈련시킴
- n_neighbors=k는 모델이 예측할 때 고려할 이웃의 수를 5로 설정
- fit 메서드를 사용하여 훈련 세트(X_train, y_train)로 모델을 학습
# 4. k-NN 회귀기 훈련 k = 5 knn_regressor = KNeighborsRegressor(n_neighbors=k) knn_regressor.fit(X_train, y_train) |
테스트 데이터로 예측을 수행하고 모델의 성능을 평가
- mean_squared_error 함수를 사용하여 예측값(y_pred)과 실제값(y_test) 간의 평균 제곱 오차(MSE)를 계산
- MSE는 오차의 제곱 평균으로, 값이 작을수록 예측이 실제 값에 가깝다는 것을 의미
- r2_score 함수를 사용하여 R² 점수를 계산
- R² 점수는 모델의 설명력을 나타내며, 1에 가까울수록 모델이 데이터를 잘 설명한다는 의미
# 5. 예측 및 평가 y_pred = knn_regressor.predict(X_test) mse = mean_squared_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"Mean Squared Error: {mse:.2f}") print(f"R^2 Score: {r2:.2f}") |
결과
Mean Squared Error: 0.43 R^2 Score: 0.67 |
서포트 벡터 머신
- 분류를 위한 기준선을 정의하는 모델
- 분류되지 않은 새로운 데이터가 나타나면 결정 경계(기준선) 기준으로 경계의 어느 쪽에 속하는지 분류하는 모델
- 결정 경계와 가까이 있는 데이터를 의미
결정경계
- 데이터를 분류하기 위한 기준선
- 결정 경계는 데이터가 분류된 클래스에서 최대한 멀리 떨어져 있을 때 성능이 가장 좋음
- 최적의 결정 경계는 마진을 최대로 해야 함
마진
- 결정 경계와 서포트 벡터 사이의 거리를 의미
서포트 벡터 머신은 데이터를 올바르게 분리하면서 마진 크기를 최대화해야 하는데, 결국 이상치를 잘 다루는 것이 중요하다.
- 하드 마진 : 이상치를 허용하지 않는 것
- 소프트 마진 : 어느 정도의 이상치들의 이상치들이 마진 안에 포함되는 것을 허용
서포트벡터 머신 예시
라이브러리 호출
from sklearn import svm from sklearn import metrics from sklearn import datasets from sklearn import model_selection import tensorflow as tf import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' |
'TF_CPP_MIN_LOG_LEVEL' 이라는 환경 변수를 사용하여 로깅을 제어
- 기본값은 0으로 모든 로그가 표시
- INFO 로그를 필터링하려면 1
- WARNING 로그를 필터링하려면 2
- ERROR 로그를 추가로 필터링하려면 3
# 1. 데이터 로드 iris = datasets.load_iris() # 2. 데이터 분할 X_train, X_test, y_train, y_test = model_selection.train_test_split(iris.data, iris.target, test_size=0.6, random_state=42) |
데이터셋을 불러와 훈련과 테스트셋으로 분리
- 사이킷런에서 제공하는 iris 데이터 호출
- 사이킷런의 model_selection 패키지에서 제공하는 train_test_split 메서드를 활용하여 훈련셋과 테스트셋으로 분리
# 3. SVM 모델 훈련 svm_model = svm.SVC(kernel='linear', C=1.0) svm_model.fit(X_train, y_train) # 4. 예측 predictions = svm_model.predict(X_test) # 5. 정확도 평가 score = metrics.accuracy_score(y_test, predictions) print('정확도: {:.2f}'.format(score)) |
훈련 데이터를 사용하여 SVM 분류기를 훈련
- 훈련된 모델을 사용하여 테스트 데이터에서 예측
- 테스트 데이터 (예측) 정확도 측정
정확도: 0.99 |
SVM은 선형 분류와 비선형 분류를 지원하는데, 비선형에 대한 커널은 선형으로 분류될 수 없는 데이터들 때문에 발생함.
- 비선형 문제를 해결하는 가장 기본적인 방법은 저차원 데이터를 고차원으로 보내는 것.
- 많은 수학적 계산이 필요하기 때문에 성능에 문제를 줄 수 있다.
위와같은 문제를 해결하고자 도입한것이 커널트릭
- 선형 모델을 위한 커널에는 선형 커널이 있고, 비선형을 위한 커널에는 가우시안 RBF 커널과 다항식 커널이 있음
- 가우시안 RBF 커널과 다항식 커널은 수학적 기교를 이용하는 것, 벡터 내적을 계산 후 고차원으로 보내는 방법으로 연산량을 줄임
선형 커널 : 선형으로 분류 가능한 데이터에 적용함
K(a,b) = a^T * b
선형 커널은 기본 커널 트릭으로 커널 트릭을 사용하지 않겠다는 의미와 일맥상통함
다항식 커널 : 실제로는 특성을 추가하지 않지만, 다항식 특성을 많이 추가한 것과 같은 결과를 얻을 수 있는 방법
- 실제로는 특성을 추가하지 않지만, 엄청난 수의 특성 조합이 생기는 것과 같은 효과를 얻기 때문에 고차원으로 데이터 매핑이 가능
K(a,b) = (r a^T * b)^d
- a,b : 입력 벡터
- r : 감마
- d : 차원, 이때 r, d는 하이퍼파라미터
가우시안 RBT 커널 : 다항식 커널의 확장, 입력 벡터를 차원이 무한한 고차원으로 매핑하는 것, 모든 차수의 모든 다항식을 고려, 다항식 커널은 차수에 한계가 존재하는데 가우시안 RBF는 차수에 제한 없이 무한한 확장이 가능하다.
K(a,b) = exp(-r절대값(a-b)^2) -> 이때 r는 하이퍼파라미터
결정 트리
- 결정트리는 데이터를 분류하거나 결과값을 예측하는 분석 방법
- 결과 모델이 트리 구조이기 때문에 결정 트리라고 한다.
- 결정 트리는 데이터를 1차로 분류한 후 영역의 순도는 증가하고, 불순도와 불확실성은 감소하는 방향으로 학습 진행
- 순도가 증가하고 불확실성이 감소하는 것을 정보 이론에서는 정보 획득 이라고 하며, 순도를 계산하는 방법에서는 엔트로피와 지니 계수를 활용한다.
엔트로피
- 확률 변수의 불확실성을 수치로 나타낸 것으로, 엔트로피가 높을 수록 불확실성이 높다는 의미
지니 계수
- 불순도를 측정하는 지표
- 데이터의 통계적 분산 정도를 정량화해서 표현한 값
- 지니 계수는 원소 n개 중에서 임의로 두 개를 추출했을 때, 추출된 두 개가 서로 다른 그룹에 속해 있을 확률
- 지니 계수가 높을수록 데이터가 분산되어 있음을 의미
- 지니 계수는 엔트로피와 달리 로그를 계산할 필요가 없어 계산이 빠르기 때문에 결정 트리에서 많이 사용
의사결정트리 예시
import pandas as pd df = pd.read_csv('train.csv', index_col='PassengerId') print(df.head()) |
Saving train.csv to train.csv Survived Pclass ... Cabin Embarked PassengerId ... 1 0 3 ... NaN S 2 1 1 ... C85 C 3 1 3 ... NaN S 4 1 1 ... C123 S 5 0 3 ... NaN S [5 rows x 11 columns] |
df = df[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Survived']] df['Sex'] = df['Sex'].map({'male': 0, 'female': 1}) df = df.dropna() X = df.drop('Survived', axis=1) y = df['Survived'] |
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1) |
from sklearn import tree model = tree.DecisionTreeClassifier() |
model.fit(X_train, y_train) |
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini', max_depth=None, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort='deprecated', random_state=None, splitter='best') |
y_predict = model.predict(X_test) from sklearn.metrics import accuracy_score accuracy_score(y_test, y_predict) |
0.8212290502793296 |
from sklearn.metrics import confusion_matrix pd.DataFrame( confusion_matrix(y_test, y_predict), columns=['Predicted Not Survival', 'Predicted Survival'], index=['True Not Survival', 'True Survival'] ) |
Predicted Not Survival | Predicted Survival | |
True Not Survival | 97 | 15 |
True Survival | 17 | 50 |
'ML' 카테고리의 다른 글
로지스틱 회귀 모델 (1) | 2024.07.04 |
---|---|
비지도 학습 (0) | 2024.07.04 |
강화학습 1 (0) | 2024.05.29 |