FLY AI 4기 4일차: SVM 실습

염지현·2023년 12월 27일

FLY AI 4기

목록 보기
5/16

4일차: SVM 실습

4일차 요약

  • 오전: SVM 훈련 시키기
  • 오후: 실습 프로젝트로 진행
    - 코드, 라이브러리, 함수를 쓸 때는 반드시 어떤 것이고 왜 내가 사용하는지 생각할 것
    • train, test는 가장 먼저 나눠놓은 후에 전처리 할 것(테스트는 절대 건드는 것이 아님)
    • get_dummies 함수는 컬럼이 늘어나면서 추가되기 때문에 클래스 개수가 다를 경우 shape이 맞지 않음 --> 지양할 것

SVM(Support Vector Machine)

  • 복잡한 분류 문제에 적합
  • 선형, 비선형 분류 모두 사용 가능
  • 회구에 사용 가능
  • 이진 분류만 가능
  • 확률 추정치를 제공

SVM 실습: 피마인디언 당뇨병 환자 데이터

1. 데이터 준비

# 데이터 로드
diabetes = pd.read_csv('./diabetes.csv')
print(f'shape: {diabetes.shape}')

# 데이터 카피
df = diabetes.copy()

# 데이터 확인
print(f'data info: {df.info()}')
print(f'data describe: {df.describe()}')

# 데이터 y label 확인
df['Outcome'].value_counts()

2. 테스트 데이터 분리

# X와 y 분리
X = df[['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin',
       'BMI', 'DiabetesPedigreeFunction', 'Age']]
y = df['Outcome']

# train test split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, shuffle=True, stratify=y)

# split 확인
print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)
print(y_train.value_counts())
print(y_test.value_counts())

3. 전처리

# 결측치 확인
print(f'결측치: \n{X_train.isnull().sum(axis = 0)}')

# 이상치 확인
# 0인 값 지우기
df1 = X_train.copy()
cols = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin',
       'BMI']
df1 = df1[cols].replace(0, np.nan)
df1.isna().sum()
df1=df1.dropna()
print(f'이상치 지운 후 shape:{df1.shape}')

# 적당한 값으로 0인 값을 치환
df2 = X_train.copy()
median_dict = {}
df2[cols] = df2[cols].replace(0, np.nan)
for c in cols:
  df2[c] = df2[c].fillna(df2[c].median())
  median_dict[c] = df2[c].median()
# print(df2.isnull().sum())
# print(df2.isna().sum())
# print(df2.describe())

# scaling
from sklearn.preprocessing import StandardScaler
X_train = df2.copy()
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)

4. 학습

from sklearn.svm import SVC

clf = SVC(random_state=42)
clf = clf.fit(X_train_s, y_train)

5. 예측

# 적당한 값으로 0인 값을 치환
df3 = X_test.copy()
df3[cols] = df3[cols].replace(0, np.nan)
for c in cols:
  df3[c] = df3[c].fillna(median_dict[c])

# scaling
from sklearn.preprocessing import StandardScaler
X_test = df3.copy()
scaler = StandardScaler()
X_test_s = scaler.fit_transform(X_test)

# 성능 평가
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score

pred = clf.predict(X_test_s)
acc = accuracy_score(y_test, pred)
recall = recall_score(y_test, pred)
precision = precision_score(y_test, pred)
f1 = f1_score(y_test, pred)
print(f'accuracy: {acc}')
print(f'recall: {recall}')
print(f'precision: {precision}')
print(f'f1: {f1}')

6.튜닝

  • C, gamma, kernel, degrees 하이퍼 파라미터 튜닝
from sklearn.model_selection import GridSearchCV

params = {
    'C':[0.1, 1],
    'gamma': [0.01, 0.1],
    'kernel':['poly','rbf'],
    'degree':[2,3]
}

grid_cv = GridSearchCV(SVC(), params, cv = 5, refit=True, verbose=3) # cv: 한 케이스당 5번 돌려서 정확도 평균 내겠다.
grid_cv.fit(X_train_s, y_train)

# 베스트 모델 재학습
clf = SVC(C=1, degree=2, gamma=0.01, kernel = 'rbf')
clf = clf.fit(X_train_s, y_train)

7. 모델 저장 및 불러와 사용하기

import pickle
# 저장
with open('./svc_c_1_degree_2_gamma_001_rbf.pkl', 'wb') as f:
  pickle.dump(clf, f)

with open('./standard_scaler.pkl', 'wb') as f:
  pickle.dump(scaler,f)

# 로드
with open('./svc_c_1_degree_2_gamma_001_rbf.pkl', 'rb') as f:
  clf = pickle.load(f)

with open('./standard_scaler.pkl', 'rb') as f:
  scaler = pickle.load(f)

펭귄 종 분류하기(SVC) 팀프로젝트 실습 진행

  • get_dummies 사용 지양
    - train, test split 했을 때 두 데이터 세트에 속한 데이터가 다를 경우 컬럼의 개수가 달라지기 때문에 get_dummies 대신 one-hot encoder로 할 것
  • 코드, 라이브러리, 함수 사용 시 왜 사용하는지, 사용한 것에 대해 설명할 것
  • train, test 데이터는 무조건 split 시키고 진행할 것
    - 실무적인 부분을 생각해보면 어떤 입력이 들어올 지 모르기 때문에 미리 전처리 하면 안 됨..
  • 강사님한테 수업 들으면서 내가 쓰는 코드를 다시 한 번 생각하게 됨..
  • 학습 데이터 도메인 지식을 반드시 알아야 함.

인간의 움직인 데이터를 보고 SVM 기반 다중 분류 하기

1. 데이터 준비

import pandas as pd
df = pd.read_csv('/content/HumanActivityRecognition/train.csv')

# 데이터 확인
print(f'data info: {df.info()}')
print(f'data describe: {df.describe()}')

# 데이터 y label 확인
df['Activity'].value_counts()

2. 데스트 데이터 분리

  • 이미 분리되어 있어서 X, y만 나눠줌
X_train = df.drop(['Activity', 'subject'], axis = 1)
y_train = df['Activity']

3. 데이터 전처리

# 결측치 확인
for i in X_train.isnull().sum(axis=0):
  if i !=0:
    print(i)
# scaling
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)

# 범주형 수치 데이터로 변환
label = {'LAYING':0,
'STANDING':1,
'SITTING':2,
'WALKING':3,
'WALKING_UPSTAIRS':4,
'WALKING_DOWNSTAIRS':5}
y_train = y_train.map(label)
    

4. 학습

from sklearn.svm import SVC
clf = SVC(random_state=42)
clf = clf.fit(X_train_s, y_train)

5. 예측

# 테스트 데이터 로드
test_df = pd.read_csv('/content/HumanActivityRecognition/test.csv')
X_test = test_df.drop(['Activity', 'subject'], axis = 1)
y_test = test_df['Activity']

# scaling
X_test_s = scaler.fit_transform(X_test) # 학습 스케일러와 동일하게 사용

# y_test 값으로 성능 평가 편하게 수치형 범주로 변환
y_test = y_test.map(label)

# 성능 평가
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score

y_pred = clf.predict(X_test_s)
acc = accuracy_score(y_test, y_pred)
print(f'accuracy: {acc}')

6. 튜닝

# from sklearn.model_selection import GridSearchCV

# params = {
#     'C':[0.1,1],
#     'gamma':[0.01, 0.1],
#     'kernel':['poly', 'rbf'],
#     'degree':[2,3]
# }

# grid_cv = GridSearchCV(SVC(), params, cv = 5, refit=True, verbose=3)
# grid_cv.fit(X_train_s, y_train)

# print(grid_cv.best_estimator_)
# print(grid_cv.best_score_)

# 베스트 모델 재 학습
clf = SVC(C=1.0, degree=3, kernel = 'rbf')
clf = clf.fit(X_train_s, y_train)

7. 모델 저장

import pickle
# 저장
with open('./svc_c_1_degree_3_rbf.pkl', 'wb') as f:
  pickle.dump(clf, f)
with open('./standard_scaler.pkl', 'wb') as f:
  pickle.dump(scaler,f)

# 로드
with open('./svc_c_1_degree_3_rbf.pkl', 'rb') as f:
  clf = pickle.load(f)

with open('./standard_scaler.pkl', 'rb') as f:
  scaler = pickle.load(f)
  
y_pred = clf.predict(X_test_s)
acc = accuracy_score(y_test, y_pred)
print(f'accuracy: {acc}')

0개의 댓글