대학공부/데이터과학

여러 가지 방법을 이용한 분류

진진리 2024. 4. 29. 17:16
728x90

1. k-최근접 이웃에 기반한 분류

  • k-Nearest Neighbor(k-최근접 이웃, k-NN)
    • 가장 가까운 이웃 k개를 바탕으로 분류를 수행하는 방법
    • 데이터가 주어질 때마다 연산을 통한 분류가 이루어지므로, 엄밀하게는 학습이라고 하기 어려움

 

  • Python에서의 k-NN
# 필수 라이브러리 불러오기
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix

# 지뢰와 보물 데이터 불러오기
df = pd.read_csv('treasure.csv')

# 주어진 데이터에서 입력 변수와 예측 변수를 분리
df_x = df[['horizontal', 'vertical']] # 입력 변수
df_y = df['MineOrTreasure'] # 예측 변수

# 데이터를 학습용과 검증용으로 분리
x_train, x_test, y_train, y_test = train_test_split(df_x, df_y, test_size = 0.3)

# 학습용 데이터를 바탕으로 k-NN 분류기 생성
kNN = KNeighborsClassifier(n_neighbors = 3, metric = 'euclidean')
kNN.fit(x_train, y_train)

# 만들어진 k-NN 분류기를 검증용 데이터를 적용
y_pred = kNN.predict(x_test)

# Confusion Matrix 출력하기
confusion_matrix(y_test, y_pred, labels = ['MINE', 'TREASURE'])
"""
array([[25,  1],
       [ 0, 34]])
""""

 

EXERCISE 1

  • 가정: 맛집은 맛집끼리 모여 있고, 평범한 음식점은 평범한 음식점끼리 모여 있다.
  • 지도 API를 활용해 음식점들의 좌표와 맛집 여부를 deli1.csv와 deli2.csv에 기록
  • k = 5일 때 k-NN 알고리즘을 이용하여 답하라

(1) deli1을 학습용으로, deli2를 검증용으로 활용할 때 Accuracy? 49/60

(2) k의 값이 5가 아니라 4일 경우의 문제점? k가 짝수인 경우에는 분류할 수 없는 상황이 발생할 수 있음


2. 사후확률과 Naive Bayes 분류

  • Naive Bayes
    • 사후확률을 계산하여 분류를 수행하는 방법
    • 각 독립변수가 확률적으로 상호 독립이라는 가정 하에 활용
  • 사후 확률(Posteriori Probability): 특정 사건 발생 후에 다른 사건이 발생할 확률을 의미
  • 사후 확률을 직접 얻기 쉽지 않음
    • P(승리할 확률 | 실책 O, 1선발 등판, 선취점 O, 홈런 X)
    • ∝ P(승리할 확률) * P(실책 O | 승리) * P(1선발 등판 | 승리) * P(선취점 | 승리) * P(홈런 X | 승리)
    • 마찬가지로 패배할 확률을 구해서 더 큰 쪽으로 분류

 

  1. 여러 개의 조건부확률들을 곱하는 과정에서 0이 등장한다면?
    • Leplacian Correction
      • 조건부확률의 분모와 분자에 동일한 값을 일괄적으로 더함
      • 사후확률 계산 과정에서 결과값이 0이 되는 것을 방지
  2. 변수들이 서로 독립이라는 가정 하에 동작하는데, 이러한 가정이 타당한가?
    • Naive Bayes는 비교적 간편한 식으로 빠르게 분류를 수행하는 대신, 실제로 성립하기 어려운 가정을 채택한다는 단점을 지님

 

  • Python에서 적용하기
# 필수 라이브러리 불러오기
import pandas as pd
from sklearn.naive_bayes import BernoulliNB

# 야구 경기 데이터 불러오기
df = pd.read_csv('baseball.csv')

# 주어진 데이터에서 입력 변수와 예측 변수를 분리
df_x = df[['error', 'pitcher', 'score', 'homerun']]
df_y = df['GameResult']

# 학습용 데이터를 바탕으로 NB 분류기 생성
NB = BernoulliNB(alpha = 0)
NB.fit(df_x, df_y)

# 만들어진 NB 분류기를 새로운 경기 데이터에 적용
x_test = pd.read_csv('ku_vs_monsters.csv')
y_pred = NB.predict(x_test)

 

  • 데이터의 형태가 달라진다면?
    • BernoulliNB: 입력 변수들이 모두 이진 형태인 경우에 활용
    • CategoricalNB: 입력 변수들이 범주형인 경우에 활용

EXERCISE 2

  • 전체 문자 중 스팸 문자는 60%
  • 스팸일 때 '베팅'이라는 낱말이 포함될 확률은 90%
  • 스팸이 아닐 때 '베팅'이라는 낱말이 포함될 확률은 20%

1. '베팅'이 포함된 (가)

P(스팸|(가)) = P(스팸) * P((가) | 스팸) = 0.6 * 0.9 = 0.54

P(햄|(가)) = P(햄) * P((가) | 햄) = 0.4 * 0.2 =0.08

-> (가)는 스팸

 

2. '베팅'이 포함되지 않은 (나)

P(스팸|(나)) = 0.6 * 0.1 = 0.06

P(햄|(나)) = 0.4 * 0.8 = 0.32

-> (나)는 햄


3. 로지스틱 회귀의 원리와 그 실제

  • 로지스틱 회귀로 범주에 대한 분류를 수행
    • 승산(Odds): (특정한 사건이 발생할 확률) / (특정한 사건이 발생하지 않을 확률) = p / (1-p)
    • 승산으로 정의하는 로지스틱 회귀
      • log(Odds) = w0 + w1x1 +w2x2 + w3x3 + ...
      • p/(1-p) = e^( w0 + w1x1 +w2x2 + w3x3 + ... )
      • p = 1 / (1 + e^-( w0 + w1x1 +w2x2 + w3x3 + ... ))
      • p의 범위: 0 < p < 1

 

  • sklearn을 이용한 로지스틱 회귀
# 데이터셋을 불로오고 독립 변수와 종속 변수를 구분
df = pd.read_csv('telecom_logistic.csv')

df_x = df.iloc[:, 0:7]
df_y = df.iloc[:, 7]

# 로지스틱 회귀 모형을 생성하고 계수를 출력
from sklearn.linear_model import LogisticRegression

LR = LogisticRegression()
LR.fit(df_x, df_y)

print(LR.coef_)
print(LR.intercept_)

  • log(Odds) = -4.53
  • p = 0.01
  • 즉, 이탈하지 않음