Artificial Intelligence/Studying

[๋จธ์‹ ๋Ÿฌ๋‹ ๊ต๊ณผ์„œ] Ch02 ๊ฐ์ฒด์ง€ํ–ฅ ํผ์…‰ํŠธ๋ก  API ๋ถ„์„

geum 2020. 9. 20. 16:38
'''
ํผ์…‰ํŠธ๋ก  ์ธํ„ฐํŽ˜์ด์Šค ๊ฐ€์ง„ ํŒŒ์ด์ฌ ํด๋ž˜์Šค ์ •์˜

1. Perceptron ๊ฐ์ฒด ์ดˆ๊ธฐํ™” ํ›„ fit ๋ฉ”์„œ๋“œ๋กœ ๋ฐ์ดํ„ฐ์—์„œ ํ•™์Šต
2. ๋ณ„๋„์˜ predict ๋ฉ”์„œ๋“œ๋กœ ์˜ˆ์ธก ์ƒ์„ฑ

cf. ๊ฐ์ฒด ์ดˆ๊ธฐํ™” ๊ณผ์ •์—์„œ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜์—ฌ ๋งŒ๋“  ์†์„ฑ์€ _ ์ถ”๊ฐ€
'''

import numpy as np

class Perceptron(object):
    '''ํผ์…‰ํŠธ๋ก  ๋ถ„๋ฅ˜๊ธฐ

    --------------
    ๋งค๊ฐœ๋ณ€์ˆ˜
    --------------
    eta : float
    -> ํ•™์Šต๋ฅ (0.0๊ณผ 1.0 ์‚ฌ์ด)

    n_iter : int
    -> ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์…‹ ๋ฐ˜๋ณต ํšŸ์ˆ˜

    random_state : int
    -> ๊ฐ€์ค‘์น˜ ๋ฌด์ž‘์œ„ ์ดˆ๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ ์‹œ๋“œ


    --------------
    ์†์„ฑ
    --------------
    w_ : 1d-array
    -> ํ•™์Šต๋œ ๊ฐ€์ค‘์น˜

    errors_ : list
    -> ์—ํฌํฌ๋งˆ๋‹ค ๋ˆ„์ ๋œ ๋ถ„๋ฅ˜ ์˜ค๋ฅ˜

    '''

    def __init__(self, eta=0.01, n_iter=50, random_state=1):
        self.eta = eta
        self.n_iter = n_iter
        self.random_state = random_state

    def fit(self, X, y):
        '''ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ ํ•™์Šต

        --------------
        ๋งค๊ฐœ๋ณ€์ˆ˜
        --------------
        X : {array-like}, shape = [n_samples, n_features]
        -> n_samples๊ฐœ์˜ ์ƒ˜ํ”Œ๊ณผ n_features๊ฐœ์˜ ํŠน์„ฑ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ

        Y : array-like, shape = [n_samples]
        -> ํƒ€๊ฒŸ ๊ฐ’


        --------------
        ๋ฐ˜ํ™˜๊ฐ’
        --------------
        self : object
        '''

        # numpy random number genarator
        rgen = np.random.RandomState(self.random_state)

        # rgen.normal(~) ์ด์šฉํ•˜์—ฌ ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ 0.01์ธ ์ •๊ทœ ๋ถ„ํฌ์—์„œ ๋ฝ‘์€ ๋žœ๋คํ•œ ์ž‘์€ ์ˆ˜ ์ €์žฅ
        self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])

        self.errors_ = []

        '''
        fit ๋ฉ”์„œ๋“œ๋Š” 

        1. ๊ฐ€์ค‘์น˜ ์ดˆ๊ธฐํ™” ํ›„ ํ›ˆ๋ จ ์„ธํŠธ์— ์žˆ๋Š” ๋ชจ๋“  ์ƒ˜ํ”Œ์„ ๋ฐ˜๋ณต ์ˆœํšŒํ•˜๋ฉฐ ํผ์…‰ํŠธ๋ก  ํ•™์Šต ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฐ€์ค‘์น˜ ์—…๋ฐ์ดํŠธ
        2. ๊ฐ€์ค‘์น˜ ์—…๋ฐ์ดํŠธ ์œ„ํ•ด predict ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜์—ฌ ํด๋ž˜์Šค ๋ ˆ์ด๋ธ”์— ๋Œ€ํ•œ ์˜ˆ์ธก ์–ป์Œ
        '''
        for _ in range(self.n_iter):
            errors = 0

            for xi, target in zip(X, y):
                update = self.eta * (target - self.predict(xi))
                self.w_[1:] += update * xi
                self.w_[0] += update
                errors += int(update != 0.0)

            self.errors_.append(errors)

        return self

    def net_input(self, X):
        # ์ตœ์ข… ์ž…๋ ฅ ๊ณ„์‚ฐ
        return np.dot(X, self.w_[1:])+self.w_[0]

    def predict(self, X):
        # ๋‹จ์œ„ ๊ณ„๋‹จ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ๋ ˆ์ด๋ธ” ๋ฐ˜ํ™˜
        return np.where(self.net_input(X) >= 0.0, 1, -1)

 

* self.w_ ๊ฐ€์ค‘์น˜๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š๋Š” ์ด์œ ?

๊ฐ€์ค‘์น˜๊ฐ€ 0์ด ์•„๋‹ˆ์–ด์•ผ ํ•™์Šต๋ฅ  eta๊ฐ€ ๋ถ„๋ฅ˜ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์คŒ. ๊ฐ€์ค‘์น˜๊ฐ€ 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜์–ด ์žˆ๋‹ค๋ฉด eta๋Š” ๊ฐ€์ค‘์น˜ ๋ฒกํ„ฐ์˜ ํฌ๊ธฐ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์นจ.