<jupyter_start><jupyter_text>함수  함수와 변수- 함수(function)는 입력 값을 출력 값으로 바꾸어 출력하는 관계(relationship)을 말함.- 맵(map) 또는 맵핑(mapping)이라는 용어를 사용하기도 한다. - 예를 들어 1,2,3, ... 이라는 숫자를 입력받아서, 두배가 되는 2, 4, 6,...을 출력하는 것은 함수라고 할 수 있다.- 1,2,3,... ----> 함수(function) ----> 2,4,6,...- 어떤 입력 값과 출력 값이 함수 관계를 이루기 위해서는 같은 입력 값에 대해서 항상 같은 출력 값이 나와야 한다. 예를 들어 똑같이 3을 입력했는데 어떤 경우에는 4가 나오고, 어떤 경우에는 5가 나온다면 함수라고 할 수 없다.- 함수에서 입력 변수가 가질 수 있는 값의 집합을 정의역(domain)이라고 한다.- 함수에서 출력 변수가 가질 수 있는 값의 집합을 공역  (range)라고 한다. - 정의역은 실수 전체인 경우가 많다. 하지만, 함수에 따라서는 일부 숫자만 정의역으로 가질 수 있다. - 변수(variable)이란 어떤 숫자를 대표하는 기호이다. - 함수에서 입력 값이나 출력 값을 기호 즉 변수로 나타내기도 한다.- 입력 값을 대표하는 변수를 입력 변수(input variable)라 한다.- 출력 값을 대표하는 변수를 출력 변수(output variable)라 한다.- 변수는 보통 x,y,z등의 알파벳 소문자로 표시한다. - 함수에서 기호를 사용하는 이유는 입력 값과 출력 값의 관계를 수식으로 표현하기 위해서 이다. - 예를 들어, 어떤 숫자를 입력으로 받아, 그 값의 2배가 되는 값을 출력으로 한다면, 다음처럼 표현 할 수 있다. x -> 2x 또는 y = 2x- 함수를 여러개 사용할 때는 이름을 붙여 구별한다. 변수와 마찬가지로 함수 f,g,h와 같이 알파벳 소문자로 표시한다. 함수 f에 특정한 입력 값 x를 넣어서 나오는 출력 값을 표기할 때는, f(x)라고 한다. 이 기호는 "f of x"라고 읽는다. 출력 기호 y 대신 f(x)를 사용하여 함수 관계를 표시할 수 도 있다. - f(x) = 2x- 파이썬의 함수는 이러한 수학 함수의 개념을 구현한 것으로 볼 수 있다. 예를 들어 다음 파이썬 함수 f는 입력 변수의 값을 2배하여 출력한다.<jupyter_code>def f(x):
    return 2 * x

x = 10 
y = f(x)
print(x, y)<jupyter_output>10 20<jupyter_text>함수의 응용- 서로 관계를 가지며 맺어지는 모든 숫자의 쌍은 함수라고 생각할 수 있다. 예를 들어,     - 앰프의 조절 나사 (knob)을 돌린 각도 x와 소리의 크기 (volume) y    - 등산을 할 때 출발점에서 간 거리 x와 그 위치의 해발 고도 y- 예측(prediction)문제도 독립 변수 x를 입력으로 가지고, 종속 변수 y hat이 원래의 출력 데이터 y와 가장 비슷한 함수 y hat = f(x)를 ㅊ자는 문제라고 할 수 있다.  역함수- 어떤 함수의 입력/출력 관계와 정반대의 입출력 관계를 가지는 함수를 **역함수(inverse function)**이라고 한다.- 예를 들어 어떤 함수 f가 1,2,3,... 를 입력받아서 1,4,9,...을 출력하고 다른 함수 g는 반대로 1,4,9,...를 입력받아서 1,2,3,...을 출력하면 두 함수 f,g는 서로 역함수이다.- 함수 f의 역함수 f^-1기호로 표시한다.- y = f(x), -> x = f^-1(y)- 함수의 "역함수"와 함수의"역수"는 다르다는 점에 주의한다.- f^-1(x) = f(x) -1 = 1 / f(x)- 함수가 존재한다고 해서 항상 역함수가 존재할 수 있는 것은 아니다. 에를 들어 두 개의 서로 다른 x1, x2 값에 대해 y의 값이 y*로 같다고 하자. - f(x1) = y*- f(x2) = y*- 그러면, 반대로 y*에 대응하는 x값을 선택할 수 없기 때문에 역함수가 존재하지 않는다.- 예를 들어 다음 함수는 역함수가 존재하지 않는다.- f(x) = y^2- 이 함수의 역함수가 존재하려면 정의역을 양수로 제한해야 한다(x > 0)이 때는 다음과 같이 역함수가 존재한다.- f^-1(x) = square root of x  연습 문제 1- 1. 함수와 역함수의 또 다른 예를 생각해 보자.- 2. 원래의 함수 f에 들어갈 입력값 3개 x1,x2,x3와 그에 해당하는 출력값 3개 y1, y2, y3를 생각한다.- 3. 역함수에 y1,y2,y3를 입력해서 진짜로 x1,x2,x3이 나오는지 확인한다  함수의 그래프- 함수의 형상을 직관적으로 파악하기 위해 그래프(graph) 또는 플롯(plot)을 사용하기도 한다.- 파이썬에서는 matplotlib의 라인 플롯을 사용하여 그래프를 만들 수 있다.- 다만, matplotlib에서는 그래프를 작성할 영역을 작은 구간으로 나눈 독립 변수값 벡터 x를 생성하고, 이 위치에 대한 함수값 벡터 y를 하나하나 계산하여 이렇게 만들어진 점을 직선으로 연결하는 방식으로 플롯을 그린다. 따라서, 구간의 간격이 너무 크면 그래프가 부정확해지고 구간의 간격이 너무 작으면 계산 시간이 증가하여 메모리 등의 리소스가 낭비된다.matplotlib으로 다음과 같은 함수의 그래프를 그려보자- f(x) = x^3 - 3x^2 + x<jupyter_code>%matplotlib inline
def f(x):
    return x ** 3 - 3 * x ** 2 + x<jupyter_output><empty_output><jupyter_text>- 우선 x = -1부터 x = 3 까지, 0.5 간격으로 9개의 점을 찍는다.<jupyter_code>x = np.linspace(-1, 3, 9)
x<jupyter_output><empty_output><jupyter_text>- 그리고 이 위치에 대해 y = f(x) 값을 구한다<jupyter_code>y = f(x)
x
y<jupyter_output><empty_output><jupyter_text>- matplotlib가 그리는 그래프는 이 표에 나타난 x,y쌍을 직선으로 연결한 그림이다.<jupyter_code>plt.plot(x, y, 'ro-')
plt.xlim(-2,4) # x축의 범위 제한
plt.xticks(np.arange(-1, 4)) # x축
plt.yticks(np.arange(-5, 4))
plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>- 이 x,y벡터의 구간을 더 조밀하게 만들면, 그래프는 곡선으로 보이게 된다. 다음 그래프는 곡선으로 보이지만 실제로느느 약 400개의 직선이 연결된 것이다.<jupyter_code>x = np.linspace(-1, 3, 400)
y = f(x)
plt.plot(x, y)

plt.xlim(-2, 4)
plt.xticks(np.arange(-1,4))
plt.yticks(np.arange(-5,4))

plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>역함수의 그래프- 역함수의 그래프는 원래의 함수에서 x축과 y축과 봐뀐 것이므로 y = x가 나타내는 직선(원점을 통과하는 기울기 1인 직선)을 대칭축으로 대칭인 함수의 그래프와 같다.   데이터 분석에서 많이 사용되는 함수들- 데이터 분석에서 많이 사용되는 함수의 형태는 다항식(polynomial)함수, 지수(exponential)함수, 로그(log)함수 등이다.  다항식 함수- 다항식(polynomial)함수는 상수항 c, 일차항 cx, 이차항 cx^2,--- 등의 거듭제곱 항의 선형 조합으로 이루어진 함수이다. 다음은 단변수(uni-variate) 다항식 함수의 전형적인 형태이다. - f(x) = c0 + c1x + c2x^2 + - - - + cnx^n  지수 함수- 정해진 어떤 값을 입력 값으로 거듭제곱하여 출력을 구하는 함수를 생각하자.- y = a^x- 거듭제곱을 할 때 아래에 있는 수를 밑(base)라고 한다. 밑을 오일러 수 e(약2.718)로 하여 거듭제곱을 하는 함수를 **지수 함수(exponential function)**라고 한다.- y = e^x- 지수 함수는 다음처럼 표시 할 수 도 있다.- y = exp(x) = expx- 지수 함수는 다음과 같은 특성을 가진다.    - 양수(e)를 거듭제곱한 값이므로 항상 양수이다.    - x = 0 일 때, 1이 된다.    - x가 양의 무한대로 가면 (x -> 무한대), 양의 무한대로 다가간다.    - x가 음의 무한대로 가면 (x -> -무한대), 0으로 다가간다.    - x1 > x2 이면, expx1 > expx2이다- NumPy에서는 e명령으로 오일러 수를, exp명령으로 지수 함수를 계산한다. 여러가지 값을 대입하여 지수 함수의 값을 구해 위 성질이 성립하는지 살펴보자.<jupyter_code>import numpy as np
import pandas as pd
np.e
np.exp(-10), np.exp(-1), np.exp(-0.1), np.exp(0), np.exp(0.1), np.exp(1), np.exp(10)<jupyter_output><empty_output><jupyter_text>- 위 특성에 의해 지수 함수의 그래프는 다음처럼 그려진다.<jupyter_code>xx = np.linspace(-2, 2, 100)
yy = np.exp(xx)
plt.plot(xx, yy)
plt.axhline(1, c='r', ls='--')
plt.axhline(0, c='r', ls='--')
plt.axvline(0, c='r', ls='--')
plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>- 두 지수 함수의 곱의 값은 입력 값의 합의 지수 함수 값과 같다. - e^x1*e^x2 = e^(x1+x2)<jupyter_code>np.exp(2 + 3), np.exp(2) * np.exp(3)<jupyter_output><empty_output><jupyter_text>로그 함수- e를 거듭제곱하여 특정한 값이 되는 수를 찾아야 할 때가 있다. 예를 들어 e를 제곱하면 약 7.3이 되고 세제곱하면 약 20이 된다. 그렇다면 몇 제곱을 해야 10이라는 값이 될까?<jupyter_code>np.exp(2), np.exp(3)<jupyter_output><empty_output><jupyter_text>- 약 2.3025851 제곱을 하면 10이 되는 것을 확인 할 수 있다. 이렇게 e를 거듭제곱하여 특정한 a가 되도록 해주는 숫자를 log a라고 하고 log라고 읽는다.<jupyter_code>np.exp(2.3025851)<jupyter_output><empty_output><jupyter_text>- NumPy에서 로그 함수 명령은 log이다.<jupyter_code>np.log(10)<jupyter_output><empty_output><jupyter_text>- 지수함수에서 밑이 e가 아닌 경우에는 다음처럼 로그를 이용하여 계산할 수 있다.- y=a^x = (e^loga)^x = e ^ xloga- 로그는 지수함수의 출력이 특정한 값이 되게 하는 입력을 찾는 것이므로 지수함수의 역함수이다.y = log x- 로그 함수는 다음과 같은 특징을 가진다.    - x값, 즉 입력 변수값이 양수이어야 한다. 0이거나 음수이면 정의되지 않는다.     - x > 1이면 양수가 된다.    - x = 1일 때, y = 0이 된다.     - 0 < x < 1 이면, 음수가 된다.    - x1 > x2 이면, log x1 > log x2이다.- 로그 함수의 그래프는 다음과 같은 형태를 띈다.<jupyter_code>xx = np.linspace(0.01, 8, 100)
yy = np.log(xx)

plt.plot(xx, yy)
plt.axhline(0, c='r', ls='--')
plt.axvline(0, c='r', ls='--')
plt.axvline(1, c='r', ls='--')
plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>- log 함수는 확률론에서 가장 많이 사용되는 함수이다. 그 이유는 로그 함수가 가지는 다음과 같은 특이한 성질때문이다.  로그 함수의 성질 1: 로그 함수는 곱하기를 더하기로 변환한다.- log(x1 * x2) = logx1 + logx2- log x^n = n*log x  연습문제 3- log2의 값은 약 0.69, log3의 값은 약 1.10이다. 이 때 log 12의 값을 구하라<jupyter_code>0.69+0.69+1.10
np.log(2) + np.log(2) + np.log(3)
np.log(12)<jupyter_output><empty_output><jupyter_text>로그 함수의 성질 2: 어떤 함수에 로그를 적용해도 함수의 최고점, 최저점의 위치는 변하지 않는다. - 만약 양수값만을 가지는 함수가 있을 때, 이 함수에 다시 로그함수를 적용하면 높낮이는 바뀌지만, 최고점이나 최저점의 위치는 바뀌지 않는다. 따라서, 최적화를 할 때, 원래의 함수가 아니라 로그를 취한 함수에 대해 최적화를 실시하는 경우가 많다.- argmaxf(x) = argmaxlogf(x)<jupyter_code>def ff(x):
    return x**3 - 12*x + 20*np.sin(x) + 7

xx = np.linspace(-4, 4, 300)
yy = ff(xx)

plt.subplot(211) # matrix size
plt.plot(xx,yy)
plt.axhline(1, c='r', ls='--')
plt.title('f(x)')

plt.subplot(212) # 
plt.plot(xx, np.log(yy))
plt.axhline(0, c='r', ls='--')
plt.title('log f(x)')

plt.tight_layout()
plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>로그 함수의 성질 3: 로그 함수는 0부터 1사이의 작은 값을 확대시켜 보여준다. - 로그함수는 0부터 1사이의 구간을 음의 무한대부터 0까지로 확장시켜주기 때문에, 확률값처럼 0과 1사이에는 있는 작은 값을 더 확실하게 비교할 수 있도록 한다.<jupyter_code>np.random.seed(0)
x = np.random.rand(5)
x = x / x.sum()

plt.subplot(211)
plt.bar(range(1, 6), x)
plt.ylim(0,1)

plt.subplot(212)
plt.bar(range(1, 6), np.log(x))

plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>다변수 함수- 함수는 복수의 입력 변수를 가질 수도 있다. 이러한 함수를 **다변수 함수(multivariate function)**이라고 한다. 예를 들어 다음 수식은 함수 f가 2개의 입력 변수 x,y를 받아서 변수 z를 출력하는 다변수 함수라는 뜻이다. - z = f(x, y)- 다음은 다변수의 함수의 예이다.- f(x, y) = 2x^2 + 6xy +7y^2 - 26x - 54y + 107- 2개의 독립 변수를 가지는 함수 f(x,y)는 다음처럼 3차원 서피스 플롯(surface plot), 또는 컨투어 플롯(contour plot)으로 나타낼 수 있다.<jupyter_code>def f(x,y):
    return 2 * x ** 2 + 6 * x * y + 7 * y ** 2 - 26 * x - 54 * y + 107

xx = np.linspace(-5, 5, 100)
yy = np.linspace(-4, 4, 100)
X, Y = np.meshgrid(xx, yy)
Z = f(X, Y)
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
fig.gca(projection='3d').plot_surface(X, Y, Z)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Surface Plot')
plt.show()
CS = plt.contour(X, Y, Z, levels=np.arange(0, 300, 20))
plt.clabel(CS, fmt='%d')
plt.title('Contour Plot')
plt.show()<jupyter_output><empty_output><jupyter_text>- 다음 함수는 다변수 함수의 곱으로 표현 가능한 다변수 함수이다. 이러한 특수한 다변수 함수는 추후 확률변수에서 중요한 역할을 한다.- g(x, y) = exp(-x^2 - 16y^2) = exp(-x^2)exp(-16y^2) = g1(x)g2(y)<jupyter_code>def g1(x):
    return np.exp(-x ** 2)

def g2(y):
    return np.exp(-16 * y ** 2)

def g(x,y):
    return g1(x) * g2(y)

xx = np.linspace(-1, 1, 100)
yy = np.linspace(-1, 1, 100)
X, Y = np.meshgrid(xx, yy)
Z = g(X, Y)
from matplotlib import transforms 
from matplotlib.ticker import NullFormatter

left, width = 0.1, 0.65
bottom, height = 0.1, 0.65
bottom_h = left_h = left + width + 0.02
rect = [left, bottom, width, height]
rectx = [left, bottom_h, width, 0.2]
recty = [left_h, bottom, 0.2, height]

plt.figure(1, figsize=(8,8))
ax = plt.axes(rect)
axx = plt.axes(rectx)
axy = plt.axes(recty)

nullfmt = NullFormatter()
axx.xaxis.set_major_formatter(nullfmt)
axy.yaxis.set_major_formatter(nullfmt)

ax.contour(X, Y, Z)
ax.axhline(0, c='r', ls='--')
ax.axhline(0.1, c= 'r', ls='--')
ax.axhline(0.2, c='r', ls='--')
ax.axhline(0.3, c='r', ls='--')
ax.axhline(0.4, c='r', ls='--')
ax.set_xlabel('x')
ax.set_ylabel('y')

axx.plot(xx, g1(xx))
axx.plot(xx, g2(0.1) * g1(xx), c='lightgray')
axx.plot(xx, g2(0.2) * g1(xx), c='lightgray')
axx.plot(xx, g2(0.3) * g1(xx), c='lightgray')
axx.plot(xx, g2(0.4) * g1(xx), c='lightgray')
axx.set_title('g1(x)')

base = axy.transData
rot=transforms.Affine2D().rotate_deg(-90)
axy.plot(yy, g2(yy), transform=rot + base)
axy.set_title('g2(y)')
axy.axhline(0, c='r', ls='--')
axy.axhline(0.1, c='r', ls='--')
axy.axhline(0.2, c='r', ls='--')
axy.axhline(0.3, c='r', ls='--')
axy.axhline(0.4, c='r', ls='--')

axx.set_xlim(ax.get_xlim())
axy.set_ylim(ax.get_ylim())

plt.show()<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\font_manager.py:1320: UserWarning: findfont: Font family ['nanumgothic'] not found. Falling back to DejaVu Sans
  (prop.get_family(), self.defaultFamily[fontext]))<jupyter_text>다변수 다출력 함수- 어떤 함수는 입력 변수 뿐 아니라 출력 변수도 여러개일 수 있다. 이 경우에는 출력을 벡터나 행렬로 나타낼 수 있다.- 다음 함수는 3차원 softmax라는 함수이다. 이 함수는 3차원 벡터를 입력받아 3차원 벡터를 출력한다. 출력 벡터는 다음과 같은 특성을 가진다.    - 모든 원소는 0와 1사이의 값을 가진다.    - 모든 원소의 합은 1이다.    - 입력 원소들의 크기 순서와 출력 원소들의 크기 순서가 같다.     - 입력 원소들의 크기 순서와 출력 원소들의 크기 순서가 같다.    [y1                    [exp(w1x1) / exp(w1x1) + exp(w2x2) + exp(w3x3)     y2   = h(x1,x2,x3) =   exp(w2x2) / exp(w1x1) + exp(w2x2) + exp(w3x3)     y3]                    exp(w3x3) / exp(w1x1) + exp(w2x2) + exp(w3x3)]<jupyter_code>def softmax(x, w): # x는 1차원 배열, w는 가중치 벡터
    e = np.exp(w * x)
    return np. exp(w * x) / e.sum()

x = [2.0, 1.0, 0.5]
y = softmax(x, np.ones(3))
y
np.sum(y)
softmax(x, 4 * np.ones(3))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16056876767004824, 'fraction_numerical': 0.040162980209545986, 'mean_word_length': 3.4943946188340806, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '253985', 'license': 'MIT', 'n_tokens_mistral': 8339, 'n_tokens_neox': 9617, 'n_words': 1707, 'path': '2018_05_26_Function_review.ipynb', 'repo_name': 'jaykim-asset/datascience_review', 'size': '12026'}