본문 바로가기
프로그램/SKT FLY AI

SKT FLY AI : 2일차 - 끄적이는 글(2). 머신러닝(기계학습)

by hsloth 2023. 6. 27.

데이터분석 회고

  • 데이터가 주어지면, 해당 데이터를 어떤식으로 활용해야하는지 판단을 못하겠다.
  • 그럴 때는, 일단 상관계수로 히트맵을 그려서 판단하자. 상관계수 높은 것들을 위주로 그래프를 작성해보자.
  • 데이터를 전처리하는 방법들을 모르겠다. 함수명도 모르겠고.
  • 답은 많이 코딩을 해보는 것인 것 같다.

머신러닝(기계학습)


  • 기계학습은 크게 "지도 학습", "비지도 학습", "강화 학습"으로 나뉜다.
  • 기계학습은 항상 입력을 받아서 출력하는 함수 y=f(x)를 학습한다고 생각할 수 있다. (함수 근사)

특징

  • 특징이란 우리가 학습 모델에게 공급하는 입력이다. 가장 간단한 경우에는 입력 자체가 특징이 된다.
  • ex) 이메일에 "광고", "선물 교환권"이나 "이벤트 당첨" 문자열 포함 여부

레이블

  • y = f(x)에서 y변수에 해당한다.
  • 농작물의 향후 가격, 사진에 표시도는 동물의 종류, 동영상의 의미 등 무엇이든지 레이블이 될 수 있다.

샘플 또는 예제

  • 샘플은 기계 학습에 주어지는 특정한 예이다.
  • y = f(x)에서 x에 해당한다.
  • 레이블이 있는 샘플도 있고, 레이블이 없는 샘플도 있다. 지도 학습을 시키려면 레이블이 있어야 한다.

K-최근접 이웃(K-Nearest Neighbor, KNN)


  • 사례기반 학습 알고리즘
  • 기존의 데이터를 기억하고 새로운 데이터는 가까운 k개의 데이터를 선택해서 다수인 클래스로 분류한다.
  • k가 너무 적으면 과대적합이 발생한다.
### 데이터 준비
import numpy as np
import pandas as pd
import seaborn as sns
df = sns.load_dataset("penguins")
df.head(10)

### 전체 데이터 개수와 피쳐의 개수 확인
print(df.shape)
df.info()

### species피쳐는 펭귄의 종류를 가지고 있다.
df["species"].value_counts()

### 결측치 (Null이나 NAN 값인듯??)
df.isnull().sum(axis=0)

### 결측치가 포함된 행을 삭제한다.
df = df.dropna()
df.isnull().sum(axis=0)

### 레이블 인코딩
df['species']= df['species'].map(
 {'Adelie':0,'Chinstrap':1, 'Gentoo':2}
)
df['island']= df['island'].map(
 {'Biscoe':0,'Dream':1, 'Torgersen':2}
)
df['sex']= 

### 시각화 - 산점도를 그려서 분포 확인
sns.set_style("darkgrid")
sns.scatterplot(x="bill_length_mm", y="bill_depth_mm",
 data=df, hue="species")
plt.show()

### 피쳐와 속성 분리
X = df.drop(['species'], axis=1) # drop해도 원본은 바뀌지 않는듯 하다.
y = df['species']
X.head()

### 테스트 데이터 분리
from sklearn.model_selection import train_test_split

# X와 y의 학습데이터와 테스트데이터를 분리한다.
# 이때, test_size는 전체 데이터의 20%
# random_state는 섞는 방식이라고 한다. 숫자가 같으면 같은 방식으로 섞인다고 한다!
X_train, X_test, y_train, y_test = train_test_split(X, y,
         test_size=20, random_state=42)
print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)

### 스케일링
from sklearn.preprocessing import StandardScaler

# 스케일링은 데이터의 특성별로 수치의 범위가 다르기 때문에, 영향이 적을거라고 판단될 수 있으므로
# 모든 특성의 범위(분포)를 같거나 비슷하게 맞춰주는 작업을 말한다.
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
y_train = y_train.values
X_train[:3, :]

### 테스트 데이터의 스케일링
X_test = sc.transform(X_test)
y_test = y_test.values

### 알고리즘 학습
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)

### 예측
y_pred = knn.predict(X_test)
print(y_pred)

### 평가
(y_test == y_pred).sum()

### 혼동행렬을 계산한다 - 뭔지 아직 잘 모르겠음. 모델의 성능을 평가하는 지표라고함.
from sklearn.metrics import confusion_matrix
cf = confusion_matrix(y_test, y_pred)
print(cf)

### 히트맵을 그린다
import seaborn as sns
s = sns.heatmap(cf, annot=True, cmap='Blues')
s.set(xlabel='Prediction', ylabel='Actual')
plt.show()

### 정확도, 재현율, 정밀도
from sklearn.metrics import *
acc = accuracy_score(y_test, y_pred)
print('accuracy_score : ',acc)
pre = precision_score(y_test, y_pred, average= "macro")
print('precision_score : ', pre)
recall = recall_score(y_test, y_pred, average= "macro")
print('recall_score: ', recall)




서포트 벡터 머신(SVM)


  • 모델 기반 학습 알고리즘
  • 기본적으로 두 개의 다른 클래스를 분류할 수 있는 하나의 선형식을 찾는 것
  • 복잡한 분류 문제에 적합하고, 선형, 비선형 모두 분류 가능
  • 결정 경계와 서포트 벡터 사이의 거리를 마진이라고 한다.
  • 하드 마진 : 마진 안에 어떠한 데이터도 포함되지 않도록 하는 것
  • 소프트 마진 : 일부 데이터가 마진 내에 들어오도록 허용하는 것
  • 서포트 벡터 : 점(예제?)이라고 생각하자.
from sklearn import svm. datasets

### 데이터 준비
cancer = datasets.load_breast_cancer()
cancer.keys()

### 데이터의 형태를 데이터 프레임으로 만든다.
dfX = pd.DataFrame(cancer.data, columns=cancer.feature_names)
dfy = pd.DataFrame(cancer.target, columns=['target'])
print('features :', dfX.shape)
print('label :', dfy.shape)

### 데이터 정보 표시

### 결측치 확인, 처리

### 테스트 데이터 준비
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(dfX, dfy,
         test_size=0.2, random_state=42)
print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)

### 데이터 스케일링
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
y_train = y_train.values
X_train[:3, :]

### 테스트 데이터 스케일링
X_test = sc.transform(X_test)
y_test = y_test.values

### 알고리즘 학습
## 데이터의 shape를 변경한다.
y_train = y_train.flatten()
## Linear Kernel을 사용해서 학습을 진행한다.
from sklearn.svm import SVC
svc = SVC(kernel="linear")
svc.fit(X_train, y_train)

### 예측
X_test = sc.transform(X_test)
y_test = y_test.values.flatten()
y_pred = svc.predict(X_test)
y_pred

### 평가
from sklearn.metrics import confusion_matrix
cf = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(6, 6))
s = sns.heatmap(cf, annot=True, fmt='d', cmap="Blues", cbar=False)
s.set(xlabel='Prediction', ylabel='Actual')
plt.show()

### 평가지표를 계산한다.
from sklearn.metrics import *
def print_scores(y_true, y_pred):
  print('accuracy_score: {0:.4f}'.format(
   accuracy_score(y_true, y_pred)))
  print('precision_score: {0:.4f}'.format(
   precision_score(y_true, y_pred)))
  print('recall_score: {0:.4f}'.format(
   recall_score(y_true, y_pred)))
print_scores(y_test, y_pred)

결정 트리(Decision Tree)


  • 분류와 회귀 모두 가능한 알고리즘
  • 특정 질문에 따라 예/아니오 질문을 이어가며 학습하며, 질문마다 두 개의 노드로 구분한다.
  • 맨 처음 질문을 Root Node라고 하고, 맨 마지막 노드를 Leaf Node라고 한다.
  • 정규화, 결측치 등의 데이터 전처리를 하지 않아도 된다.

사이킷런 ML 알고리즘의 데이터 기본 조건


  • 모든 데이터는 숫자형이어야 한다.
  • 데이터에 빈 값이 없어야 함(Null 안됨)

사이킷런 ML 알고리즘 적용 전 기본 처리 사항


결손값 처리

  • NAN, Null 값을 고정 값으로 변환
  • 평균값 대체, 해당 피쳐 제외 등
  • 주의 : Null값은 잘못 처리 시 예측 왜곡 심각

문자열 값 처리

  • 인코딩 처리하여 숫자형으로 변환
  • 카테고리형 피처는 코드값으로 표현
  • 텍스트 피처는 피처 벡터화 기법으로 벡터화
  • 불필요한 피처는 삭제처리
    • 주민번호, 단순 문자열 아이디 등