🌗

7일차 데이터 분석을 위한 수학적 이론

notion imagenotion image

목차

통계이론

  • 모수(parameter) : 모집단의 특성을 수치로 표현한 수
  • 통계량/추정량(statistic) : 표본을 통해서 계산되어진 양
    • 표본평균 : 표본의 평균
    • notion imagenotion image
    • 표본 분산 : 표분의 분산
    • notion imagenotion image

평균

반_1 = [100, 0] 반_2 = [75, 25] 반_3 = [50, 50]
반_1_평균 = sum(반_1)/len(반_1) 반_1_평균
Out[-] 50.0
반_2_평균 = sum(반_2)/len(반_2) 반_2_평균
Out[-] 50.0
반_3_평균 = sum(반_3)/len(반_3) 반_3_평균
Out[-] 50.0
 

분산

notion imagenotion image
  • 평균으로부터 각 숫자들의 거리 편차를 제곱한 값의 평균 ⇒ 편차의 제곱의 평균
# 반_1 = [50, -50] # 반_2 = [25, -25] # 반_3 = [0, 0] 반_1_분산 = [50**2, (-50)**2] 반_2_분산 = [25**2, (-25)**2] 반_3_분산 = [0, 0]
반_1_분산 = sum(반_1_분산)/len(반_1_분산) 반_1_분산
Out[-] 2500.0
반_2_분산 = sum(반_2_분산)/len(반_2_분산) 반_2_분산
Out[-] 625.0
반_3_분산 = sum(반_3_분산)/len(반_3_분산) 반_3_분산
Out[-] 0.0
반_1_분산 ** 0.5
Out[-] 50.0
 

표준편차

notion imagenotion image
  • 데이터의 산포도(퍼진 정도)를 나타내는 값
  • 데이터가 밀집되지 않고 넓게 분포되어지면 표준편차의 값은 커짐
import math 반_1_표준편차 = math.sqrt(반_1_분산) 반_2_표준편차 = math.sqrt(반_2_분산) 반_3_표준편차 = math.sqrt(반_3_분산)
print(반_1_표준편차, 반_2_표준편차, 반_3_표준편차)
Out[-] 50.0 25.0 0.0

확률 이론

  • 확률 실험/확률 시행(Random Experiment) : 이론적으로 동일한 조건에서 여러 번 반복할 수 있고, 그 결과는 우연에 의해서 결정되는 실험
  • 표본 공간(Sample space) : 나올 수 있는 모든 경우의 결과들의 모임, 시행의 결과들의 집합
  • 근원 사건(Sample outcome) : 표본 공간의 원소
  • 사건(Event) : 표본 공간의 부분집합이자 근원 사건의 집합
  • 곱 사건 : 두 사건의 교집합으로 표현
  • 배반 사건 : 두 집합의 교집합이 공집합인 사건
  • 확률 변수 : 사건의 확률을 수치적 변수로 표현

동전 2개를 던졌을 때 앞면의 개수

x 0 1 2 P(x) 1/4 1/2 1/4
import numpy as np 평균 = 1 확률 = [1/4, 1/2, 1/4] 편차 = np.array([-1, 0, 1]) 편차의제곱 = 편차**2 편차의제곱
Out[-] array([1, 0, 1], dtype=int32)
sum(편차의제곱*확률)
Out[-] 0.5
 

공분산

notion imagenotion image
  • 두 변수(x, y)의 어떤 관계를 가지고 변화하는 측도를 나타냄
  • 공분산이 양수이면 두 변수가 같은 방향이고, 음수일 경우 서로 다른 방향
  • 공분산이 0이면 서로가 독립을 의미
수학점수 = [] 컴퓨터점수 = [] for i in range(100): if i > 20 and i < 80: 수학점수.append(i + np.random.randint(1, 30)) 컴퓨터점수.append(i + np.random.randint(1, 30)) else: 수학점수.append(i + np.random.randint(1, 10)) 컴퓨터점수.append(i + np.random.randint(1, 10))
import matplotlib.pyplot as plt %matplotlib inline plt.scatter(수학점수, 컴퓨터점수) plt.xlabel('math') plt.ylabel('computer') plt.show()
Out[-]
notion imagenotion image
# 평균(mean): np.mean(x) # 표준편차(standard deviation) : np.std(x) # 분산(variance) : np.var(x) # 1사분면 = (x - np.mean(x)(y - np.mean(y)) # (90 - 50)(90 - 50) = 1600 # 2사분면 = (x - np.mean(x)(y - np.mean(y)) # (40 - 50)(60 - 50) = -100 # 3사분면 = (x - np.mean(x)(y - np.mean(y)) # (20 - 50)(20 - 50) = 900 # 4사분면 = (x - np.mean(x)(y - np.mean(y)) # (70 - 50)(40 - 50) = -200
 

미분

  • 함수가 주어졌을 때 도함수를 구하는 과정
    • 도함수 : x가 바뀔 때마다 생기는 순간 변화율을 구하는 함수
  • 함수의 극대값, 극소값을 구할 수 있음
  • 평균 변화율 : x가 변할 때 y의 변화량을 말함
  • 순간 변화율 : 평균 변화율의 극한값으로 접선의 기울기
import numpy as np import matplotlib.pyplot as plt %matplotlib inline x = np.arange(0, 10, 0.1) y = np.sin(x) plt.figure(figsize=(12,6)) plt.plot(x, y);
Out[-]
notion imagenotion image
plt.figure(figsize=(12,6)) plt.plot(x, y, 'k', label='Original') plt.plot(x, np.cos(x), 'b', label='True Cos') plt.plot(x, np.r_[0, np.diff(y)]/0.1, 'r.', label='Calculated Diff') plt.legend(loc='best') plt.show()
Out[-]
notion imagenotion image
 

선형 회귀

  • Modeling : 모델을 만들어 내는 과정
  • 지도 학습 : 정답을 제공하고 학습을 시키는 것
    • 회귀 분석 : 입력 변수 x에 대해서 연속형 출력 변수 Y를 예측하는 분석
  • 기본 가정
      1. 선형성 : 독립 변수 x와 종속변수 y가 선형적이어야 함
      1. 독립성 : 종속변수는 다른 종속변수의 값에 영향 받지 않음
      1. 정규성 : 잔차는 기대값이 0인 정규분포를 따라야 함
      1. 등분산성 : 잔차의 분산은 일정해야 함

정규분포

notion imagenotion image
import numpy as np # x정의 x = np.linspace(-5,5,101) x
Out[-] array([-5. , -4.9, -4.8, -4.7, -4.6, -4.5, -4.4, -4.3, -4.2, -4.1, -4. , -3.9, -3.8, -3.7, -3.6, -3.5, -3.4, -3.3, -3.2, -3.1, -3. , -2.9, -2.8, -2.7, -2.6, -2.5, -2.4, -2.3, -2.2, -2.1, -2. , -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1. , -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5. ])
# 정규분포식 y = (1/np.sqrt(2*np.pi))*np.exp(-x**2 / 2) y
Out[-] array([1.48671951e-06, 2.43896075e-06, 3.96129909e-06, 6.36982518e-06, 1.01408521e-05, 1.59837411e-05, 2.49424713e-05, 3.85351967e-05, 5.89430678e-05, 8.92616572e-05, 1.33830226e-04, 1.98655471e-04, 2.91946926e-04, 4.24780271e-04, 6.11901930e-04, 8.72682695e-04, 1.23221917e-03, 1.72256894e-03, 2.38408820e-03, 3.26681906e-03, 4.43184841e-03, 5.95253242e-03, 7.91545158e-03, 1.04209348e-02, 1.35829692e-02, 1.75283005e-02, 2.23945303e-02, 2.83270377e-02, 3.54745928e-02, 4.39835960e-02, 5.39909665e-02, 6.56158148e-02, 7.89501583e-02, 9.40490774e-02, 1.10920835e-01, 1.29517596e-01, 1.49727466e-01, 1.71368592e-01, 1.94186055e-01, 2.17852177e-01, 2.41970725e-01, 2.66085250e-01, 2.89691553e-01, 3.12253933e-01, 3.33224603e-01, 3.52065327e-01, 3.68270140e-01, 3.81387815e-01, 3.91042694e-01, 3.96952547e-01, 3.98942280e-01, 3.96952547e-01, 3.91042694e-01, 3.81387815e-01, 3.68270140e-01, 3.52065327e-01, 3.33224603e-01, 3.12253933e-01, 2.89691553e-01, 2.66085250e-01, 2.41970725e-01, 2.17852177e-01, 1.94186055e-01, 1.71368592e-01, 1.49727466e-01, 1.29517596e-01, 1.10920835e-01, 9.40490774e-02, 7.89501583e-02, 6.56158148e-02, 5.39909665e-02, 4.39835960e-02, 3.54745928e-02, 2.83270377e-02, 2.23945303e-02, 1.75283005e-02, 1.35829692e-02, 1.04209348e-02, 7.91545158e-03, 5.95253242e-03, 4.43184841e-03, 3.26681906e-03, 2.38408820e-03, 1.72256894e-03, 1.23221917e-03, 8.72682695e-04, 6.11901930e-04, 4.24780271e-04, 2.91946926e-04, 1.98655471e-04, 1.33830226e-04, 8.92616572e-05, 5.89430678e-05, 3.85351967e-05, 2.49424713e-05, 1.59837411e-05, 1.01408521e-05, 6.36982518e-06, 3.96129909e-06, 2.43896075e-06, 1.48671951e-06])
# 정규분포 그리기 import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize = (10,6)) plt.plot(x,y) plt.ylabel("y") plt.show()
Out[-]
notion imagenotion image

선형 회귀 분석

  • 결정 계수
    • 선형 회귀 분석에서 모델이 얼마나 적합한지 평가
    • 범위는 [0,1]
    • 1에 가까울 수록 독립변수와 종속변수를 잘 설명하고 있음
      • notion imagenotion image
      • SST : 실제값과 종속변수의 표본평균의 차의 제곱합
      • SSR : 예측값과 종속변수의 표본평균의 차의 제곱합
      • SSE : 예측값과 실제값의 차의 제곱합
      • SST = SSR + SSE
import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression
# 랜덤한 임의의 X,Y 값 생성 np.random.seed(1200) X = 2*np.random.rand(100,1) print('X shape : ', X.shape) Y = 3 + 2*X + np.random.randn(100,1) print('Y shape : ', Y.shape) plt.scatter(X,Y) plt.show()
Out[-]
X shape : (100, 1) Y shape : (100, 1)
notion imagenotion image
lin_reg = LinearRegression() lin_reg.fit(X,Y) print(f'y절편: {lin_reg.intercept_}, 기울기: {lin_reg.coef_}')
Out[-] y절편: [3.18198669], 기울기: [[1.81375875]]
# X_test 생성 X_test = np.linspace(0,2,100).reshape(100,1) print('X_test') print(X_test[:6]) print(X_test[-6:]) # 예측 predictions = lin_reg.predict(X_test) print('prediction : ', predictions[:6])
Out[-] X_test [[0. ] [0.02020202] [0.04040404] [0.06060606] [0.08080808] [0.1010101 ]] [[1.8989899 ] [1.91919192] [1.93939394] [1.95959596] [1.97979798] [2. ]] prediction : [[3.18198669] [3.21862828] [3.25526987] [3.29191146] [3.32855306] [3.36519465]]
# 그래프 그리기 plt.scatter(X,Y) plt.plot(X_test, predictions,'r') plt.show()
Out[-]
notion imagenotion image

비선형 회귀 분석

%matplotlib inline import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.preprocessing import PolynomialFeatures
# training Set 만들기 # range : -3 <= x < 3 의 x값 100개 np.random.seed(1216) X = 6*np.random.rand(100,1)-3 print('X = ', X[:6]) # y값 랜덤 생성 Y = 0.3 + 2 *X + X**2 + np.random.randn(100,1) print('Y = ', Y[:6])
Out[-] X = [[ 2.9735891 ] [ 0.74046546] [ 2.25656212] [ 2.33626717] [-0.67942513] [ 1.13951938]] Y = [[17.94142067] [ 1.59013283] [ 9.77487261] [ 8.76874343] [-0.83438259] [ 5.68952924]]
# 그래프 구현 plt.scatter(X,Y) plt.show()
Out[-]
notion imagenotion image
# poly_feature 생성하기 poly_feature = PolynomialFeatures(degree=2, include_bias = False) # X에 poly_featrue 적용 X_poly = poly_feature.fit_transform(X) print('X poly = ', X_poly[:6])
Out[-] X poly = [[ 2.9735891 8.84223212] [ 0.74046546 0.5482891 ] [ 2.25656212 5.09207262] [ 2.33626717 5.45814428] [-0.67942513 0.46161851] [ 1.13951938 1.29850441]]
# LinearRegression 객체 생성 lin_reg = LinearRegression() # 회귀분석 실행 매소드 lin_reg.fit(X_poly, Y) print('intercept : ', lin_reg.intercept_) print('coefficients : ', lin_reg.coef_) # y = b + a1 * x + a2 * x^2
Out[-] intercept : [0.33611387] coefficients : [[2.02456163 0.97973891]]
# X_test 만들기 # linspace 함수 : -3~3사이에서 100개의 균일한 간격으로 점 생성 # reshape 함수 : 데이터 타입을 100,1 의 행렬로 변환 X_test = np.linspace(-3,3,100).reshape(100,1) print(X_test[:6]) print(X_test[-6:])
Out[-] [[-3. ] [-2.93939394] [-2.87878788] [-2.81818182] [-2.75757576] [-2.6969697 ]] [[2.6969697 ] [2.75757576] [2.81818182] [2.87878788] [2.93939394] [3. ]]
# X_test를 회귀분석에 맞게 핏하기 X_test_poly = poly_feature.fit_transform(X_test) # X_test로 예측해보기 y_pred = lin_reg.predict(X_test_poly) #예측 그래프 그리기 plt.scatter(X,Y) plt.plot(X_test, y_pred, 'r') plt.show()
Out[-]
notion imagenotion image

선형 회귀 분석 실습

from sklearn.datasets import make_regression from sklearn.metrics import r2_score from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt %matplotlib inline
# 데이터 생성하기 x,y = make_regression(n_samples = 500, n_features=1, n_informative = 1, noise = 25, random_state = 10) # train data 와 test data 분류 (7:3) x_train, x_test, y_train, y_test = train_test_split(x,y, test_size = 0.3, random_state = 10)
# 선형회귀에 적용하기 line = LinearRegression().fit(x_train, y_train) # 예측하기 pred = line.predict(x_test)
# 그래프 그리기 fig, ax = plt.subplots() ax.scatter(x_test, y_test, alpha = 0.6) ax.plot(x_test, pred, color = 'red')
Out[-] [<matplotlib.lines.Line2D at 0x1633d205c08>]
notion imagenotion image
# 평가하기 print('R2 : ', r2_score(y_test, pred))
Out[-] R2 : 0.8535702276418713

행렬

  • 수 또는 문자를 직사각형 모양으로 배열하여 괄호로 묶은 것
  • 차원 : 행렬의 크기
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] l[1][2]
Out[-] 6
import numpy as np matrix = np.array(l) print(matrix.ndim) print(matrix.shape) # test = 3 # 스칼라 test= [[[[3, 2, 1, 3, 5, 4, 2]]]] # 괄호 개수 = 차원 수 test_matrix = np.array(test) print(test_matrix.ndim) print(test_matrix.shape)
Out[-] 2 (3, 3) 4 (1, 1, 1, 7)
matrix = np.arange(30).reshape(2, 3, 5) print(matrix) print(matrix[0][1][3])
Out[-] [[[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]] [[15 16 17 18 19] [20 21 22 23 24] [25 26 27 28 29]]] 8
matrix + matrix
Out[-] array([[[ 0, 2, 4, 6, 8], [10, 12, 14, 16, 18], [20, 22, 24, 26, 28]], [[30, 32, 34, 36, 38], [40, 42, 44, 46, 48], [50, 52, 54, 56, 58]]])
 

행렬의 연산

matrix = np.arange(15).reshape(3, 5) print(matrix)
Out[-] [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]]
print(matrix * 2) print(matrix / 2) print(matrix + 2) print(matrix - 2)
Out[-] [[ 0 2 4 6 8] [10 12 14 16 18] [20 22 24 26 28]] [[0. 0.5 1. 1.5 2. ] [2.5 3. 3.5 4. 4.5] [5. 5.5 6. 6.5 7. ]] [[ 2 3 4 5 6] [ 7 8 9 10 11] [12 13 14 15 16]] [[-2 -1 0 1 2] [ 3 4 5 6 7] [ 8 9 10 11 12]]
test = np.zeros((3,4)) test
Out[-] array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])
 

행렬의 곱셈

키보드 마우스 S 5000 8000 L 7000 3000 바울랩 키보드 31 마우스 40 5000*31 + 8000*40 7000*31 + 3000*40
x = np.array([[5000, 8000], [7000, 3000]]) y = np.array([[31], [40]]) print(x @ y) print(5000*31 + 8000*40) print(7000*31 + 3000*40)
Out[-] [[475000] [337000]] 475000 337000
 

행렬의 유형

  1. 단위 행렬 : 주 대각원소가 모두 1이고 나머지 원소가 0으로 이루어진 정사각행렬
  1. 정방 행렬 : 행과 열의 수가 같은 행렬
  1. 영행렬
      • 모든 원소가 0으로 이루어진 행렬
      • 반드시 정방행렬일 필요는 없음
      • 대수법칙의 덧셈의 항등원에 해당
  1. 전치 행렬 : 원래의 행렬의 행과 열을 바꾼 행렬
  1. 역행렬
      • 단위 행렬이 나오도록 특정 행렬에 곱하여진 정방 행렬
      • 행렬 A X B가 단위 행렬이 되면 A의 역행렬은 B
      • A와 B는 정방 행렬이어야 함. 단, 모든 정방 행렬이 역행렬을 가지는 것은 아님
       
오리와 양의 머리수 7 오리와 양의 다리수 22 이 문제를 행렬로 풀어보세요. 1x + 1y = 7 2x + 4y = 22 1 1 x 7 2 4 y 22
x = np.random.randint(1, 10, size=[3, 3]) print(x) y = np.linalg.inv(x) print(x @ y)
Out[-] [[5 6 5] [8 4 6] [5 1 4]] [[ 1.00000000e+00 -4.44089210e-16 2.22044605e-16] [ 0.00000000e+00 1.00000000e+00 -4.44089210e-16] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
x = np.array([[1, 1], [2, 4]]) y = np.linalg.inv(x) # np.linalg : 선형 대수 함수, inv : 역행렬 z = np.array([[7], [22]]) print(y @ z)
Out[-] [[3.] [4.]]
%matplotlib inline import matplotlib.pyplot as plt print(sum(matrix)) print(np.sum(matrix)) print(np.sum(matrix, axis=0)) print(np.sum(matrix, axis=1)) student = np.sum(matrix, axis=1) plt.bar([1,2,3],student) plt.show()
Out[-] [15 18 21 24 27] 105 [15 18 21 24 27] [10 35 60]
notion imagenotion image
print(matrix[matrix > 5]) print(matrix[matrix % 2 == 0])
Out[-] [ 6 7 8 9 10 11 12 13 14] [ 0 2 4 6 8 10 12 14]
print(matrix[matrix > 5]) print(matrix[matrix % 2 == 0]) print(matrix[1][2]) print(matrix[1, 2]) mask = matrix % 2 == 0 print(mask) print(matrix[mask])
Out[-] [ 6 7 8 9 10 11 12 13 14] [ 0 2 4 6 8 10 12 14] 7 7 [[ True False True False True] [False True False True False] [ True False True False True]] [ 0 2 4 6 8 10 12 14]