기본 콘텐츠로 건너뛰기

[ML] 결정트리(Decision Tree) 모델

[python]class에서 init, iter, generator 사용하기

클래스에서 init, iter, generator 사용

__init__()

클래스를 정의하면서 인수를 전달할 경우 __init__()메서드를 사용합니다.
이 메서드는 클래스에 인수를 전달하는 등 초기화를 위해 적용합니다.
    class Fib:
      ‘’’iterator that yields numbers in the Fibonacci sequence’’’①
      def __init__(self, maxnum):
        내용 ②
① 클래스에 대한 간략한 설명 즉, docstring 입니다.
② __init__() 메소드는 클래스 개체인 인스턴스를 생성하면서 호출됩니다. 즉, 인스턴스 생성시 첫번째로 실행되는 코드입니다.
이 메소드의 인수중 첫번째 인수는 self입니다. 이것은 새롭게 생성된 객체(인스턴스)를 참조하는 것으로 명시적으로 나타내어야 합니다.
초기화자는 단순히 인자 전달 외에 그 인자의 정성적인 측면의 정보를 제공할 수 있습니다.
    class Fib:
      '''iterator that yields numbers in the Fibonacci sequence'''
      def __init__(self, maxnum):
        if maxnum <0 :
          raise ValueError("maxnum은 양수이어야 합니다.")
    b=Fib(-10)
      ---------------------------------------------------------------------------
      ValueError Traceback (most recent call last)
      ...
      ---→ 5 raise ValueError("maxnum은 양수이어야 합니다.")
      ValueError: maxnum은 양수이어야 합니다.

Instance

클래스를 정의하자마자 같은 이름으로 새로운 클래스 객체를 생성할 수 있습니다. 이를 클래스 객체 즉, 인스턴스라고 합니다.
인스턴스는 다음과 같이 생성할 수 있습니다. 이 경우 인수는 생성자 __init__()에 명시한 인자들과 같습니다. 단, 인스턴스 생성시 self는 암묵적으로 호출되므로 명시하지 않아야 합니다.
객체이름 = 클래스이름(인자들)
    class Fib:
      '''피보나치 수열을 생성하기 위한 클래스'''
      def __init__(self, maxnum):
        self.maxnum = maxnum
      def re(self):
        mx=self.maxnum
        return (mx)

    fib=Fib(10)
    print(dir(fib), end=" ")
      ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'maxnum']
    fib.__class__
      __main__.Fib
    fib.__doc__
      '피보나치 수열을 생성하기 위한 클래스'
    fib=Fib(10)
      10
위 코드에서 fib 인스턴스를 생성하였습니다. 모든 클래스 인스턴스는 내장된(built-in) 속성을 가지며 dir() 함수에 의해 확인할 수 있습니다.
__class__속성은 인스턴스의 위치를 나타내며 __doc__는 클래스의 docstring을 반환합니다.
다음의 __init__()에 정의된 self.maxnum은 인스턴스 변수라고 합니다. 이 메소드에서 선언된 변수는 전역변수로서 인스턴스 내의 모든 메소드에서 사용됩니다. 그러므로 다음 생성한 메소드 re()에서 그 인스턴스 변수를 사용할 수 있습니다.
    fib.re()
      10

반복자 (Iterator)

위 클래스내에서 반복자를 생성합니다. 반복자는 클래스 내에서 __iter__() 메소드에 의해 정의됩니다.
인스턴스에서 매직메소드인 __iter__()은 자동적으로 for loop를 실행합니다. 그러나 이렇게 실행되는 for loop는 일반적인 반복문의 실행과는 약간의 차이를 가집니다. 즉, 일반적인 반복문의 경우 객체내의 모든 원소들을 생성한 후에 호출의 결과를 반환합니다. 그에 반해 iterator는 객체내의 각 원소가 실행되고 호출된 후 다른 원소가 실행되고 호출됩니다. 즉, 실행과 반환이 한 쌍으로 이루어집니다.
다음과 같이 작성할 수 있습니다.
    class Fib:
      '''피보나치 수열을 생성하기 위한 클래스'''
      def __init__(self, maxnum): ①
        self.maxnum = maxnum
      def __iter__(self): ②
        self.a=0
        self.b=1
        return(self)
      def __next__(self): ③
        re=self.a
        if re > self.maxnum:
          raise StopIteration
        self.a, self.b=self.b, self.a+self.b
        return(re)

    fib=Fib(10)
    for i in fib:
      print(i, end=" ")
      0 1 1 2 3 5 8
①, ②, ③은 모두 매직 메소드입니다. 그러므로 직접 호출할 수 없습니다.
대신에 위에서 소개한 것과 같이 인스턴스에서 반복자인 ②에 의해 for loop가 생성되며 ③에 의해 각 원소가 실행됩니다.
실행된 결과 호출을 위해서 yield() 함수를 사용할 수 있지만 이 경우는 __iter__ 대신에 for~loop문을 직접 사용하는 gnerator(생성자)에서만 사용할 수 있습니다. 위의 코드에서와 같이 yield ()대신에 return()을 사용합니다.
__iter__() 메소드에서 if 구문은 인수로 전달한 값보다 클경우 이 과정을 중지시키기 위해 StopIteration 식을 사용하였습니다. 이 식은 예외 발생이 아닌 정상적으로 인스턴스의 실행으로 중지시키는 것입니다.
반복자에 의한 결과의 반환은 위의 for loop 대신에 결과의 자료형을 확정함으로서 보다 직접적인 결과를 반환할 수 있습니다.
반복자나 생성자에 의한 결과는 실행단계에서 결과 객체의 원소들이 저장될 위치만을 확보한 상태로서 반환될 결과의 자료형이나 값이 결정되지 않은 상태입니다. 다시말하면 결과 객체의 각 원소를 호출할 때 참조주소에 위치한 값을 호출하는 것입니다.
이러한 과정을 확장하면 모든 결과 원소들로 구성된 객체의 자료형을 확정함으로서 전체를 반환할 수 있게 됩니다.
    list(x)
      [0, 1, 1, 2, 3, 5, 8]

발생자(generator)

fibonacci 수열을 생성하기 위해 generator를 사용하는 경우는 보다 간단합니다. 즉, iterator(반복자)인 __iter__() 메서드 대신 반복문을 직접적으로 사용할 수 있으므로 단일한 함수로 작성할 수 있습니다.
    def fibo_gen(maxnum):
      a, b=0, 1
      while a < maxnum:
        yield a
        a, b=b, a+b
생성자의 결과를 반환하기 위해 다양한 방법을 사용할 수 있습니다.
(1) 결과를 각 원소단위로 반환하기 위해 next()함수를 사용합니다. 이 경우 생성자가 함수의 형태로 작성된 경우 에도 객체의 모든 원소에 대한 참조를 확정하기 위해 인스턴스를 생성하여 사용합니다. next()를 사용할 경우 지정한 인수의 범위를 초과하면 자동적으로 예외를 발생시킵니다.
    x=fibo_gen(10)
    next(x)
      0
    next(x)
      1
    next(x)
      1
    next(x)
      2
    next(x)
      3
    next(x)
      5
    next(x)
      8
    next(x)
      StopIteration:
(2) for ~ loop 문을 사용하여 반환
    for i in fibo_gen(10):
      print(i, end=" ")
      0 1 1 2 3 5 8
(3) yield()에 의한 결과의 반환은 자료형이 확정되지 않은 상태입니다. 그러므로 반환 자료형을 확정시킨 상태를 실행합니다.
    list(fibo_gen(10))
      [0, 1, 1, 2, 3, 5, 8]
    tuple(fibo_gen(10))
      (0, 1, 1, 2, 3, 5, 8)

반복자 (Iterator)

위 클래스내에서 반복자를 생성합니다. 반복자는 클래스 내에서 __iter__() 메소드에 의해 정의됩니다.
인스턴스에서 매직메소드인 __iter__()은 자동적으로 for loop를 실행합니다. 그러나 이렇게 실행되는 for loop는 일반적인 반복문의 실행과는 약간의 차이를 가집니다. 즉, 일반적인 반복문의 경우 객체내의 모든 원소들을 생성한 후에 호출의 결과를 반환합니다. 그에 반해 iterator는 객체내의 각 원소가 실행되고 호출된 후 다른 원소가 실행되고 호출됩니다. 즉, 실행과 반환이 한 쌍으로 이루어집니다.
다음과 같이 작성할 수 있습니다.
    class Fib:
      '''피보나치 수열을 생성하기 위한 클래스'''
      def __init__(self, maxnum): ①
        self.maxnum = maxnum
      def __iter__(self): ②
        self.a=0
        self.b=1
        return(self)
      def __next__(self): ③
        re=self.a
        if re > self.maxnum:
          raise StopIteration
        self.a, self.b=self.b, self.a+self.b
        return(re)

    fib=Fib(10)
    for i in fib:
      print(i, end=" ")
      0 1 1 2 3 5 8
①, ②, ③은 모두 매직 메소드입니다. 그러므로 직접 호출할 수 없습니다.
대신에 위에서 소개한 것과 같이 인스턴스에서 반복자인 ②에 의해 for loop가 생성되며 ③에 의해 각 원소가 실행됩니다.
실행된 결과 호출을 위해서 yield() 함수를 사용할 수 있지만 이 경우는 __iter__ 대신에 for~loop문을 직접 사용하는 gnerator(생성자)에서만 사용할 수 있습니다. 위의 코드에서와 같이 yield ()대신에 return()을 사용합니다.
__iter__() 메소드에서 if 구문은 인수로 전달한 값보다 클경우 이 과정을 중지시키기 위해 StopIteration 식을 사용하였습니다. 이 식은 예외 발생이 아닌 정상적으로 인스턴스의 실행으로 중지시키는 것입니다.
반복자에 의한 결과의 반환은 위의 for loop 대신에 결과의 자료형을 확정함으로서 보다 직접적인 결과를 반환할 수 있습니다.
반복자나 생성자에 의한 결과는 실행단계에서 결과 객체의 원소들이 저장될 위치만을 확보한 상태로서 반환될 결과의 자료형이나 값이 결정되지 않은 상태입니다. 다시말하면 결과 객체의 각 원소를 호출할 때 참조주소에 위치한 값을 호출하는 것입니다.
이러한 과정을 확장하면 모든 결과 원소들로 구성된 객체의 자료형을 확정함으로서 전체를 반환할 수 있게 됩니다.
    list(x)
      [0, 1, 1, 2, 3, 5, 8]

발생자(generator)

fibonacci 수열을 생성하기 위해 generator를 사용하는 경우는 보다 간단합니다. 즉, iterator(반복자)인 __iter__() 메서드 대신 반복문을 직접적으로 사용할 수 있으므로 단일한 함수로 작성할 수 있습니다.
    def fibo_gen(maxnum):
      a, b=0, 1
      while a < maxnum:
        yield a
        a, b=b, a+b
생성자의 결과를 반환하기 위해 다양한 방법을 사용할 수 있습니다.
(1) 결과를 각 원소단위로 반환하기 위해 next()함수를 사용합니다. 이 경우 생성자가 함수의 형태로 작성된 경우 에도 객체의 모든 원소에 대한 참조를 확정하기 위해 인스턴스를 생성하여 사용합니다. next()를 사용할 경우 지정한 인수의 범위를 초과하면 자동적으로 예외를 발생시킵니다.
    x=fibo_gen(10) next(x)
      0
    next(x)
      1
    next(x)
      1
    next(x)
      2
    next(x)
      3
    next(x)
      5
    next(x)
      8
    next(x)
      ---------------------------------------------------------------------------
      StopIteration Traceback (most recent call last)
      in
        ----> 1 next(x)
        StopIteration:
(2) for ~ loop 문을 사용하여 반환
    for i in fibo_gen(10):
      print(i, end=" ")
      0 1 1 2 3 5 8
(3) yield()에 의한 결과의 반환은 자료형이 확정되지 않은 상태입니다. 그러므로 반환 자료형을 확정시킨 상태를 실행합니다.
    list(fibo_gen(10))
      [0, 1, 1, 2, 3, 5, 8]
    tuple(fibo_gen(10))
      (0, 1, 1, 2, 3, 5, 8)

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같

[matplotlib] 히스토그램(Histogram)

히스토그램(Histogram) 히스토그램은 확률분포의 그래픽적인 표현이며 막대그래프의 종류입니다. 이 그래프가 확률분포와 관계가 있으므로 통계적 요소를 나타내기 위해 많이 사용됩니다. plt.hist(X, bins=10)함수를 사용합니다. x=np.random.randn(1000) plt.hist(x, 10) plt.show() 위 그래프의 y축은 각 구간에 해당하는 갯수이다. 빈도수 대신 확률밀도를 나타내기 위해서는 위 함수의 매개변수 normed=True로 조정하여 나타낼 수 있다. 또한 매개변수 bins의 인수를 숫자로 전달할 수 있지만 리스트 객체로 지정할 수 있다. 막대그래프의 경우와 마찬가지로 각 막대의 폭은 매개변수 width에 의해 조정된다. y=np.linspace(min(x)-1, max(x)+1, 10) y array([-4.48810153, -3.54351935, -2.59893717, -1.65435499, -0.70977282, 0.23480936, 1.17939154, 2.12397372, 3.0685559 , 4.01313807]) plt.hist(x, y, normed=True) plt.show()

R 미분과 적분

내용 expression 미분 2차 미분 mosaic를 사용한 미분 적분 미분과 적분 R에서의 미분과 적분 함수는 expression()함수에 의해 생성된 표현식을 대상으로 합니다. expression expression(문자, 또는 식) 이 표현식의 평가는 eval() 함수에 의해 실행됩니다. > ex1<-expression(1+0:9) > ex1 expression(1 + 0:9) > eval(ex1) [1] 1 2 3 4 5 6 7 8 9 10 > ex2<-expression(u, 2, u+0:9) > ex2 expression(u, 2, u + 0:9) > ex2[1] expression(u) > ex2[2] expression(2) > ex2[3] expression(u + 0:9) > u<-0.9 > eval(ex2[3]) [1] 0.9 1.9 2.9 3.9 4.9 5.9 6.9 7.9 8.9 9.9 미분 D(표현식, 미분 변수) 함수로 미분을 실행합니다. 이 함수의 표현식은 expression() 함수로 생성된 객체이며 미분 변수는 다음 식의 분모의 변수를 의미합니다. $$\frac{d}{d \text{변수}}\text{표현식}$$ 이 함수는 어떤 함수의 미분의 결과를 표현식으로 반환합니다. > D(expression(2*x^3), "x") 2 * (3 * x^2) > eq<-expression(log(x)) > eq expression(log(x)) > D(eq, "x") 1/x > eq2<-expression(a/(1+b*exp(-d*x))); eq2 expression(a/(1 + b * exp(-d * x))) > D(eq2, "x") a * (b * (exp(-d * x) * d))/(1 + b