본문 바로가기
수업(국비지원)/Python

[Python] 머신러닝 - 지도학습(분류) 1. KNN

by byeolsub 2023. 4. 26.
2022-12-15 복습
지도 학습 : 기계학습시 정답 제시
   회귀 분석 : 예측. 회귀선을 이용하여 분석을 함.
               독립변수(설명변수) : 예측에 사용되는 데이터
               종속변수(목표변수, 예측변수) : 정답. 예측해야하는 데이터
               알고리즘 : LinearRegression
    분류 : 데이터 선택. 평가. yes or no
           KNN (k-Nearset-Neighbors) : 최근접이웃 알고리즘.
비지도 학습 : 기계학습시 정답 제시 안함
   주체와 가장 가까운 아이들끼리 군집화 하여 표시함

#################################
# 분류 : 지도학습
#  설명변수(독립변수)  
#  목표변수(종속변수) 
#  알고리즘 : KNN(k-Nearset-Neighbors)    
#             SVM(Support Vector Machine)
#             Decision Tree             
#################################

1. KKN


 📌

########### 1. 분류 : 지도학습
# titanic 데이터 로드
import seaborn as sns
import pandas as pd
df = sns.load_dataset("titanic")
df.info()

# 전처리
# deck 컬럼 제거 : 결측값이 너무 많다.
del df["deck"]

df["embarked"].unique()
# embarked 컬럼의 결측값을 최빈값(가장 많은 값)으로 변경하기
#1 최빈값 구하기
df["embarked"].value_counts().idxmax()
most_freq = df["embarked"].value_counts().idxmax()
most_freq

#2 변경하기
df["embarked"] = df["embarked"].fillna(most_freq)
df.info()

df.head()

df.head()
# 설명변수 선택하기 
# 중복된 내용도 있어서 전부 사용하지 않고 컬럼들을 선택함
df[["class","pclass"]] # pclass 선택
df[["embarked","embark_town"]] # embarked 선택

ndf = df[["survived","pclass","sex","age","sibsp","parch","embarked"]]

# age 결측값 존재. => 결측값이 있는 행을 제거
ndf = ndf.dropna(subset=['age'], axis=0)
ndf.info()


📌

########### 2. 원핫인코딩
'''
 원핫 인코딩 : 문자열혈 범주데이터를 모형이 인식하도록 숫자형으로 변형
      pandas에 있는 함수 사용.
      pd.get_dummies()
'''
# sex 원핫인코딩 하기
onhot_sex = pd.get_dummies(ndf["sex"])
onhot_sex

# ndf, onhot_sex 데이터 합하기
ndf = pd.concat([ndf, onhot_sex],axis=1)
ndf.info()

# sex 컬럼 제거하기
del ndf["sex"]

# embarked 원핫인코딩 하기
# prefix="town" : 컬럼 조회시 town_C, town_Q...이렇게 나오도록 설정함.
onhot_embarked = pd.get_dummies(ndf["embarked"],prefix="town")
onhot_embarked

# ndf,onhot_embarked 데이터 합하기
ndf = pd.concat([ndf, onhot_embarked],axis=1)

# embarked 컬럼 삭제하기
del ndf["embarked"]
ndf.info()

# 설명변수, 목표변수 결정
# 설명변수 : survived 컬럼 제외한 변수들
# 목표변수 : survived 컬럼
X = ndf[ndf.columns.difference(["survived"])]
Y = ndf["survived"]
X.info()


 📌

########### 3. 정규화
'''
  설명변수의 정규화 필요
      - 분석시 사용되는 변수의 값의 크기에 따라 영향을 미침
        age 컬럼 : 0 ~ 100 사이
      - 정규화 과정을 통해서 설명 변수의 값을 기준단위로 변경  
'''
from sklearn import preprocessing
import numpy as np
X = preprocessing.StandardScaler().fit(X).transform(X)
X[5]
X.shape

# 훈련데이터, 테스트데이터 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test =\\
    train_test_split(X,Y, test_size=0.3, random_state=10)
x_train.shape 
x_test.shape

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train, y_train)
y_hat = knn.predict(x_test)
y_hat[:20] # 예측 데이터
y_test.values[:20] # 실제 데이터


📌

########### 4.모형 성능 평가데이터
# 모형의 성능 평가하기
from sklearn import metrics
knn_report =\\
    metrics.classification_report(y_test, y_hat)
knn_report
'''
support : 전체 개수
accuracy(정확도) : 정확한 예측/전체데이터
precision(정밀도) : 실제 생존자 인원/생존자로 예측한 인원
recall(재현율, 민감도) : 생존자로 예측/실제 생존한 인원
f1-score(조화평균) : 정밀도와 재현율 값을 이용한 성능 평가지수
     2*(정밀도*재현율)/(정밀도 + 재현율)
macro avg : 평균의 평균값
nweighted avg : 가중치 평균

실제 생존자 : 0 0 0 0 1 1 1 1 1 1
예측 생존자 : 0 0 0 0 1 1 1 1 1 0
   정확도 : 9/10 = 0.9
   정밀도 : 5/5 = 1.0
   재현율 : 5/6 = 0.83333
'''


 📌

########### 5. 혼동행렬
knn_matrix = metrics.confusion_matrix(y_test, y_hat)
knn_matrix
'''     예측 0   1  
실제 0   [109,  16]
    1   [ 25,  65]
   
  TN : 109 : 실제 0, 예측 0
  FP : 16  : 실제 0, 예측 1
  FN : 25  : 실제 1, 예측 0
  TP : 65  : 실제 1, 예측 1  

 실제와 같은 예측 : TN, TP
 실제와 다른 예측 : FN, FP
 
 정확도 : 정답/전체 데이터 (TP+TN)/(TP+TN+FP+FN)
          174/215 = 0.809...
          
 정밀도 : 실제 생존자/생존자로 예측한 인원  (TP)/(TP+FP)      
          65/81 = 0.8024...
          
 재현율 : 실제 생존자 중 생존으로 예측한 사람 /실제 생존자   (TP)/(TP+FN)    
          65/90 = 0.7222...    
'''

from sklearn.metrics import accuracy_score,\\
    precision_score, recall_score, f1_score
print("정확도(accuracy): %.3f" %\\
      accuracy_score(y_test, y_hat))
print("정밀도(Precision) : %.3f" %\\
      precision_score(y_test, y_hat)) 
print("재현율(Recall) : %.3f" %\\
      recall_score(y_test, y_hat))
print("F1-score : %.3f" %\\
      f1_score(y_test, y_hat))