투빅스 9&10기 3주차 Support Vector Machine - 10기 장유영

by 장유영 posted Aug 08, 2018
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

+ - Up Down Comment Print

ToBigs Week03 Assignment Support Vector Machine 파이썬 코드입니다.


# Setting
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC
[1st: Ffires 데이터]
#1 데이터 로드
path = "C:/Users/YY/Desktop/TB/Week03/SVM/"
file = pd.read_csv(os.path.join(path, 'Ffires.csv'))
file.info()
file.head()
file.isnull().sum()
# DF 잘보기
pd.set_option('display.max_columns', 50)
#2 Preprocessing
# 타겟 변수인 area의 분포를 보면 왼쪽으로 치우쳐져 있음을 알 수 있다.
sns.distplot(file["area"], color="darkblue", kde=True, hist=False)
plt.show()
1.PNG





















# EDA를 위해 로그변환을 실행한 arae 변수도 만들어주자.
file['log_area'] = file['area'].map(lambda i: np.log(i) if i > 5 else 0)
# 5보다 클 경우 1로, 작을 경우 0으로 매핑을 해준다. (가이드라인)
file['area'] = file['area'].map(lambda i: 1 if i > 5 else 0)
# 커널 서포트벡터 머신은 단위에 영향을 크게 받기 때문에 상당히 조심스러운 전처리가 요구된다.
# 연속형 변수의 경우 표준 정규화와 더불어 Min-Max Scailing까지 진행해 준다.
def edit_data(file, col_list):
"""
Arguments: file -- dataset
col_list -- a list containing names of columns; It should be continuous data
Return: Scaled file
"""
....scaler = MinMaxScaler()

....for col in col_list:
........file[col] = (file[col] - np.mean(file[col], axis=0)) / np.std(file[col])
........output = np.array( scaler.fit_transform(file[col].values.reshape(-1, 1)) )
........file[col] = output

....return file
# 전처리할 열의 이름을 담은 리스트: col_list
col_list = ['FFMC', 'DMC', 'DC', 'ISI', 'temp', 'RH', 'wind', 'rain']
file = edit_data(file=file, col_list=col_list)
# 좌표가 area와 연관이 있을까? 큰 차이를 찾지 못하였다.
sns.catplot(x="X", y="log_area", data=file, orient="v", kind="violin")
plt.show()

2.PNG


















sns.catplot(x="Y", y="log_area", data=file, orient="v", kind="violin")
plt.show()
3.PNG



















# 좌표를 담은 X, Y 칼럼은 Min-Max Scailing만 해준다.
scaler = MinMaxScaler()
file['X'] = scaler.fit_transform(file['X'].values.astype('float64').reshape(-1, 1))
file['Y'] = scaler.fit_transform(file['Y'].values.astype('float64').reshape(-1, 1))
# Month 변수가 결과에 영향을 미칠까?: 그렇다!
# 특히 12월에 화재가 많이 발생하였음을 알 수 있다.
sns.catplot(x="month", y='area', kind="bar", palette="ch:.25", data=file,
order=['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'])
plt.show()

4.PNG


























# Day 변수가 결과에 영향을 미칠까?: 그렇다!
sns.catplot(x="day", y='area', kind="bar", palette="ch:.25", data=file,
order=['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'])
plt.show()
5.PNG


























# 범주형 변수는 변환을 해주도록 한다. (month, day)
month_mapping = {'jan':0, 'feb':1/11, 'mar':2/11, 'apr':3/11, 'may':4/11, 'jun':5/11,
'jul':6/11, 'aug':7/11, 'sep':8/11, 'oct':9/11, 'nov':10/11, 'dec':1}
day_mapping = {'mon':0, 'tue':1/6, 'wed':2/6, 'thu':3/6, 'fri':4/6, 'sat':5/6, 'sun':1}
file['month'] = file['month'].map(month_mapping)
file['day'] = file['day'].map(day_mapping)
# 전처리가 끝난 데이터를 확인해보자.
file.head()
X Y month day FFMC DMC DC ISI temp
7 5 0.181818 0.666667 0.870968 0.086492 0.101325 0.090909 0.192926
7 4 0.818182 0.166667 0.927742 0.118194 0.775419 0.119430 0.508039
7 4 0.818182 0.833333 0.927742 0.146795 0.796294 0.119430 0.398714
8 6 0.181818 0.666667 0.941935 0.110958 0.081623 0.160428 0.196141
8 6 0.181818 1.000000 0.910968 0.172984 0.110590 0.171123 0.295820
RH wind rain area log_area
0.423529 0.700000 0.00000 0 0.0
0.211765 0.055556 0.00000 0 0.0
0.211765 0.100000 0.00000 0 0.0
0.964706 0.400000 0.03125 0 0.0
0.988235 0.155556 0.00000 0 0.0
#3 모델링
# 아래 SN_데이터에서는 커널을 여러 개 사용하여 비교하는 작업을 하였다.
# 왜냐하면 데이터의 수도 더 적고 고려해야할 변수의 수 또한 더 적었기 때문이다.
# 본 데이터에서는 Gaussian 커널에 초점을 두고 튜닝을 하도록 하겠다.
X = file.drop(['area', 'log_area'], axis=1).values
Y = file['area'].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=100)
print("Length of X_train: ", len(X_train)) # 413
print("Length of X_test: ", len(X_test)) # 104
param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100, 1000], 'gamma':[0.001, 0.01, 0.1, 1, 10, 100, 1000]}
svm = SVC(kernel='rbf')
grid = GridSearchCV(estimator=svm, param_grid=param_grid, cv=10, scoring='accuracy')
grid.fit(X_train, Y_train)
grid.best_params_
grid.score(X_train, Y_train)
grid.score(X_test, Y_test)
#3 결과는 아래와 같다.
Best Parameters {'C': 10, 'gamma': 0.1}
Train Accuracy 73.37%
Test Accuracy 72.12%






[2nd: SN_ad 데이터]
#1 데이터 로드: 타겟 변수는 Purchased로 설정
path = "C:/Users/YY/Desktop/TB/Week03/SVM/"
sn = pd.read_csv(os.path.join(path, 'SN_ad.csv'))
sn.info()
sn.head()
sn.isnull().sum()
#2 Preprocessing
# ID 변수 삭제
sn.drop('User ID', axis=1, inplace=True)
# Gender 변수 매핑
sn['Gender'] = sn['Gender'].map({'Male':0, 'Female':1})
# 커널 서포트벡터 머신은 단위에 영향을 크게 받기 때문에 상당히 조심스러운 전처리가 요구된다.
# Age와 Esimated Salary는 표준 정규화와 더불어 Min-Max Scailing까지 진행해 준다.
# 이름이 너무 길어서 ES로 바꿔주겠다.
sn = sn.rename(columns={"EstimatedSalary":"ES"}, inplace=False)
def edit_data(sn):
"""
Arguments: sn -- dataset / Age, ES -- name of columns
Return: Scaled Data
"""
....# Normalizing
....sn['Age'] = (sn['Age'] - np.mean(sn['Age'], axis=0)) / np.std(sn['Age'])
....sn['ES'] = (sn['ES'] - np.mean(sn['ES'], axis=0)) / np.std(sn['ES'])

....# MinMaxScaling
....scaler = MinMaxScaler()
....Age = np.array( scaler.fit_transform(sn['Age'].values.reshape(-1, 1)) )
....ES = np.array( scaler.fit_transform(sn['ES'].values.reshape(-1, 1)) )
....return Age, ES
Age, ES = edit_data(sn)
# 데이터프레임을 업데이트 해주자.
sn['Age'] = Age
sn['ES'] = ES
# 한 번 확인해보자.
sn.head(5)
Gender Age ES Purchased
0 0 0.023810 0.029630 0
1 0 0.404762 0.037037 0
2 1 0.190476 0.207407 0
3 1 0.214286 0.311111 0
4 0 0.023810 0.451852 0
# 아마 Age와 ES는 서로 연관이 있지 않을까?
cmap = sns.cubehelix_palette(n_colors=3, start=0, rot=0.2, light=0.9, dark=0.2, as_cmap=True)
sns.heatmap(sn[['Age', 'ES']].corr(), annot=True, fmt="0.2f", cmap=cmap)
plt.show()
# 생각보다 큰 관련이 없다. (0.16)

6.PNG


















# 실제로 각 변수가 구매 여부에 미치는 영향을 그래프로 확인해 보자.
# Gender: Female(1)의 구매비율이 더 높다.
sns.countplot(x='Purchased', hue='Gender', data=sn, palette=sns.color_palette("Paired", 2))
plt.show()
7.PNG















# Age
sns.distplot(sn[('Age')], hist=True, bins=10, kde=True, rug=True)
plt.show() # 정규분포와 유사하다.
8.PNG

















sns.catplot(x="Purchased", y="Age", kind="boxen", data=sn)
plt.show() # 나이 든 사람들이 더 많이 구매를 했다.
9.PNG






















# ES
sns.distplot(sn[('ES')], hist=True, bins=20, kde=True, rug=True)
plt.show() # 저_중소득층의 비율이 더 높다.
10.PNG



















sns.catplot(x="Purchased", y="ES", kind="boxen", data=sn)
plt.show() # 당연히 돈 많은 사람들이 소비도 더 많이 할 것이다.

11.PNG




















# 마지막으로 학습을 위한 데이터를 구성한다.
X = sn[['Gender', 'Age', 'ES']].values
Y = sn['Purchased'].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0, stratify=Y)
print("Length of X_train: ", len(X_train)) # 320
print("Length of X_test: ", len(X_test)) # 80
#3 모델링
# 커널의 비교를 위해 random_state를 고정하도록 하겠다.
# 미리 Scailing을 실행했기 때문에 scaler는 불러올 필요가 없다.
# Purchased label의 수를 보면 0: 257개, 1:143개로 크게 unbalanced하지 않다.
# 따라서 정확도는 accuracy로 판정하도록 할 것이다.

sn['Purchased'].value_counts()

0 257
1 143
Name: Purchased, dtype: int64
# 커널 비교 시 학습량이 많으므로 간단하게만 비교를 하도록 할 것이다.
# Poly 커널은 속도가 너무 느려 제외하였다.
# Linear 커널
param_grid = {'C':[0.01, 0.1, 1, 10, 100], 'gamma':[0.01, 0.1, 1, 10, 100]}
svm = SVC(kernel='linear', random_state=0)
grid1 = GridSearchCV(estimator=svm, param_grid=param_grid, cv=3, scoring='accuracy')
grid1.fit(X_train, Y_train)
# Gaussian 커널
param_grid = {'C':[0.01, 0.1, 1, 10, 100], 'gamma':[0.01, 0.1, 1, 10, 100]}
svm = SVC(kernel='rbf', random_state=0)
grid2 = GridSearchCV(estimator=svm, param_grid=param_grid, cv=3, scoring='accuracy')
grid2.fit(X_train, Y_train)
# Sigmoid 커널
param_grid = {'C':[0.01, 0.1, 1, 10, 100], 'gamma':[0.01, 0.1, 1, 10, 100]}
svm = SVC(kernel='sigmoid', random_state=0)
grid3 = GridSearchCV(estimator=svm, param_grid=param_grid, cv=3, scoring='accuracy')
grid3.fit(X_train, Y_train)
# 최종 결과를 표로 정리하면 아래와 같다.
# Gaussian Kernel의 성능이 가장 좋다.


12.PNG







Articles

5 6 7 8 9 10 11 12 13 14

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5