본문 바로가기

프로그래머스 데브 코스/TIL

[6기] 프로그래머스 인공지능 데브코스 32일차 TIL

1002

Do it! 정직하게 코딩하며 배우는 딥러닝 입문

위 도서 참고하여 코랩에서 딥러닝 실습하기

코드 간단하게만 정리 22
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_breast_cancer   # 사이킷런에서 제공하는 유방암 데이터셋 이용하기
cancer = load_breast_cancer()

print(cancer.data.shape, cancer.target.shape)   # 데이터셋의 입력값과 출력값 모양 확인
cancer.data[:3]   # 데이터셋 확인

plt.boxplot(cancer.data)   # 데이터셋 박스그래프로 분산 확인하기
plt.xlabel('feature')
plt.ylabel('value')
plt.show()

cancer.feature_names[[3, 13, 23]]   # 유독 분산 폭이 넓은 데이터 어떤 유형인지 확인
# array(['mean area', 'area error', 'worst area'], dtype='<U23')
# 유독 폭이 넓은 애들은 부피 관련된 데이터임을 알 수 있음

x = cancer.data
y = cancer.target

from sklearn.model_selection import train_test_split   # 사이킷런에서 사용할 수 있는 훈련 데이터/테스트 데이터 분류 기능

x_train, x_test, y_train, y_test = train_test_split(x, y, stratify = y, test_size = 0.2, random_state = 42)
# stratify로 훈련 데이터 나눌 때 클래스 비율 동일하게 만듦
# test_size로 테스트 데이터 양 지정하기
# random_state로 데이터 세트 무작위로 섞어 나눌 때 난수 초깃값 42로 지정

class LogisticNeuron:
  def __init__(self):
    self.w = None
    self.b = None

  def forpass(self, x):
    z = np.sum(x * self.w) + self.b
    return z

  def backprop(self, x, err):
    w_grad = x * err
    b_grad = 1 * err
    return w_grad, b_grad

  def activation(self, z):
    z = np.clip(z, -100, None)
    a = 1 / (1 + np.exp(-z))
    return a

  def fit(self, x, y, epochs=100):
    self.w = np.ones(x.shape[1])
    self.b = 0
    for i in range(epochs):
      for x_i, y_i in zip(x, y):
        z = self.forpass(x_i)
        a = self.activation(z)
        err = -(y_i - a)
        w_grad, b_grad = self.backprop(x_i, err)
        self.w -= w_grad
        self.b -= b_grad

  def predict(self, x):
    z = [self.forpass(x_i) for x_i in x]
    a = self.activation(np.array(z))
    return a > 0.5

neuron = LogisticNeuron()
neuron.fit(x_train, y_train)

np.mean(neuron.predict(x_test) == y_test)
# 0.8245614035087719

class SingleLayer:
  def __init__(self):
    self.w = None
    self.b = None
    self.losses = []

  def forpass(self, x):
    z = np.sum(x * self.w) + self.b
    return z

  def backprop(self, x, err):
    w_grad = x * err
    b_grad = 1 * err
    return w_grad, b_grad

  def activation(self, z):
    z = np.clip(z, -100, None)
    a = 1 / (1 + np.exp(-z))
    return a

  def fit(self, x, y, epochs=100):
    self.w = np.ones(x.shape[1])
    self.b = 0
    for i in range(epochs):
      loss = 0
      indexes = np.random.permutation(np.arange(len(x)))
      for i in indexes:
        z = self.forpass(x[i])
        a = self.activation(z)
        err = -(y[i] - a)
        w_grad, b_grad = self.backprop(x[i], err)
        self.w -= w_grad
        self.b -= b_grad
        a = np.clip(a, 1e-10, 1-1e-10)
        loss += -(y[i] * np.log(a) + (1 - y[i]) * np.log(1 - a))
      self.losses.append(loss/len(y))

  def predict(self, x):
    z = [self.forpass(x_i) for x_i in x]
    return np.array(z) > 0

  def score(self, x, y):
    return np.mean(self.predict(x) == y)

layer = SingleLayer()
layer.fit(x_train, y_train)
layer.score(x_test, y_test)
# 0.9298245614035088