AI 부트캠프 - 11일차

Cookie Baking·2024년 10월 16일

AI 부트 캠프 TIL

목록 보기
10/42

지도 학습 모델 학습

1. SVM

SVM이란

  • 서포트 벡터 머신은 분류와 회귀 분석에 사용되는 강력한 지도학습 모델이다.
  • 데이터를 분류하기 위해 결정 경계를 찾아 분류한다.
  • 초평면은 두 클래스 사이의 최대 마진을 보장하는 방식으로 선택함
  • 목표는 마진을 최대화하면서 결정 초평면을 찾아 데이터 포인트를 정확하게 분류하는 것이다.
  • 이는 일반화 성능을 높이는 데 도움을 줌
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 1. 데이터 로드
data = load_breast_cancer()
X = data.data
y = data.target

# 2. 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 3. 데이터 스케일링
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 4. 모델 생성 및 학습
model = SVC(kernel='linear')
model.fit(X_train, y_train)

# 5. 예측
y_pred = model.predict(X_test)

# 6. 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

2. KNN

KNN이란

  • 새로운 데이터 포인트를 기존 데이터 포인트 중 가장 가까운 k개의 이웃과 비교하여 분류함
  • 데이터 포인트의 특성을 기준으로 거리 계산을 통해 가장 가까운 이웃을 찾음
  • k 값을 얼마를 할당하는지가 관건이겠음
  • KNN의 목표는 학습 데이터를 기반으로 새로운 데이터 포인트의 클래스를 예측하는 것임
# 모델 생성 및 학습
model = KNeighborsClassifier(n_neighbors=5)
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

3. 나이브베이즈

나이브레이즈란

  • 주어진 데이터 포인트가 특정 클래스에 속할 확률을 계산하여 분류하는 것을 말함
  • 단순하고 계산이 효율적이며, 텍스트 분류와 같은 문제에서 좋은 성능을 발휘함
  • 가우시안 나이브베이즈 : 특징들이 연속적이고 정규 분포를 따른다고 가정
  • 베르누아 나이브베이즈 : 특징들이 이진수로 표현되는 경우 사용
  • 멀티노미얼 나이브베이즈 : 특징들이 다항 분포를 따르는 경우 사용
  • 많은 경우 정규 분포를 따른다고 가정하는 가우시안 나이브베이즈 사용
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 모델 생성 및 학습
model = GaussianNB()
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

4. 의사결정나무

의사결정나무란

  • 의사결정나무는 예측 모델 중 하나로 데이터의 특징을 기준으로 의사결정 규칙을 만들고 이를 바탕으로 데이터를 분류하거나 화귀하는 데 사용됨
  • 의사결정나무는 트리 구조를 가지며, 각 내부 노드는 데이터의 특정 특징에 대한 테스트를 나타내고, 각 가지는 테스트 결과를 나타내며, 각 리프 노드는 클래스 레이블을 나타냄
  • 불확실성이 낮아지도록 규칙을 만드는 것이 목적임
  • 단 불확실성이 더 나아지지 않을 곳까지 분할하는 것이 목적 (정보 이득)
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# 모델 생성 및 학습
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)

# 예측
y_pred = model.predict(X_test)

# 평가
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")

비지도학습 모델 (정답이 없음)

  • 유사한 데이터를 잘 묶는 것이 중요하겠음
  • 개냐 고양이냐 판별하는 모델 학습
  • skikit-learn 사용 X

1. K-means clustering 알고리즘

    1. 초기화 : k개의 군집 중심을 랜덤하게 설정
    1. 할당 단계 : 각 데이터 포인트를 가장 가까운 군집 중심에 할당함
    1. 업데이트 단계 : 각 군집의 중심을 해당 군집에 속한 데이터 포인드들의 평균으로 업데이트함
    1. 반복 : 할당 단계와 업데이트 단계를 군집 중심이 더이상 변화하지 않을 때까지 반복함
  • 세밀한 측정을 하고 싶다면 거리 측정 방법을 유클리드가 아닌 다른 방법을 사용해 볼 것
  • 최적의 k(군집의 수)를 찾는 방법은 엘보우 방법을 사용하는 것이다. 즉 k를 증가시키면서 각 k에 대한 군집의 응집도를 계산하고, 이를 그래프로 나타내어 그래프에서 응집도가 급격히 감소하는 지점을 찾는 것이다. (더 이상 의미있게 감소하지 않는 구간을 찾는 것이 목적)
  • 다만 군집의 중심을 각 그룹마다 찾아야 한다는 단점이 있다.
  • 검색이나 데이터 쿼리를 걸 때 해당 알고리즘을 사용함
  • 즉 저 k가 관건인 알고리즘이다.
inertia = []

K = range(1, 11)

# 엘보우 방법으로 K 설정
for k in K:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(data_scaled)
    inertia.append(kmeans.inertia_)

plt.figure(figsize=(10, 8))
plt.plot(K, inertia, 'bx-')
plt.xlabel('k')
plt.ylabel('Interia')
plt.title('Elbow Method For Optimal k')
plt.show()

kmeans = KMeans(n_clusters=5, random_state=42)
kmeans.fit(data_scaled)

data['Cluster'] = kmeans.labels_

# 군집화를 진행하는데 조합을 어떻게 하느냐가 관건이 되겠음
plt.figure(figsize=(10, 8))
sns.scatterplot(x=data['Age'], y=data['Annual Income (k$)'], hue=data['Cluster'], palette='viridis')
plt.show()

계층적 군집화 알고리즘

  • 계층적 군집화는 데이터포인트를 계층 구조로 그룹화하는 방법을 말함
  • 데이터 포인트를 점진적으로 병합하거나 분할하여 군집을 형성함

병합 군집화

병합 군집화는 각 데이터 포인트를 개별 군집으로 시작하여, 가장 가까운 군집을 반복적으로 병합함

  • 단순성 : 구현이 비교적 간단
  • 계산 비용 : 데이터 포인트 수가 많아질수록 계산 비용이 증가함
  • 덴드로그램 : 군집화 과정을 시각화한 덴드로그램을 생성할 수 있음

분할 군집화

분할 군집화는 모든 데이터 포인트를 하나의 군집으로 시작하여, 반복적으로 가장 멀리 떨어진 군집을 분할함

  • 상대적으로 복잡함 : 병합 군집화보다 구현이 상대적으로 복잡함
  • 효율성 : 큰 데이터셋에서 병합 군집화보다 요율적임
  • 덴드로그램 : 군집화 과정을 시각화한 뎅드로그램을 생성할 수 있음
# 데이터셋 불러오기
# 데이터 확인 (df.head())
# 필요한 열만 선택 (1차적 군집화 : 산점도 그래프를 계속해서 그려가며 최적의 조합을 찾는다.)

# 계층적 군집화 모델 생성
# n_clusers의 값은 군집의 수를 말함
hc = AgglomerativeClustering(n_clusters=5, metric='euclidean', linkage='ward')

# 모델 학습 및 예측
y_hc = hc.fit_predict(X_scaled)

# 결과 시각화
plt.figure(figsize=(10, 7))
plt.scatter(X_scaled[y_hc == 0, 0], X_scaled[y_hc == 0, 1], s=100, c='red', label='Cluster 1')
plt.scatter(X_scaled[y_hc == 1, 0], X_scaled[y_hc == 1, 1], s=100, c='blue', label='Cluster 2')
plt.scatter(X_scaled[y_hc == 2, 0], X_scaled[y_hc == 2, 1], s=100, c='green', label='Cluster 3')
plt.scatter(X_scaled[y_hc == 3, 0], X_scaled[y_hc == 3, 1], s=100, c='cyan', label='Cluster 4')
plt.scatter(X_scaled[y_hc == 4, 0], X_scaled[y_hc == 4, 1], s=100, c='magenta', label='Cluster 5')
plt.title('Clusters of customers')
plt.xlabel('Age')
plt.ylabel('Annual Income (k$)')
plt.legend()
plt.show()


# 모델 평가
from sklearn.metrics import silhouette_score

# 실루엣 점수 계산
silhouette_avg = silhouette_score(X_scaled, y_hc)
print(f'Silhouette Score: {silhouette_avg}')

DBSCAN

  • DBSCAN은 밀도 기반 군집화 알고리즘임
  • DBSCAN은 데이터 밀도가 높은 영역을 군집으로 간주하고, 밀도가 낮은 영역은 노이즈로 처리함
  • 밀도를 기반으로 한 알고리즘이기 때문에 특화된 군집을 찾을 수 있다는 장점이 있는 알고리즘임
  • 단 밀도가 낮을 경우에는 찾기 어렵다는 단점이 있는 알고리즘임
  • 원형 경계를 찾지 않아도 된다는 장점이 있는 알고리즘
  • 가장 먼저 거리를 설정해야 함
  • Core을 선택해야 함
  • Core가 되지 못하는 것들은 경계라고 함
  • Core도, 경계도 아닌 것을 노이즈라고 함

작동원리
1. 임의의 데이터 포인트를 선택
2. 선택한 데이터 포인트의 eps 반경 내에 있는 모든 데이터 포인트를 찾음
3. eps 반경 내의 데이터 수 >= min_samples : 해당 데이터 포인트를 중심으로 새로운 군집 형성
4. eps 반경 내의 데이터 수 < min_samples : 해당 데이터 포인트를 노이즈로 간주
5. 군집에 속한 데이터 포인트에 대해 2~4 단계를 반복
6. 모든 데이터 포인트가 처리될 때까지 이 과정을 반복

from sklearn.cluster import DBSCAN
import matplotlib.pyplot as plt
import seaborn as sns

# DBSCAN 모델 생성
dbscan = DBSCAN(eps=5, min_samples=5)

# 모델 학습 및 예측
df['Cluster'] = dbscan.fit_predict(X)

# 군집화 결과 시각화
plt.figure(figsize=(10, 7))
sns.scatterplot(x='Annual Income (k$)', y='Spending Score (1-100)', hue='Cluster', data=df, palette='viridis')
plt.title('DBSCAN Clustering of Mall Customers')
plt.show()

# 다양한 eps와 min_samples 값 시도
eps_values = [3, 5, 7, 10]
min_samples_values = [3, 5, 7, 10]

for eps in eps_values:
    for min_samples in min_samples_values:
        dbscan = DBSCAN(eps=eps, min_samples=min_samples)
        df['Cluster'] = dbscan.fit_predict(X)
        
        plt.figure(figsize=(10, 7))
        sns.scatterplot(x='Annual Income (k$)', y='Spending Score (1-100)', hue='Cluster', data=df, palette='viridis')
        plt.title(f'DBSCAN Clustering (eps={eps}, min_samples={min_samples})')
        plt.show()

차원 축소 - PCA

  • 차원이 낮을수록 연산이 줄어들기 때문에 더 효율적이게 되겠음
  • PCA는 데이터의 분산을 최대한 보존하면서, 데이터의 주요 특징을 추출해 저차원 공간으로 변환하는 것을 말함
from sklearn.datasets import fetch_openml
import pandas as pd

# MNIST 데이터셋 불러오기
mnist = fetch_openml('mnist_784', version=1)

# 데이터와 레이블 분리
X = mnist.data
y = mnist.target

# 데이터 프레임의 첫 5행 출력
print(X.head())
print(y.head())

from sklearn.preprocessing import StandardScaler

# 데이터 표준화
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

from sklearn.decomposition import PCA

# PCA 모델 생성
pca = PCA(n_components=0.95)  # 전체 분산의 95%를 설명하는 주성분 선택

# PCA 학습 및 변환
X_pca = pca.fit_transform(X_scaled)

# 변환된 데이터의 크기 확인
print(X_pca.shape)

# 선택된 주성분의 수
print(f'선택된 주성분의 수: {pca.n_components_}')

# 각 주성분이 설명하는 분산 비율
print(f'각 주성분이 설명하는 분산 비율: {pca.explained_variance_ratio_}')

# 누적 분산 비율
print(f'누적 분산 비율: {pca.explained_variance_ratio_.cumsum()}')

import matplotlib.pyplot as plt
import seaborn as sns

# 2차원 시각화
plt.figure(figsize=(10, 7))
sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=y, palette='viridis', legend=None)
plt.title('PCA of MNIST Dataset (2D)')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

차원축소 - t-SNE

  • 데이터가 배치된 것을 보고 확률을 계산한 후 낮은 차원에서 유사하게 배치함
  • 핵심은 고차원에서 데이터 배치랑 저차원에서의 배치를 유사하게 배치한다는 것임
  • 장점 : 비선형 기반을 탐지할 수 있으며 데이터 구조를 파악할 수 있음, 다양한 유형에 적용 가능
  • 단점 : 계산 비용이 많이 듦
# 데이터 셋 불러오기
# 데이터와 레이블 분리
# 데이터 표준화 

from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
import seaborn as sns

# t-SNE 모델 생성
tsne = TSNE(n_components=2, random_state=42)

# t-SNE 학습 및 변환
X_tsne = tsne.fit_transform(X_scaled)

# 변환된 데이터의 크기 확인
print(X_tsne.shape)

차원축소 - LDA

  • 차원축소와 분류를 동시에 수행함
  • 데이터의 클래스 간 분산을 최대화하고, 클래스 내 분산을 최소화하는 방향으로 데이터를 변환함, 해당하는 변환 행렬을 찾는 것이 최대 목표임
  • 데이터의 분류 성능을 향상시키고, 저차원 공간에서 데이터의 구조를 시각화할 수 있음
  • 클래스가 최대로 분리되는 기준을 찾는 것이 목적
  • 단점 : 선형 변환을 하기 때문에 성능이 떨어질 수도 있음

# 데이터 로드
# 데이터와 레이블 분리
# 데이터 표준화

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# LDA 모델 생성
lda = LinearDiscriminantAnalysis(n_components=9)  # 클래스의 수 - 1 만큼의 선형 판별 축 선택

# LDA 학습 및 변환
X_lda = lda.fit_transform(X_scaled, y)

# 변환된 데이터의 크기 확인
print(X_lda.shape)


import matplotlib.pyplot as plt
import seaborn as sns

# 2차원 시각화
plt.figure(figsize=(10, 7))
sns.scatterplot(x=X_lda[:, 0], y=X_lda[:, 1], hue=y, palette='viridis', legend=None)
plt.title('LDA of MNIST Dataset (2D)')
plt.xlabel('LDA Component 1')
plt.ylabel('LDA Component 2')
plt.show()

앙상블 학습

배깅과 부스팅

배깅 (다수결 원리)

  • 배깅은 여러 개의 학습 모델을 병렬로 학습시키고, 그 예측 결과를 평균 또는 다수결로 결합하는 앙상블 기법임
  • 데이터의 샘플링 과정에서 부트스트래핑 기법을 사용하여, 원본 데이터셋에서 중복을 허용한 무작위 샘플을 생성함
  • 각 모델은 서로 다른 데이터 샘플을 학습하게 되어, 모델 간의 상관성을 줄이고 예측 성능을 향상시킴
  • 장점 : 과적합이 감소되며, 안정성이 향상되고 병렬 처리가 가능해짐

부스팅 (약한 학습기를 결합한 강한 학습기)

  • 부스팅은 여러 개의 약한 학습기를 순차적으로 학습시키고, 그 예측 결과를 결합하여 강한 학습기를 만드는 앙상블 기법임
  • 이전 모델이 잘못 예측한 데이터 포인트에 가중치를 부여하여 다음 모델이 이를 더 잘 학습하도록 함
  • 장점 : 높은 예측 성능, 과적합 방지, 순차적 학습 (이전 모델의 오류를 보완하는 방식임)
# 데이터 로드
# 데이터 분할
# 데이터 스케일링

# 배깅 모델 생성
bagging_model = BaggingRegressor(estimator=DecisionTreeRegressor(), n_estimators=100, random_state=42)

# 모델 학습
bagging_model.fit(X_train_scaled, y_train)

# 예측
y_pred_bagging = bagging_model.predict(X_test_scaled)

# 평가
mse_bagging = mean_squared_error(y_test, y_pred_bagging)
print(f'배깅 모델의 MSE: {mse_bagging}')

from sklearn.ensemble import GradientBoostingRegressor

# 부스팅 모델 생성
boosting_model = GradientBoostingRegressor(n_estimators=100, random_state=42)

# 모델 학습
boosting_model.fit(X_train_scaled, y_train)

# 예측
y_pred_boosting = boosting_model.predict(X_test_scaled)

# 평가
mse_boosting = mean_squared_error(y_test, y_pred_boosting)
print(f'부스팅 모델의 MSE: {mse_boosting}')

랜덤 포레스트

  • 배깅을 기본으로 한 앙상블 학습 모델
  • 여러 개의 결정 트리를 학습시키고, 그 예측 결과를 결합하여 최종 예측을 수행함

원리

  • 부트스트랩 샘플링 : 원본 데이터 셋에서 중복을 허용한 무작위 샘플을 생성함
  • 결정 트리 학습 : 각 부트스트랩 샘플을 사용하여 결정 트리를 학습시킴, 이때 각 노드에서 무작위로 선택된 특성의 일부만을 사용하여 분할을 수행함
  • 예측 결합 : 모든 결정 트리의 예측 결과를 결합하여 최종 예측을 수행함
    회귀 문제에서는 평균을 사용하고, 분류 문제에서는 다수결을 사용함
  • 각 트리가 약한 학습기에 해당하기 때문에 과적합이 방지된다는 특징이 있음

그래디언트

  • 여러 개의 약한 학습기를 순차적으로 학습시키고, 그 예측 결과를 결합하여 강한 학습기를 만드는 기법을 말함

  • 오류를 보완해 학습되는 것으로 구성됨 (잔여 오차를 줄여나가는 식으로)

  • 모델 생성 시 max_depth를 너무 크게 쓰면 오히려 안 좋을 수도

  • 의미를 보려면 복잡한 데이터를 가져와 실험해볼 것

# 데이터 로드
# 데이터 분할
# 데이터 스케일링

from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error

# GBM 모델 생성
gbm_model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

# 모델 학습
gbm_model.fit(X_train_scaled, y_train)

# 예측
y_pred_gbm = gbm_model.predict(X_test_scaled)

# 평가
mse_gbm = mean_squared_error(y_test, y_pred_gbm)
print(f'GBM 모델의 MSE: {mse_gbm}')

XGBoost

  • 만능의 머신러닝 모델
  • 잔여 오차가 작아질 때까지 예측하는 결정 트리를 학습시켜 반복하는 원리
  • 각 트리의 예측 결과를 가중합하여 최종 예측을 수행
  • 장점 : 병렬처리, 조기 종료, 정규화, 유연성
  • 가장 깊게 공부할 필요성이 있음
# 데이터 로드
# 데이터 분할
# 데이터 스케일링

import xgboost as xgb
from sklearn.metrics import mean_squared_error

# XGBoost 모델 생성
xgb_model = xgb.XGBRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

# 모델 학습
xgb_model.fit(X_train_scaled, y_train)

# 예측
y_pred_xgb = xgb_model.predict(X_test_scaled)

# 평가
mse_xgb = mean_squared_error(y_test, y_pred_xgb)
print(f'XGBoost 모델의 MSE: {mse_xgb}')

커널함수란? 더 높은 차원으로 분석하는 것을 말함

ex. 1차원 분석했던 몸무게를 -> 2차원 분석으로 세분화된 분리 / 분석을 가능하게 함

배이즈 정리란 ? 새로운 정보가 주어졌을 때, 어떤 사건이 일어날 확률을 업데이트하는 데 사용됨

덴드로그램이란 ? 군집 분석에서 사용되는 트리 모양의 도표로, 데이터를 계층적으로 묶는 과정을 시각적으로 표현합니다. 계층적 군집화 방법을 사용할 때 각 데이터가 어느 클러스터에 속하는지, 클러스터들이 어떤 순서로 병합되거나 분리되는지를 나타냄

공분산이란 ? 두 변수 간의 관계를 나타내는 통계적 수치로, 두 변수가 함께 어떻게 변하는지를 측정합니다. 양의 공분산은 두 변수가 함께 증가하거나 감소하는 경향이 있음을, 음의 공분산은 한 변수가 증가할 때 다른 변수가 감소하는 경향이 있음을 의미

주성분 선택이란 ? 데이터를 설명하는 데 가장 중요한 차원(주성분)을 선택하는 방법입니다. 데이터의 분산을 최대한 보존하면서 차원을 축소해, 중요한 정보를 잃지 않으면서 데이터의 복잡도를 줄임

t분포란 ? 표본 크기가 작거나 모집단의 분산을 모를 때 사용하는 확률 분포

정규분포와 비슷하지만, 꼬리가 더 두꺼워서 작은 표본에서도 안정적인 추론을 할 수 있음

0개의 댓글