본문 바로가기
DB 공부하기

230322_DB복습

by 보랏 2023. 3. 22.

안녕하세요. 보랏입니다.

오늘은 머신러닝을 실제로 진행해보았으며(k-최근접 이웃 알고리즘),

코루틴, 데코레이터, 메모이제이션 등 다양한 개념을 배웠습니다.

 

바로 복습 시작하겠습니다.

 

1. 머신러닝(machine learning)

  • 규칙을 프로그래밍하지 않아도 자동으로 데이터에서 규칙을 학습하고 알고리즘을 연구하는 분야
  • 통계학과 딥러닝/머신러닝 용어 비교
통계학 딥러닝/머신러닝
모수 가중치
추정, 적합 학습
회귀 또는 분류 지도학습
군집화, 분포 추정 비지도학습
독립(설명)변수 특징
종속(반응)변수 레이블

 

2. 머신러닝 - 생선 데이터를 기반으로 도미와 빙어를 구분하기

  • 도미데이터 준비하기 
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

import matplotlib.pyplot as plt

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

  • 빙어 데이터 준비하기
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

3. K-최근접 이웃 알고리즘(K-Nearest Neighbors)

  • 숫자 K와 거리 측정 기준을 선택
  • 분류하려는 샘플에서 k개의 최근접 이웃
  • 다수결 투표를 통해 클래스 레이블을 할당

  • 생선 데이터 모으기 
fish_data = [[l,w] for i, w in zip(length, weight)]
print(fish_data)

  • 정답 데이터 만들기
fish_target = [1]*35 + [0]*14
print(fish_target)

  • K-최근접 이웃 알고리즘 구현 
from sklearn.neighbors import KNeighborsClassifier

### 임포트한 KNeighborsClassifier 클래스의 객체를 먼저 생성
kn = KNeighborsClassifier() 

### fish_data와 fist_target을 전달하여 도미를 찾기 위한 기준을 학습(=훈련)
### 사이킷런에서는 fit()메서드
kn.fit(fish_data, fish_target)

### 훈련이 얼마나 잘 되었는지 평가 
kn.score(fish_data, fish_target) -> 1.0

점수의 범위는 0~1사이로, 1은 100%로 점수는 정확도라고 부름
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.scatter(30, 600, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

  • 위의 그림에서 새로운 데이터(삼각형 모양)을 도미로 판단할 것 -> 삼각형 주변에 다른 도미 데이터가 많이 분포되어 있기 때문
kn.predict([[30, 600]])
-> array([1])
  • predict()메서드는 새로운 데이터의 정답을 예측 -> 리스트로 데이터 전달 필요
  • 도미는 1, 빙어는 0으로 해당 값은 도미로 판별되었습니다. 
print(kn._fit_X)

print(kn._y)

  • KNeighborsClassifier 클래스의 기본 값은 5로 하고, 이 기준은 n_neighbors 매개변수로 변경할 수 있음
### 정확도
kn49 = KNeighborsClassifier(n_neighbors=49)
kn49.fit(fish_data, fish_target)
kn49.score(fish_data, fish_target)
-> 0.7142857142857143

### 도미만을 올바르게 맞추기 위한 정확도 측정
print(35/49)
-> 0.7142857142857143

 

4. 데이터 전처리 

  • 데이터 준비하기 
import numpy as np

fish_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 
                31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0, 9.8, 
                10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
fish_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 
                500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 
                700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0, 6.7, 
                7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
  • np.column_stack()함수와 np.concatenate()함수의 연결 방식 확인하기 

np.column_stack(([1,2,3], [4,5,6]))

fish_data = np.column_stack((fish_length, fish_weight))
print(fish_data[:5])

### 도미와 빙어 1과 0으로 구분
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
print(fish_target)

  • 사이킷런으로 훈련 세트와 테스트 세트 나누기
    • train_test_split() 함수 : 전달되는 리스트나 배열을 비율에 맞게 훈련세트와 테스트 세트로 섞어서 나눔
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    fish_data, fish_target, random_state=42)
    
print(train_input.shape, test_input.shape)
-> (36, 2) (13, 2)

print(train_target.shape, test_target.shape)
-> (36,) (13,)

print(test_target)
-> [1. 0. 0. 0. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

 

  • 도미의 데이터를 입력해서 이상치 값 확인
import matplotlib.pyplot as plt

plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

  • 기준 맞추기 
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D')
plt.xlim((0, 1000))
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

  • 두 특성(길이와 무게)의 값이 놓인 범위가 매우 다릅니다. -> 이를 두 특성의 스케일(scale)이 다르다고 말함
  • 샘플 간의 거리에 영향을 많이 받으므로 제대로  사용하려면 특성값을 일정한 기준으로 맞춰 주어야 함 -> 데이터 전처리
    • 가장 널리 사용하는 전처리 방법 중 하나는 '표준점수'
mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)
train_scaled = (train_input - mean) / std

### 전처리 데이터로 모델 훈련
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(25, 150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
new = ([25, 150] - mean) / std

plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

5. Decorator 

  • 기존의 함수에서 추가적으로 프로세스를 추가하는 방법
def mydeco(func) : 
    def new_func() : 
        print("new_func_today : {}".format(datetime.date.today()))
        func() #func를 함수 변수로 받아 함수를 print_hi함수와 new_func함수 둘 다 실행
    return new_func
    
ph1 = mydeco(print_hi)
ph1()

ph2 = mydeco(lambda : print("ddd"))
ph2()

def deco3(func) : 
    def new_func() : 
        print("encore")
        func()
    return new_func
### @를 사용하면 현재창에 있는 함수는 @함수의 데코레이터로 사용됨
@deco3 
def print_hi3() : 
    print("hi en")
print_hi3()

6. Generator

  • yield 
    • 대부분의 프로그래밍 언어에서는 일반적으로 함수가 어떤 결과 값을 return을 이용해서 반환
    • 그러나 파이썬에서는 함수가 yield키워드를 이용해서 다소 다른 방식으로 결과값을 제공
  • Generator 
    • 여러 개의 데이터를 미리 만들어 놓지 않고 필요할 때마다 즉석으로 하나씩 만들어 낼 수 있는 객체
    • return은 반환 즉시 함수가 끝나지만 yield는 잠시 함수 바깥의 코드가 실행되도록 양보하여 값을 가져가게 한 뒤 다시 generator안의 코드를 계속 실행하는 방식
### return 방식
import time 

def return_abc():
  alphabets = []
  for ch in "ABC":
    time.sleep(1)
    alphabets.append(ch)
  return alphabets

-----------------------------------
for ch in return_abc():
  print(ch)

#3초 경과
A
B
C


### yield 방식
import time

def yield_abc():
  for ch in "ABC":
    time.sleep(1)
    yield ch

---------------------------------
for ch in return_abc():
  print(ch)

# 1초 경과
A
# 1초 경과
B
# 1초 경과
C

 

 

7. CO-routine(Cooperate routine)

  • 실행을 일시 중단하고 재개할 수 있도록 해서 비선점형 멀티태스킹을 위한 서브 루틴을 일반화하는 컴퓨터 프로그램 구성 요소
    • 선점형 멀티태스킹 : 컴퓨터 OS가 몇 가지 기준을 써서 다른 작업에 OS를 사용할 차례를 주기 전, 한 작업에 할당한 시간을 결정하는 작업 
    • 선점 : 한 작업에서 OS를 제어해서 다른 작업에 넘겨주는 행위 
def fib_generator() : 
    a, b = 0, 1
    while True : 
        yield b 
        a, b = b, a+b
        
fg = fib_generator()

print(next(fg))
-> 0,1,2,4부터 시작해서 계속해서 증가

 

8. 메모이제이션

  • 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술
from functools import wraps
#from benchmark import benchmark

def memo(func):
    cache = {} # 딕셔너리에 기록을 해서 중복이면 계산하지 않고 바로 리턴하는 방식으로 진행
    
    @wraps(func)
    def wrap(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrap

 

오늘은 새로운 알고리즘에 대해 많이 배웠습니다.

그런데 아직 해당 알고리즘에 대해 이해가 안가는 부분이 많아 다른 자료도 많이 찾아봐야될 것 같습니다.

 

오늘 복습은 이렇게 마무리 하겠습니다.

 

감사합니다. 

'DB 공부하기' 카테고리의 다른 글

230327_DB복습  (0) 2023.03.27
230323_DB복습  (0) 2023.03.23
230314_DB복습  (0) 2023.03.14
230313_DB복습  (0) 2023.03.13
230309_DB복습  (0) 2023.03.09