Skip to content

Latest commit

 

History

History
339 lines (278 loc) · 11.8 KB

211013.md

File metadata and controls

339 lines (278 loc) · 11.8 KB

Day 12

파이썬을 이용한 머신러닝, 딥러닝 실전 앱 개발 (3일차)


머신러닝 입문

최적의 알고리즘과 매개변수 찾기

최적의 알고리즘

붓꽃 분류 프로그램을 사용해 최적의 알고리즘을 찾는 방법

관점 고려할 점 해결 방법
1 알고리즘 선정 더 높은 정답률을 내는 다른 알고리즘이 있지는 않은가? 각각의 알고리즘으로 정답률을 구하고 비교하기
2 알고리즘 평가 데이터(학습 전용과 테스트 전용) 분류의 편향이 발생하지는 않았는가? 크로스 밸리데이션

각 알고리즘의 정답률 비교하기

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import warnings
from sklearn.utils import all_estimators

# 붓꽃 데이터를 레이블과 입력 데이터로 분리하기
iris_data = pd.read_csv('./data/iris.csv', encoding = 'utf-8')

# 붓꽃 데이터를 레이블과 입력 데이터로 분리하기
y = iris_data.loc[:, 'Name']
x = iris_data.loc[:, ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth']]

# 학습 전용과 테스트 전용 분리하기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, train_size = 0.8, shuffle = True)

# classifier 알고리즘 모두 추출하기
warnings.filterwarnings('ignore') # 경고를 무시하고 출력하지 않는다
allAlgorithms = all_estimators(type_filter='classifier') # 모든 classifier 알고리즘 추출, (알고리즘 이름, 알고리즘 클래스)형태로 반환

for (name, algorithm) in allAlgorithms:
    # 각 알고리즘 객체 생성하기
    try:
        clf = algorithm()

        # 학습하고 평가하기
        clf.fit(x_train, y_train)
        y_pred = clf.predict(x_test)
        print(name, '의 정답률 = ', accuracy_score(y_test, y_pred))
    except: # 가끔 필수적으로 인자를 줘야하는 경우가 있어서 에러가 발생, ClassifierChain에서 에러가 남, 예외처리
        pass

크로스 밸리데이션 (교차 검증)

  • 알고리즘의 타당성을 평가하는 방법의 하나

K-분할 밸리데이션 : 데이터를 K개의 그룹으로 분할하고, 'K-1개를 학습 전용 데이터, 남은 1개를 평가 전용 데이터로 사용해 평가'하는 것을 K번 반복하는 방법

  • 데이터를 A, B, C라는 3개의 그룹으로 분할
  • A와 B를 학습 전용 데이터, C를 평가 전용 데이터로 사용해 정답률을 구함
  • B와 C를 학습 전용 데이터, A를 평가 전용 데이터로 사용해 정답률을 구함
  • C와 A를 학습 전용 데이터, B를 평가 전용 데이터로 사용해 정답률을 구함

크로스 밸리데이션

import pandas as pd
from sklearn.utils import all_estimators
from sklearn.model_selection import KFold
import warnings
from sklearn.model_selection import cross_val_score

# 붓꽃 데이터
iris_data = pd.read_csv('./data/iris.csv', encoding = 'utf-8')

# 붓꽃 데이터를 레이블과 입력 데이터로 분리
y = iris_data.loc[:, 'Name']
x = iris_data.loc[:, ['SepalLength', 'SepalWidth','PetalLength','PetalWidth']]

# classifier 알고리즘 모두 추출하기
warnings.filterwarnings('ignore')
allAlgorithms = all_estimators(type_filter = 'classifier')

# K-분할 크로스 밸리데이션 전용 객체
kfold_cv = KFold(n_splits=5, shuffle=True) # 5-분할 크로스 밸리데이션, 

for (name, algorithm) in allAlgorithms:
    try:
        # 각 알고리즘 객체 생성하기
        clf = algorithm()
        
        # score 메서드를 가진 클래스를 대상으로 하기
        if hasattr(clf, 'score'): # cross_val_score는 score() 메소드가 있을 경우에만 사용 가능하므로 미리 확인
            # 크로스 밸리데이션
            scores = cross_val_score(clf, x, y, cv=kfold_cv) # cross_val_score(알고리즘 객체, 입력 데이터, 레이블 데이터, 크로스 밸리데이션 전용 객체)
            print(name, '의 정답률 = ')
            print(scores)
    except:
        pass

최적의 매개변수 찾기

하이퍼 파라미터 : 개발자가 직접 지정해야 하는 매개변수

그리드 서치 : 지정한 매개변수 패턴을 사용해서 정답률을 구하고 가장 정답률이 높은 패턴을 선택하는 방법

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
from sklearn.model_selection import GridSearchCV

# 붓꽃
iris_data = pd.read_csv('./data/iris.csv', encoding = 'utf-8')

# 레이블과 입력 데이터로 분리
y = iris_data.loc[:, 'Name']
x = iris_data.loc[:, ['SepalLength', 'SepalWidth','PetalLength','PetalWidth']]

# 학습 전용과 테스트 전용 분리
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, train_size = 0.8, shuffle = True)

# 그리드 서치에서 사용할 매개 변수
# 이번에는 SVC와 관련된 매개변수 몇 가지 지정
parameters = [
    {'C':[1, 10, 100, 1000], 'kernel':['linear']},
    {'C':[1, 10, 100, 1000], 'kernel':['rbf'], 'gamma':[0.001, 0.0001]},
    {'C':[1, 10, 100, 1000], 'kernel':['sigmoid'], 'gamma':[0.001, 0.0001]}
]

# 그리드 서치
kfold_cv = KFold(n_splits=5, shuffle = True)
clf = GridSearchCV(SVC(), parameters, cv = kfold_cv)
clf.fit(x_train, y_train)
print('최적의 매개 변수 =', clf.best_estimator_) # best_estimator로 최적의 매개 변수 확인 가능

# 최적의 매개 변수로 평가하기
y_pred = clf.predict(x_test)
print('최종 정답률 = ', accuracy_score(y_test, y_pred))

OpenCV와 머신러닝 - 이미지/동영상 입문

OpenCV

OpenCV : 오픈소스 이미지(동영상) 라이브러리

# 이미지 다운로드
import urllib.request as req
url = 'https://cdn.eyesmag.com/content/uploads/posts/2021/02/22/Keanu-reeves-refused-to-play-on-marvel-project-01-adcbb42a-f982-460b-9247-984016e1314b.jpg'
req.urlretrieve(url, './data/Keanu.png')

# OpenCV로 읽기
img = cv2.imread('./data/Keanu.png')
print(img)

imread()함수는 실패해도 None만 반환하고 예외를 전혀 발생하지 않음

이미지 인라인 출력

# 다운로드한 이미지 출력
import matplotlib.pyplot as plt
import cv2

%matplotlib inline

img = cv2.imread('./data/test.png')
plt.axis('off') # axis 출력하지 않음
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # BGR 에서 RGB로 변환, (255,0,0) -> (0,0,255), 바꾸지 않고 바로 출려하면 붉은색과 파란색이 반전돼 출력
plt.show()

OpenCV : BGR
matplotlib : RGB

이미지 저장, 크기 변경, 자르기

import cv2

# 이미지 읽어 들이기
img = cv2.imread('./data/test.png')

# 이미지 저장하기
cv2.imwrite('./data/out.jpg', img)

# 이미지 크기 변경
im2 = cv2.resize(img, (600,300))

# 이미지 자르기
im2 = img[50:150, 50:150] #[y1:y2, x1:x2]

# 이미지 출력
plt.axis('off')
plt.imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))
plt.show()

OpenCV 좌표계

이미지 왼쪽 위 부분이 (0,0)이고, 오른쪽과 아래로 갈수록 값이 커진다

얼굴 검출 - 자동으로 얼굴에 모자이크 처리하기

얼굴 인식

OpenCV는 Haar-like 특징 학습기라고 부느는 머신러닝을 사용해 얼굴 인식
얼굴 데이터베이스를 사용해 눈, 코, 입과 같은 요소의 위치 관계를 확인하고 얼굴인지 확인하는 방법
사람 얼굴 사진을 그레이스케일로 변환하여 명암 패턴을 확인하고 판단

얼굴 검출 과정 확인

  1. 케스케이드 파일을 지정해서 검출기 만들기
  2. 대상 이미지를 읽어 들이고 그레이스케일로 변환하기
  3. 얼굴 검출 실행하기
import matplotlib.pyplot as plt
import cv2

# 캐스케이드 파일 지정해서 검출기 생성
cascade_file = './data/haarcascade_frontalface_alt.xml'
cascade = cv2. CascadeClassifier(cascade_file)

# 이미지 읽고 그레이스케일로 변환
img = cv2.imread('./data/Keanu.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 얼굴 인식하기
face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))

# 결과 확인하기
if len(face_list) == 0:
    print('실패')
    quit()
    
# 인식한 부분 표시하기
for (x, y, w, h) in face_list:
    print('얼굴의 좌표 = ', x, y, w, h)
    red = (0, 0, 255)
    cv2.rectangle(img, (x, y), (x+w, y+h), red, thickness=20)
    
# 이미지 출력하기
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

모자이크 함수

import cv2

def mosaic(img, rect, size):
    # 모자이크 적용할 부분 추출하기
    (x1, y1, x2, y2) = rect
    w = x2 - x1
    h = y2 - y1
    i_rect = img[y1:y2, x1:x2]
    
    # 축소하고 확대하기
    i_small = cv2.resize(i_rect, (size, size))
    i_mos = cv2.resize(i_small, (w, h), interpolation=cv2.INTER_AREA)
    
    # 모자이크 적용하기
    img2 = img.copy()
    img2[y1:y2, x1:x2] = i_mos
    return img2

모자이크 처리

import matplotlib.pyplot as plt
import cv2

# 캐스케이드 파일 지정해서 검출기 생성
cascade_file = './data/haarcascade_frontalface_alt.xml'
cascade = cv2. CascadeClassifier(cascade_file)

# 이미지 읽고 그레이스케일로 변환
img = cv2.imread('./data/Keanu.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 얼굴 인식하기
face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))

# 결과 확인하기
if len(face_list) == 0:
    print('실패')
    quit()
    
# 인식한 부분 표시하기
for (x, y, w, h) in face_list:
    img = mosaic(img, (x, y, x+w, y+h), 10)
    
# 이미지 출력하기
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

OpenCV의 얼굴 검출은 옆모습과 기울어진 얼굴을 잘 검출하지 못한다

import matplotlib.pyplot as plt
import cv2
from scipy import ndimage

# 검출기 생성, 이미지 읽기
cascade_file = './data/haarcascade_frontalface_alt.xml'
cascade = cv2. CascadeClassifier(cascade_file)
img = cv2.imread('./data/Keanu.png')

# 얼굴 검출하고 영역 표시
def face_detect(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face_list = cascade.detectMultiScale(img_gray, minSize = (300, 300))
    # 인식한 영역 표시하기
    for (x, y, w, h) in face_list:
        print('얼굴의 좌표 = ', x, y, w, h)
        red = (0, 0, 255)
        cv2.rectangle(img, (x, y), (x+w, y+h), red, thickness = 20)
        
# 여러 각도의 이미지를 만들고 테스트
for i in range(0, 9):
    ang = i * 10
    print('--' + str(ang) + '--')
    img_r = ndimage.rotate(img, ang)
    face_detect(img_r)
    plt.subplot(3, 3, i + 1) # 여러 개의 그래프를 출력할 때 사용함
    plt.axis('off')
    plt.title('angle = ' + str(ang))
    plt.imshow(cv2.cvtColor(img_r, cv2.COLOR_BGR2RGB))
    
plt.show()

KFold(n_split=n, shuffle=True)

  • n_split : 데이터 분할 수 지정
  • 데이터를 분할할 때 랜덤하게 분할할지를 지정

cross_val_score(clf, x, y, cv)

  • clf : 알고리즘 객체
  • x : 입력 데이터
  • y : 레이블 데이터
  • cv : 크로스 밸리데이션 전용 객체
  • cv는 정숫값 지정 가능, 정숫값을 지정하면 실행시 알고리즘이 ClassifierMixin에서 파생되었다면 StartfiedKFold 클래스 그 외는 KFold 클래스 사용

GridSearchCV(A(), parameters, cv = kfold_cv)

  • A : 알고리즘 객체
  • parameters : 매개변수 리스트
  • cv : 크로스 밸리데이션 전용 객체

resize(img, (width, height))

cvtColor(img, )

  • GRAY : BGR2GRAY, GRAY2BGR, RGB2GRAY, GRAY2RGB
  • HSV
  • YCrCb : BGR2HSVYCrCb, YCrCb2BGR, RGB2HSVYCrCb, YCrCb2RGB
  • Luv