기본 콘텐츠로 건너뛰기

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

지수와 로그함수

내용

지수와 로그함수

지수함수(Exponential Function)

주어진 시간 동안 항상 자신의 크기에 비례하는 방식으로 증가하는 양을 생각해 봅시다. 이러한 증가는 일정한 금리로 돈에 대한 이자를 계산하는 과정으로 설명할 수 있습니다. 자본이 클수록 주어진 시간에 대한 이자의 증가액은 커집니다. 이러한 이자는 단순이자복리 이자로 구분됩니다. 전자의 경우 자본은 고정된 상태로 유지되고 후자의 경우 이자가 자본에 추가되므로 원금에 대한 증가율 역시 증가됩니다.

import numpy as np
import pandas as pd
from sympy import *
import matplotlib.pyplot as plt

단순이자(simple interest)

원금이 1000원이고 연 이자율을 10%로 가정합니다. 이 경우 증분은 매년 100원이 됩니다. 다음 10년 동안 계속하면 그 시간이 끝날 때까지 총액이 2000원으로 원금의 두 배가 될 것입니다. 연 이자율이 5% 였다면 재산을 두 배로 늘리려면 20년, 연이율이 2%라면 50년이 소요될 것입니다.

연간 이자가 r 이면 재산을 두 배로 늘리기 위한 기간은 식 1에 의해 결정할 수 있습니다.(등차수열)

$$\begin{align}\tag{1} y &= y_0(1 + Nr)\\ y_0&: 원금\\ r&: 연 이자율\\ N&: 보유기간(년) \end{align}$$

복리 이자(compound interest)

원금 1000원과 10%의 연 이자율을 가정합니다. 매년 이자를 원금에 합산한다고 하면 1년후 원금은 1100원이 2년 후에는 1100원에 10%이므로 12100원이 됩니다. 이와같이 10년간 증가는 다음과 같습니다.

re={0:1000}
for i in range(1, 11): 
    re[i]=round(re[i-1]+re[i-1]*0.1, 0) 
pd.DataFrame([re.keys(), re.values()], index=["year", "savings"]).T
year savings
0 0.0 1000.0
1 1.0 1100.0
2 2.0 1210.0
3 3.0 1331.0
4 4.0 1464.0
5 5.0 1610.0
6 6.0 1771.0
7 7.0 1948.0
8 8.0 2143.0
9 9.0 2357.0
10 10.0 2593.0

위 결과에 의하면 원금의 2배가 되는 기간은 단순이자의 경우보다 단축됩니다. 위 계산은 식 2와 같이 하나의 식으로 나타낼 수 있습니다.(등비수열)

$$\begin{align}\tag{2} & y = y_0(1 + \frac{r}{n})^{yr*n}\\ & y_0: 원금\\ & r: 복리 연이율\\ & n:연중 구간수\\ & yr: 보유기간(년) \end{align}$$

연 이자율 10%로 10년 후의 총액은 다음과 같습니다.

round(1000*(1+0.1)**10, 2)
2593.74

위에서 복리를 1년을 기준으로 계산을 하였는데 이 기간을 단축시켜 계산해봅니다. 예를 들어 1년을 10개의 구간으로 구분하면 1구간에서의 다음과 같이 계산되므로 이자율을 1%가 될 것입니다. 1000원의 원금에 10년 후의 금액은 다음과 같습니다.

$$\begin{align} & r_n = \frac{r}{n}\\ & r_n:\, 1구간의 이자율\\ & n: \, 1년 내의 구간수 \\ & r:\, 연 이자율 \end{align}$$
round(1000*(1+0.1/10)**100,2)
2704.81

위 계산과 같이 연내의 구간수의 변화에 따른 10년 후의 결과를 계산해 보면 다음과 같습니다.

re1={}
for i in range(1, 101):
    re1[i]=round(compound(0.1, i, 10), 3)
re1=pd.DataFrame([re1.keys(), re1.values()], index=["bins", "savings"]).T
plt.figure(dpi=100)
plt.plot(re1.iloc[:,0], re1.iloc[:,1])
plt.xlabel("bins", size=12, weight="bold")
plt.ylabel("savings", size=12, weight="bold")
plt.show()
그림 1

위 결과로부터 N의 증가에 의해 값 역시 증가 되지만 그 증가 차이는 감소하며 일정한 값으로 수렴함을 알 수 있습니다.

위 단순과 복리 이자를 기하학적으로 나타내 봅니다. 먼저 연이자율 10%의 단순 이자의 경우 10년에 원금의 두 배가 되는 구조로 식 1의 관계를 갖습니다. 식 1을 n에 대한 y의 미분하면 식 3과 같습니다.

$$\begin{align} &y = y_0(1 + 0.1n)\\ &\frac{dy}{dn} = 0.1y_0 \end{align}$$

그림 2는 위 식에 대해 처음의 높이 Begin은 10년후 2배인 End가 됨을 나타낸 것입니다. 이자율을 5%로 낮추는 경우 역시 미분 계수는 상수가 되며 그림 2의 각 단계에서의 높이가 작아지는 차이를 제외하고 유사한 형태를 나타냅니다. 이 그림의 기울기는 원 함수의 미분계수로서 상수입니다.

그림 2. 단순이자.
n=symbols('n')
y=1000*(1+0.1*n)
dy=y.diff(n)
dy
100.0

반면에 복리의 경우 시간에 따른 변화율 즉, 미분 계수를 계산해 보면 다음과 같습니다. 다음 식의 결과는 log 함수이며 이러한 형태의 미분 계산 방법은 다음 절에서 소개합니다.

n=symbols('n')
y=1000*(1+0.1/n)**(10*n)
dy=y.diff(n)
dy
$\quad \small \color{blue}{1000 \left(1 + \frac{0.1}{n}\right)^{10 n} \left(10 \log{\left(1 + \frac{0.1}{n} \right)} - \frac{1.0}{n \left(1 + \frac{0.1}{n}\right)}\right)}$

위 결과와 같이 미분계수는 상수가 아니며 그 형태는 그림 3과 같습니다. 즉, 처음에 급격한 증가를 보이지만 n이 증가할수록 그 증가율은 감소되며 일정한 값으로 수렴됩니다.

re1.tail(1)
bins savings
9596.0 2716.867
9697.0 2716.882
9798.0 2716.896
9899.0 2716.910
99100.0 2716.924
그림 3. 복리이자.

오일러 수(Euler number)

그림 1의 그래프에서 초기값을 1로 할 경우 값은 2.71814...으로 수렴됩니다. 이 수렴 값을 수학적으로 오일러 수(ε 또는 e)라고 합니다.

순간 성장율이 위의 복리식(식 2)과 유사한 형태인 식 3과 같을 경우 대수 성장율(logarithmic rate)이라고 합니다. 다시 말하면 단위 대수 성장률은 단위 시간에서 1이 2.718281(e)에 이르는 속도입니다. 이 성장은 주어진 시간에 유기체 성장의 특징을 나타낼 수 있기 때문에 유기 성장 속도(organic rate of growing)라고도 합니다. 결과적으로 단위 속도당 100% 성장한다고 하면 산술적 성장은 2가 되며 대수적 성장은 e가 됩니다.

$$\begin{equation}\tag{3} \left(1+\frac{1}{n}\right)^n \end{equation}$$

식 3에서 n이 무한히 증가할 경우 값들을 대수적으로 다음과 같이 계산할 수 있습니다.

$$\begin{aligned} &\left(1+\frac{1}{1}\right)=2.0\\ &\left(1+\frac{1}{5}\right)^5=2.488\\ & \left(1+\frac{1}{10}\right)^{10}=2.594\\ &\left(1+\frac{1}{20}\right)^{20}=2.653\\ &\left(1+\frac{1}{100}\right)^{100}=2.705\\ & \left(1+\frac{1}{1000}\right)^{1000}=2.717\\ &\left(1+\frac{1}{10000}\right)^{10000}=2.718 \end{aligned}$$

위 계산은 두 항에 대한 거듭제곱의 형태입니다. 이러한 계산은 식 4와 같이 전개되는 이항 정리(binomial theorem)을 사용하여 나타낼 수 있습니다.

$$\begin{equation} \tag{4} \left(1+\frac{1}{n} \right)^n=1+1+\frac{1}{2!}\frac{n-1}{n}+\frac{1}{3!}\frac{(n-1)(n-2)}{n^2}+\cdots \end{equation}$$

식 4에서 n을 무한히 증가시키면 대수성장율 ε(=e)는 다음과 같습니다.

\begin{equation} e=1+1+\frac{1}{2!}+\frac{1}{3!}+\frac{1}{4!}+\cdots \end{equation}

sympy에서 지수 함수 exp(1)를 사용하여 e값을 나타냅니다.

re={0:1, 1:1} 
for i in range(2, 10): 
    re[i]=N(1/factorial(i), 5) 
re=pd.DataFrame([re.keys(), re.values()], index=["n", "value"]).T
re
n value
001
111
882.4802e-5
992.7557e-6
epsilon=sum(re.values[:,1]) 
epsilon
2.7183
exp(1)
e
N(exp(1), 5)
2.7183

지수 급수(Exponential series)

이항정리를 적용하여 $\displaystyle \left(1+\frac{1}{n}\right)^{nx}$를 전개하여 봅니다. 식 5와 같이 e의 지수 형태로 n을 무한대로 확장한 경우입니다. 이런 형태를 지수 급수라고 합니다.

$$\begin{align}\tag{5} e^x&= 1^{nx} + nx\frac{1^{nx-1}\frac{1}{n}}{1!}+nx(nx-1)\frac{1^{nx-2}\left(\frac{1}{n}\right)^2}{2!}\\ &\quad +nx(nx-1)(nx-2)\frac{1^{nx-3}\left(\frac{1}{n}\right)^3}{3!}+\cdots\\ &=1+x+\frac{x^2-\frac{1}{n}}{2!}+\frac{x^3-\frac{3x^2}{n}+\frac{2x}{n^2}}{3!}+\cdots \end{align}$$

ex의 중요성은 다른 함수가 가지지 않은 속성 즉, 그 값을 미분할 경우에도 값의 변경이 없다는 특성 때문입니다. 그러므로 지수 급수의 경우 미분 계수가 그 자신과 같습니다. 위 식을 미분해 봅니다.

x=symbols('x') 
f=0 
for i in range(6): 
    f += x**i/factorial(i) 
f
$\quad \small \color{blue}{\frac{x^{5}}{120} + \frac{x^{4}}{24} + \frac{x^{3}}{6} + \frac{x^{2}}{2} + x + 1}$
df=diff(f, x) 
df
$\quad \small \color{blue}{\frac{x^{4}}{24} + \frac{x^{3}}{6} + \frac{x^{2}}{2} + x + 1}$

코드에서 n이 [0, 5] 범위에서 지수 급수 형태의 함수(f)를 생성하였습니다. 이 함수를 미분한 결과인 df는 원래의 함수의 첫 항이 제거된 형태입니다. n이 무한대로 확장하는 경우 이 부분은 무시 가능합니다. 즉, 지수 급수의 경우는 미분 결과는 원래의 값과 같다고 할 수 있습니다.

지수 급수와 같이 미분 결과가 원래의 형태와 같은 함수를 찾아봅시다. 다음과 같이 x의 거듭제곱의 표현을 고려합니다.

$$\begin{align} y &= A + Bx + Cx^2 + Dx^3 + Ex^4 + \cdots\\ \frac{dy}{dx} &= B + Cx + Dx^2 + Ex^3 + \cdots \end{align}$$

위의 두 형태가 같기 위해서는 각 계수들간에 다음이 성립하여야 합니다.

$$\begin{align} A&=B \\ 2C&=B \rightarrow C=\frac{B}{2}=\frac{A}{1 \cdot 2}\\ 3D&=C \rightarrow D=\frac{C}{3}=\frac{A}{1 \cdot 2 \cdot 3}\\ & \vdots & \end{align}$$

위와 같이 A, B, C, D 등의 계수는 무한하게 정리할 수 있으나 분모가 계속 증가하므로 어느 시점부터는 무시할 수 있습니다. 위 y 식에서 A, B, C, D에 대해 정리하면 다음과 같습니다.

$$y=A\left(1+\frac{x}{1}+\frac{x}{1 \cdot 2}+\frac{x}{1 \cdot 2\cdot 3}+\cdots\right)$$

위 결과에서 A=1로 가정하고 x에 따른 y의 변화를 봅니다. 다음 코드에서 지수 급수를 나타내기 위해 n=100까지 확장한 함수 y를 생성하고 x 값을 1에서 4까지 대입하였습니다.

x=symbols('x') 
y=0 
for i in range(100): 
    y += x**i/factorial(i) 
(N(y.subs(x, 1),5), N(exp(1), 5))
(2.7183, 2.7183)
(N(y.subs(x, 2),5), N(exp(2), 5))#≃ e2 
(7.3891, 7.3891)
(N(y.subs(x, 3),5), N(exp(3), 5))#≃ e3
(20.086, 20.086)
(N(y.subs(x, 4),5), N(exp(4), 5))#≃ e4
(54.598, 54.598)

위 결과에 의하면 함수 y는 다음과 같이 표현됩니다.

$$\begin{align} y&=A\left(1+\frac{x}{1}+\frac{x}{1 \cdot 2}+\frac{x}{1 \cdot 2\cdot 3}+\cdots\right)\\\ &=A \cdot e^x \end{align}$$

자연로그(Natural Logarithms)

식 6에서 나타낸 것과 같이 ex의 역함수는 자연로그 함수가 됩니다. 즉, 로그의 밑수가 e인 로그로서 ln()나타내며 상용로그는 10로 log()로 표현합니다. 그러나 numpy, sympy등 파이썬 패키지에서는 log()함수 내에 밑수를 별도로 지정하여 사용합니다. log()의 기본은 자연로그를 나타냅니다.

$$\begin{equation}\tag{6} y=e^x \rightarrow x=\log_ey \end{equation}$$

위의 지수 함수의 그래프는 그림 4와 같으며 그 함수의 역함수인 로그 함수의 형태 역시 그림 4와 같습니다. 즉, 위에서 표시한 두 함수는 실제로 같은 의미입니다.

plt.figure(dpi=100)
plt.subplot(1,2,1)
x=np.linspace(0, 3, 100)
y=np.exp(x)
plt.plot(x, y, label=r"$\mathbf{y=e^x}$")
plt.xlabel("x", size=12, weight="bold")
plt.ylabel("y", size=12, weight="bold")
plt.legend(loc="best")
plt.subplot(1,2,2)
y=np.linspace(0.01, 3, 100)
x=np.log(y)
plt.plot(x, y, label=r"$\mathbf{x=ln(y)}$")
plt.xlabel("x", size=12, weight="bold")
plt.legend(loc="best")
plt.show()
그림 4. $\displaystyle y=e^x \quad \text{또는} \quad x = log_e y$.

다음 코드에서 일정한 x 값에 대해 위의 지수함수를 계산했으며 그 역함수에 그 결과 값들을 대입하여 x가 반환됨을 확인해 봅니다.

x, y=symbols('x, y') 
eq=y-exp(x) 
y1=solve(eq, y) 
y1
[exp(x)]
re={} 
for i in np.arange(0, 4, 0.5): 
    re[i]=N(y1[0].subs(x, i), 5) 
pd.DataFrame([re.keys(), re.values()], index=["x","y"])
0 1 2 3 4 5 6 7
x 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5
y 1.0000 1.6487 2.7183 4.4817 7.3891 12.182 20.086 33.115
x1=solve(eq, x) 
x1
[log(y)]
re_x1={} 
for i in re.values(): 
    re_x1[i]=N(x1[0].subs(y, i), 5) 
pd.DataFrame([re_x1.values(), re_x1.keys()], index=["x","y"])
0 1 2 3 4 5 6 7
x 0 0.50000 1.0000 1.5000 2.0000 2.5000 3.0000 3.5000
y 1.0000 1.6487 2.7183 4.4817 7.3891 12.182 20.086 33.115

댓글

이 블로그의 인기 게시물

[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