PYTHON

20200327 - 파이썬 머신러닝(얼굴 자동 모자이크, 당뇨병 예측, 분류 평가)

낫싱 2020. 3. 27. 17:36
728x90
반응형

 

ml_openCV_0327호지수 - Jupyter Notebook.pdf
1.10MB
ml_모델링평가_0327호지수 - Jupyter Notebook.pdf
0.41MB
ml_평가연습_피마인디언당뇨병예측_호지수 - Jupyter Notebook.pdf
0.25MB
ml_openCV_0327호지수.ipynb
0.87MB
ml_모델링평가_0327호지수.ipynb
0.02MB
ml_평가연습_피마인디언당뇨병예측_호지수.ipynb
0.02MB

 

참고용 사이트

www.kdata.or.kr

www.dbguide.net - 교육과정(기초교육) - 데이터 수집, 인공신경만 딥러닝, R을 이용한 통계분석

kmooc.kr

udacity.com

https://www.edx.org/

coursera.org

미국 석사 학위 취득 방법 : 학비 약 1,000만원(2년)

https://www.cc.gatech.edu/future/masters/mscs/program

유튜브 : 성김

 

얼굴인식 오픈소스

https://github.com/opencv/opencv/tree/master/data/haarcascades

 

 

분류 평가

정확도만으로 불균형한 레이블 데이터 세트에서 평가지표로 사용하기에는 부적합

정확도가 가지는 분류 평가 지표로의 한계점을 극복하기 위해 여러 가지 분류 지표와 함께 적용해야 함

 

Confusion Matrix(혼동행렬, 오차행렬)

이진 분류에서 성능 지표로 잘 활용되는 오차행렬(혼동행렬)은 학습된 분류 모델이 예측을 수행하면 얼마나 혼동될 수 있는지도 함께 보여주는 지표임

이진 분류의 예측 오류가 얼마인지와 더불어 어떠한 유형의 예측오류가 발생하고 있는지를 함께 보여줌.

 

평가 지표

 

모델에서 예측을 참 으로 했냐 거짓으로 했냐가 뒤에 붙은 N ,P

 

실제값이랑 비교했을때 실제랑 같으면 앞에 True, 다르면 False

 

TP, FP, FN, TP는 예측 클래스와 실제 클래스의 Positive 결정 값과 Negative 결정 값의 결합에 따라 결정

앞문자 True/False는 예측값과 실제값이 같은가/틀린가를 의미하고 뒤 문자 Negative/Positive는 예측 결과 값이 부정/긍정을 의미

TN는 예측값을 Negative값 0으로 예측했고 실제값 역시 Negative 값0

FP는 예측값을 Positive 값 1로 예측했고 실제값은 Negative 값 0

FN은 예측값을 Negative 값 0으로 예측했고 실제값은 Positive 값 1

TP는 예측값을 Positive 값 1로 예측했고 실제값 역시 Positive 값 1

정확도(accuracy) = (TP + TN) / (TP+TN+FP+FN)

정밀도 = TP / (TP+FP) : P로 예측한 것 중에서 실제도 P

재현율 = TP / (TP+FN) : 실제 P인 것 중에서 예측도 P

F1 = 2 (정밀도 재현율) / (정밀도 + 재현율) : 정밀도와 재현율이 어느 한쪽으로 치우치지 않는 수치를 나타낼 때 높아짐

정밀도와 재현율은 Positive 데이터 세트의 예측 성능에 좀 더 초점을 맞춘 평가 지표

재현율이 중요 지표인 경우는 실제 Positive 양성 데이터를 Negative로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우 (ex.보험사기)

정밀도가 더 중요한 지표인 사례는 스팸 메일 여부를 판단하는 경우로 스팸 메일이 아닌데 스팸 메일로 분류해서 업무 차질 발생

In [1]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

TN = 143

FP = 15

FN = 37

TP = 67

accuracy = ((TP+TN) / (TP+TN+FP+FN))

precision = TP / (TP+FP)

recall = TP / (TP+FN)

F1 = 2 * (precision*recall) / (precision+recall)

 

print('accuracy : ',accuracy)

print('precision : ',precision)

print('recall : ',recall)

print('F1 : ',F1)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

accuracy : 0.8015267175572519 precision : 0.8170731707317073 recall : 0.6442307692307693 F1 : 0.7204301075268817

In [2]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import pandas as pd

import numpy as np

 

pd.set_option('display.max_columns', 15)

titanic_df=pd.read_csv('titanic3.csv')

 

from sklearn.preprocessing import LabelEncoder

# Null 처리 함수

def fillna(df):

df['age'].fillna(df['age'].mean(), inplace=True)

df['cabin'].fillna('N', inplace=True)

df['fare'].fillna(df['fare'].mean(), inplace=True)

df['embarked'].fillna('N', inplace=True)

return df

 

def drop_features(df):

df.drop(['home.dest','boat','body','name','ticket'], axis=1, inplace=True)

return df

 

def format_features(df):

df['cabin'] = df['cabin'].str[:1]

features = ['cabin','sex','embarked']

for feature in features:

le = LabelEncoder()

df[feature] = le.fit_transform(df[feature])

return df

 

def transform_features(df):

df = fillna(df)

df = drop_features(df)

df = format_features(df)

return df

 

t_df = transform_features(titanic_df)

t_df.to_pickle('t_df.pkl')

 

from sklearn import preprocessing

from sklearn.model_selection import train_test_split

 

# 독립변수, 종속변수 분리

X = t_df[['pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'cabin', 'embarked']]

y = t_df['survived']

 

# 독립변수 정규화(평균 0, 분산1인 표준정규분포)

X = preprocessing.StandardScaler().fit(X).transform(X) # StandardScaler : 표준정규분포

 

# 학습용 데이터와 평가용 데이터를 8:2로 분리

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10)

 

# SVM

from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, f1_score

from sklearn.metrics import classification_report

from sklearn import svm

# 벡터 공간으로 매핑하는 함수를 커널이라고 함

# kernal = 'rbf' 옵션으로 RBF(Radial Basis Function) 함수를 적용

 

svm_model = svm.SVC(kernel='rbf', random_state=0) # random_state=0 으로 정해서 예측치 변동이 생기지 않게 한다.

# kernel : 구분하는 선을 기준으로 선과 데이터의 거리가 margin이다.

# 하지만, 하나의 선으로 분류할 수 있는 경우는 거의 없기 때문에 1차원을 2차원으로 만들고, 2차원을 3차원으로 만든다.

# 선을 차원으로 바꿔주는 것이 kernel.

 

svm_model.fit(X_train, y_train)

s_pred = svm_model.predict(X_test)

 

s_accuracy = accuracy_score(y_test, s_pred)

print('s 예측 정확도 :', s_accuracy)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

s 예측 정확도 : 0.8015267175572519

정밀도 및 재현율 활용시 유의사항

정밀도와 재현율 성능 수치는 어느 한쪽만 참조하면 극단적인 수치 조작이 가능

정밀도 100%가 되는 방법 : 확실한 기준이 되는 경우만 Positive로 예측하고 나머지는 모두 Negative로 예측 전체 환자 1000명 중 확실한 Positive징후만 가진 환자는 단1명 이라고 하면, 이 한명만 P로 예측하고 나머지는 모두 N으로 예측 FP는 0, TP는 1이 되며 정밀도 (TP/(TP+FP)는 1/(1+0)=1

재현율이 100%가 되는 방법 : 모든 환자를 Positive로 예측 1000명의 환자 중 실제 양성인 사람이 30명 정도라도 TN이 수치에 포함되지 않고 FN은 0 이므로 재현율 (TP/(TP+FN)은 30/(30+0) =1

분류가 정밀도, 재현율 중 하나에 상대적인 중요도를 부여할 수 있지만 하나만 강조해서는 안됨

암 예측 모델에서 재현율을 높인다고 주로 양성만 판정한다면 환자의 부담과 불평이 커지게 됨

In [3]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

def accuracy(TP,TN,FP,FN):

accuracy=((TP+TN) / (TP+TN+FP+FN))

return accuracy

 

def precision(TP,FP):

precision=TP / (TP+FP)

return precision

 

def recall(TP,FN):

recall = TP / (TP+FN)

return recall

 

def F1(precision,recall):

F1=2* (precision*recall) / (precision+recall)

return F1

 

# confusion matrix

confusion = confusion_matrix(y_test, s_pred)

print(confusion)

#[[143 15] 생존자 기준일 때, 143이 TN, 15가 FP에 해당

# [ 37 67]] 37이 FN에, 67이 TP에 해당

 

#생존자 기준

TP = 67

TN = 143

FP = 15

FN = 37

 

acc=accuracy(TP,TN,FP,FN) # 생존률과 사망률 둘다 비슷하다

pre=precision(TP,FP) # 정밀도

recall=recall(TP,FN) #재현율

F1=F1(pre,recall)

print(acc, pre, recall, F1)

 

svm_report = classification_report(y_test, s_pred)

print(svm_report)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

[[143 15] [ 37 67]] 0.8015267175572519 0.8170731707317073 0.6442307692307693 0.7204301075268817 precision recall f1-score support 0 0.79 0.91 0.85 158 1 0.82 0.64 0.72 104 accuracy 0.80 262 macro avg 0.81 0.77 0.78 262 weighted avg 0.80 0.80 0.80 262

In [4]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# 사망자 기준

TN = 67

TP = 143

FN = 15

FP = 37

 

acc=accuracy(TP,TN,FP,FN)

pre=precision(TP,FP)

recall= TP / (TP+FN)

F1= 2 * (pre*recall) / (pre+recall)

print(acc, pre, recall, F1)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

0.8015267175572519 0.7944444444444444 0.9050632911392406 0.8461538461538461

In [5]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, f1_score

 

def get_clf_eval(y_test, s_pred):

confusion = confusion_matrix(y_test, s_pred)

accuracy = accuracy_score(y_test, s_pred)

precision = precision_score(y_test, s_pred)

recall = recall_score(y_test, s_pred)

f1 = f1_score(y_test, s_pred)

 

print('오차행렬')

print(confusion)

print()

print('정확도 : {0:.4f}, 정밀도 {1:.4f}, 재현율 : {2:.4f}, F1:{3:.4f}'.format(accuracy, precision, recall, f1))

 

get_clf_eval(y_test, s_pred)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

오차행렬 [[143 15] [ 37 67]] 정확도 : 0.8015, 정밀도 0.8171, 재현율 : 0.6442, F1:0.7204

In [6]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

from sklearn.model_selection import train_test_split

from sklearn.linear_model import LogisticRegression

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import accuracy_score

import warnings

warnings.filterwarnings('ignore')

 

t_df = pd.read_pickle('t_df.pkl')

 

y_df = t_df.survived

X_df = t_df.drop('survived', axis=1)

 

# 학습용 평가용 데이터 분리

X_train, X_test, y_train, y_test = train_test_split(X_df, y_df, test_size=0.2, random_state=11)

 

# 분류기 객체 생성

lr_clf = LogisticRegression(random_state=11)

# dt_clf = DecisionTreeClassifier(random_state=11)

# rf_clf = RandomForestClassifier(random_state=11)

 

# GridSearchCV : 파라미터를 통해 성능을 튜닝. (타이타닉 생존률을 해결하기 위해 필요한 작업)

from sklearn.model_selection import GridSearchCV

from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, f1_score

 

parameters = parameters = {'penalty':['l2','l1'],'C':[0.01,0.1,1,1,5,10]}

 

grid_lrlf = GridSearchCV(lr_clf, param_grid=parameters, scoring='accuracy', cv=5, refit=True)

 

display(grid_lrlf)

grid_lrlf.fit(X_train, y_train)

 

print('GridSearchCV 최적 하이퍼 파라미터:', grid_lrlf.best_params_)

 

print('GridSearchCV 최고 정확도:', grid_lrlf.best_score_)

 

best_lrlf = grid_lrlf.best_estimator_

display(best_lrlf)

dpredictions = best_lrlf.predict(X_test)

accuracy = accuracy_score(y_test, dpredictions)

 

def get_clf_eval(y_test, dpredictions):

confusion = confusion_matrix(y_test, dpredictions)

accuracy = accuracy_score(y_test, dpredictions)

precision = precision_score(y_test, dpredictions)

recall = recall_score(y_test, dpredictions)

f1 = f1_score(y_test, dpredictions)

 

print('오차행렬')

print(confusion)

print()

print('정확도 : {0:.4f}, 정밀도 {1:.4f}, 재현율 : {2:.4f}, F1:{3:.4f}'.format(accuracy, precision, recall, f1))

 

get_clf_eval(y_test, dpredictions)

 

print('Logistic Regression GSCV 예측 정확도 : ', accuracy)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

GridSearchCV(cv=5, error_score=nan, estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, l1_ratio=None, max_iter=100, multi_class='auto', n_jobs=None, penalty='l2', random_state=11, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False), iid='deprecated', n_jobs=None, param_grid={'C': [0.01, 0.1, 1, 1, 5, 10], 'penalty': ['l2', 'l1']}, pre_dispatch='2*n_jobs', refit=True, return_train_score=False, scoring='accuracy', verbose=0)

GridSearchCV 최적 하이퍼 파라미터: {'C': 1, 'penalty': 'l2'} GridSearchCV 최고 정확도: 0.7841330599225337

LogisticRegression(C=1, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, l1_ratio=None, max_iter=100, multi_class='auto', n_jobs=None, penalty='l2', random_state=11, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False)

오차행렬 [[139 17] [ 30 76]] 정확도 : 0.8206, 정밀도 0.8172, 재현율 : 0.7170, F1:0.7638 Logistic Regression GSCV 예측 정확도 : 0.8206106870229007

In [ ]:


Q. 피마 인디언 당뇨병 예측모델을 만들고 아래사항을 수행하세요.

diabetes.csv

데이터 세트는 북아메리카 피마 지역 원주민의 Type-2 당뇨병 결과 데이터임.

고립된 지역에서 인디언 고유의 혈통이 지속돼 왔지만 20세기 후반에 들어서면서 서구화된 식습관으로 많은 당뇨 환자 발생

Logistic Regression 을 사용하여 예측모델을 만들고 평가 지표함수를 이용, 정확도, 정밀도, 재현율, F1 Score를 출력

In [5]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# 768개의 데이터중에서 Negative 값 0이 500개, Positive값 1이 268개임

 

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

 

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score

from sklearn.metrics import f1_score, confusion_matrix, precision_recall_curve, roc_curve

from sklearn.preprocessing import StandardScaler

from sklearn.linear_model import LogisticRegression

import warnings

warnings.filterwarnings('ignore')

 

diabetes_data = pd.read_csv('diabetes.csv')

print(diabetes_data['Outcome'].value_counts()) # 타겟값이 어떻게 되어있는지 확인해야함

diabetes_data.head(3)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

0 500 1 268 Name: Outcome, dtype: int64

Out[5]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 1열 선택1열 다음에 열 추가
  • 2열 선택2열 다음에 열 추가
  • 3열 선택3열 다음에 열 추가
  • 4열 선택4열 다음에 열 추가
  • 5열 선택5열 다음에 열 추가
  • 6열 선택6열 다음에 열 추가
  • 7열 선택7열 다음에 열 추가
  • 8열 선택8열 다음에 열 추가
  • 9열 선택9열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가
  • 1행 선택1행 다음에 행 추가
  • 2행 선택2행 다음에 행 추가
  • 3행 선택3행 다음에 행 추가

열 너비 조절

행 높이 조절

 

Pregnancies

Glucose

BloodPressure

SkinThickness

Insulin

BMI

DiabetesPedigreeFunction

Age

Outcome

0

6

148

72

35

0

33.6

0.627

50

1

1

1

85

66

29

0

26.6

0.351

31

0

2

8

183

64

0

0

23.3

0.672

32

1

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

In [2]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

count, bin_dividers = np.histogram(diabetes_data['BMI'], bins=5)

display(bin_dividers)

 

bin_names = ['저체중', '보통체중', '경도비만', '비만', '고도비만']

 

diabetes_data['BMI_bin'] = pd.cut(x=diabetes_data['BMI'],

bins=bin_dividers,

labels=bin_names,

include_lowest=True)

 

BMI_dummies = pd.get_dummies(diabetes_data['BMI_bin'])

diabetes_data['BMI_bin'] = BMI_dummies

diabetes_data.drop('BMI', axis=1, inplace=True)

diabetes_data.head()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

array([ 0. , 13.42, 26.84, 40.26, 53.68, 67.1 ])

Out[2]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 1열 선택1열 다음에 열 추가
  • 2열 선택2열 다음에 열 추가
  • 3열 선택3열 다음에 열 추가
  • 4열 선택4열 다음에 열 추가
  • 5열 선택5열 다음에 열 추가
  • 6열 선택6열 다음에 열 추가
  • 7열 선택7열 다음에 열 추가
  • 8열 선택8열 다음에 열 추가
  • 9열 선택9열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가
  • 1행 선택1행 다음에 행 추가
  • 2행 선택2행 다음에 행 추가
  • 3행 선택3행 다음에 행 추가
  • 4행 선택4행 다음에 행 추가
  • 5행 선택5행 다음에 행 추가

열 너비 조절

행 높이 조절

 

Pregnancies

Glucose

BloodPressure

SkinThickness

Insulin

DiabetesPedigreeFunction

Age

Outcome

BMI_bin

0

6

148

72

35

0

0.627

50

1

0

1

1

85

66

29

0

0.351

31

0

0

2

8

183

64

0

0

0.672

32

1

0

3

1

89

66

23

94

0.167

21

0

0

4

0

137

40

35

168

2.288

33

1

0

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

In [3]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

count, bin_dividers = np.histogram(diabetes_data['BloodPressure'], bins=4)

display(bin_dividers)

 

bin_names = ['저혈압', '정상', '고혈압', '초고혈압']

 

diabetes_data['BloodPressure_bin'] = pd.cut(x=diabetes_data['BloodPressure'],

bins=bin_dividers,

labels=bin_names,

include_lowest=True)

 

BloodPressure_dummies = pd.get_dummies(diabetes_data['BloodPressure_bin'])

diabetes_data['BloodPressure_bin'] = BloodPressure_dummies

diabetes_data.drop('BloodPressure', axis=1, inplace=True)

diabetes_data.head()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

array([ 0. , 30.5, 61. , 91.5, 122. ])

Out[3]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 1열 선택1열 다음에 열 추가
  • 2열 선택2열 다음에 열 추가
  • 3열 선택3열 다음에 열 추가
  • 4열 선택4열 다음에 열 추가
  • 5열 선택5열 다음에 열 추가
  • 6열 선택6열 다음에 열 추가
  • 7열 선택7열 다음에 열 추가
  • 8열 선택8열 다음에 열 추가
  • 9열 선택9열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가
  • 1행 선택1행 다음에 행 추가
  • 2행 선택2행 다음에 행 추가
  • 3행 선택3행 다음에 행 추가
  • 4행 선택4행 다음에 행 추가
  • 5행 선택5행 다음에 행 추가

열 너비 조절

행 높이 조절

 

Pregnancies

Glucose

SkinThickness

Insulin

DiabetesPedigreeFunction

Age

Outcome

BMI_bin

BloodPressure_bin

0

6

148

35

0

0.627

50

1

0

0

1

1

85

29

0

0.351

31

0

0

0

2

8

183

0

0

0.672

32

1

0

0

3

1

89

23

94

0.167

21

0

0

0

4

0

137

35

168

2.288

33

1

0

0

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

In [4]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

def get_clf_eval(y_test, pred): # 매개변수값에 None 이라고 적힌것은 특별히 의미있는 값은 아님

confusion = confusion_matrix(y_test, pred)

accuracy = accuracy_score(y_test, pred)

precision = precision_score(y_test, pred)

recall = recall_score(y_test, pred)

f1 = f1_score(y_test, pred)

 

print('오차행렬')

print(confusion)

print()

print('정확도 : {0:.4f}, 정밀도 {1:.4f}, 재현율 : {2:.4f}, F1:{3:.4f}'.format(accuracy, precision, recall, f1))

 

#독립변수, 종속변수 나누기

y_df = diabetes_data.Outcome

X_df = diabetes_data.drop('Outcome', axis=1)

 

#정규화 작업

scaler = StandardScaler()

data_scaled = scaler.fit_transform(X_df)

 

# 학습용 평가용 데이터 분리

X_train, X_test, y_train, y_test = train_test_split(data_scaled, y_df, test_size=0.2, random_state=156, stratify=y_df)

 

# 분류기 객체 생성

lr_clf = LogisticRegression()

 

lr_clf.fit(X_train , y_train)

pred = lr_clf.predict(X_test)

get_clf_eval(y_test , pred)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

오차행렬 [[89 11] [24 30]] 정확도 : 0.7727, 정밀도 0.7317, 재현율 : 0.5556, F1:0.6316

 


Open CV

Open Source Computer Vision Library는 오픈소스 이미지(동영상) 라이브러리

이미지 형식 변환, 필터 처리, 얼굴 인식, 물체 인식, 문자 인식 등 이미지와 관련된 다양한 처리

머신러닝에서 OpenCV 사용 : 머신러닝의 입력으로 전달하려면 이미지를 숫자 배열 데이터로 변경

pip install opencv-python

In [1]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

!pip install opencv-python

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

Requirement already satisfied: opencv-python in c:\users\user\anaconda3\envs\ml_python\lib\site-packages (4.2.0.32) Requirement already satisfied: numpy>=1.14.5 in c:\users\user\anaconda3\envs\ml_python\lib\site-packages (from opencv-python) (1.18.1)

In [2]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# 이미지 다운로드

import urllib.request as req

import cv2

url = 'http://uta.pw/shodou/img/28/214.png'

req.urlretrieve(url, 'test.png') # url리트라이브로 주소에 있는것을 가져온다. 거기에 test.png라고 이름 부여

# OpenCV로 읽어들이기

img = cv2.imread('test.png') #cv2를 이용해서 imread함수로 이미지를 숫자로 바꿔주는 것

print(img)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

[[[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] ... [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]]]

In [3]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# 다운로드한 이미지 출력하기

import matplotlib.pyplot as plt

import cv2

%matplotlib inline

 

filepath = 'girl.jpg'

img = cv2.imread(filepath) # 이미지를 숫자로 변경

plt.axis('off') # axis 출력 끄기(눈금자 끄기)

# openCV BGR(파녹빨) 인 반면 matplotlib RGB(빨녹파) 순서

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

plt.show()

plt.close()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

In [4]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import cv2

 

# 이미지 읽어 들이기

filepath = 'girl.jpg'

img = cv2.imread(filepath)

 

# 이미지 저장하기

cv2.imwrite("out.png", img)

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

Out[4]:

True

In [5]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import matplotlib.pyplot as plt

import cv2

 

# 이미지 읽어들이기

img = cv2.imread('out.png') # 이미지 파일 읽어오기

# plt.axis('off')

# 이미지 크기 변경하기

im2 = cv2.resize(img, (500,600)) #img, (width, height)

# 크기 변경한 이미지 저장하기

cv2.imwrite('out-resize.png', im2) # imwrite 는 im2를 ''이름으로 저장

 

# 이미지 출력하기

plt.imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))

plt.show()

plt.close()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

In [19]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import matplotlib.pyplot as plt

import cv2

 

# 이미지 읽어 들이기

img = cv2.imread('out.png')

# plt.axis('off')

# 이미지 자르기

im2 = img[360:660,400:640]

#이미지 크기 변경

im2 = cv2.resize(im2, (400, 500))

# 크기 변경한 이미지 저장

cv2.imwrite('cut-resize.png', img)

 

#이미지 출력하기

plt.imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))

# plt.imshow(im2) # 활성화 하면 BGR 로 나오게된다.(이상한 색)

plt.show()

plt.close()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

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

인간의 얼굴이 어디 있는지 검출

사람의 얼굴을 검출하고 자동으로 모자이크 처리 \ 사생활 보호를 위해 관계없는 사람의 얼굴 자동으로 모자이크 처리 \ 얼굴 인식을 사용해 사람 얼굴이 있는 사진을 자동으로 수집

In [26]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import numpy as np

import matplotlib.pyplot as plt

import cv2

 

# 캐스케이스 파일 지정해서 검출기 생성하기

# openCV는 haar-like 특징 학습기라고 부르는 머신러닝을 사용해 얼굴 인식

# 캐스케이드 파일(얼굴요소 DB)를 사용해 눈, 코, 입과 같은 요소의 위치 관계를 확인하고

# 얼굴인지 확인(정면, 웃는얼굴, 눈, 몸, 전체 검출 등 다양한 캐스케이스 파일)

# http://github.com/opencv/opencv/tree/master/data/haarcascades

cascade_file = 'haarcascade_frontalface_alt.xml' # 캐스케이드 파일, 정면얼굴에 대한 DB

cascade = cv2.CascadeClassifier(cascade_file) # 얼굴 검출기에다가 DB를 입력해서 자동분류처리

 

# 이미지를 읽어 들이고 그레이스케일로 변환하기( 명암 패턴을 결합해 얼굴 형태 확인 )

filepath = 'girl.jpg'

img = cv2.imread(filepath)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# print(img_gray)

 

# 얼굴 인식하기

face_list = cascade.detectMultiScale(img_gray, minSize=(150,150)) # 그레이스케일 한 이미지로 얼굴 인식

# print(face_list)

 

#결과 확인하기

if len(face_list)==0:

print('얼굴 인식 실패')

quit()

 

#인식한 부분 표시하기 --(*5)

for (x,y,w,h) in face_list:

print("얼굴의 좌표=",x,y,w,h)

yellow = (0,255,255)

cv2.rectangle(img, (x,y), (x+w, y+h), yellow, thickness=7)

 

#이미지 출력하기

cv2.imwrite("face-detect.png", img)

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

plt.show()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

얼굴의 좌표= 319 308 405 405

대표사진 삭제

사진 설명을 입력하세요.

In [21]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

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

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

In [27]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

img = cv2.imread('cat.png')

#이미지 출력하기

cv2.imwrite('cat.png', img)

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

plt.show()

plt.close()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

In [36]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

import matplotlib.pyplot as plt

import cv2

from mosaic import mosaic as mosaic

 

# 이미지를 읽어 들이고 모자이크 처리하기

img = cv2.imread('cat.png')

mos = mosaic(img, (0,50,250,450),15) # ), 10) 숫자 조절로 모자이크 농도 조절 가능

 

#이미지 출력하기

cv2.imwrite('cat-mosaic.png', mos)

plt.imshow(cv2.cvtColor(mos, cv2.COLOR_BGR2RGB))

plt.show()

plt.close()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

In [42]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# 사람 얼굴에 자동으로 모자이크 처리

 

# 캐스케이드 파일 지정해서 검출기 생성하기

cascade_file = 'haarcascade_frontalface_alt.xml'

cascade = cv2.CascadeClassifier(cascade_file)

 

# 이미지를 읽어 들이고 그레이스케일로 변환

img = cv2.imread('family.jpg')

# img = cv2.imread('myphoto.jpg')

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

 

#얼굴 검출하기

face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))

if len(face_list) ==0:

quit()

 

# 인식한 부분에 모자이크 처리하기

for (x,y,w,h) in face_list:

img = mosaic(img, (x, y, x+w, y+h), 15)

 

# 이미지 출력하기

cv2.imwrite('family-mosaic.png', img)

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

plt.show()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

In [46]:

셀 전체 선택

  • 0열 선택0열 다음에 열 추가
  • 0행 선택0행 다음에 행 추가

열 너비 조절

행 높이 조절

# Open CV 의 얼굴 검출은 옆모습과 기울어진 얼굴을 잘 검출 못함

 

import matplotlib.pyplot as plt

import cv2

from scipy import ndimage

 

# 캐스케이드 파일 지정해서 검출기 생성하기

cascade_file = 'haarcascade_frontalface_alt.xml'

cascade = cv2.CascadeClassifier(cascade_file)

img = cv2.imread('girl.jpg')

 

# 얼굴 검출하고 영역 표시하기

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)

yellow = (0,255,255)

cv2.rectangle(img, (x,y), (x+w, y+h), yellow, thickness=7)

 

# 여러 각도의 이미지를 만들고 테스트 하기

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()

  • 셀 병합
  • 행 분할
  • 열 분할
  • 너비 맞춤
  • 삭제

대표사진 삭제

사진 설명을 입력하세요.

===0=== 얼굴의 좌표= 319 308 405 405 ===10=== 얼굴의 좌표= 394 385 409 409 ===20=== 얼굴의 좌표= 451 444 408 408 ===30=== 얼굴의 좌표= 494 483 409 409 ===40=== ===50=== ===60=== ===70=== ===80===

 

728x90
반응형