SVM(Support Vector Machine)์ด๋?
๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฅํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ์ด ๋ชจ๋ธ์ ๊ฒฐ์ ์ดํ๋ฉด(hyperplane)์ ์ฐพ์์, ๋ ๊ฐ์ ํด๋์ค๋ฅผ ๊ฐ์ฅ ํฐ ์ฌ์ (margin)๋ฅผ ๋๊ณ ๋ถ๋ฆฌํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ค. ์ฃผ๋ก ์ด์ง ๋ถ๋ฅ ๋ฌธ์ ์์ ์ฌ์ฉ๋๋ ๊ฐ๋ ฅํ ๋ถ๋ฅ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก, ์ด๋ฉ์ผ์ ๋จ์ด ๋น๋๋ฅผ ํน์ง์ผ๋ก ์ฌ์ฉํ์ฌ ์คํธ ๋๋ ์คํธ์ด ์๋ ์ด๋ฉ์ผ์ ๋ถ๋ฅํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ค.
- ์ ํ ๋ถ๋ฅ๊ธฐ ๋๋ ๋น์ ํ ๋ถ๋ฅ๊ธฐ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์ปค๋ ํธ๋ฆญ์ ์ฌ์ฉํด ๊ณ ์ฐจ์ ๊ณต๊ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋งคํํ์ฌ ๋น์ ํ ๋ถ๋ฅ๋ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
- ํ๋ ๋ง์ง(hard margin)๊ณผ ์ํํธ ๋ง์ง(soft margin)์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ๋ถ๋ฅ๋ฅผ ์ ์ฐํ๊ฒ ์กฐ์ ํ ์ ์๋ค.
๋ชฉํ
ํ๋ ๋ง์ง SVM, ์ํํธ ๋ง์ง SVM, ๊ฐ์ฐ์์ RBF ์ปค๋์ ์ฌ์ฉํ๋ SVM์ ๊ตฌํํ๊ณ ๊ฐ๊ฐ์ ์ฑ๋ฅ์ ๋น๊ตํด๋ณผ ๊ฒ์ด๋ค.
๊ตฌํ
ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ฒ์ ํ์ธ
import sys
assert sys.version_info >= (3, 7)
from packaging import version
import sklearn
assert version.parse(sklearn.__version__) >= version.parse("1.0.1")
ํ์ผ ์ฝ๊ธฐ : ๋ฐ์ดํฐ ์ค๋น
ํ์ผ์์ ์ฝ์ด์์ ํน์ง ํ๋ ฌ๊ณผ ๋ ์ด๋ธ์ ๋ฐํํ๋ค.
def svm_readMatrix(file):
fd = open(file, 'r')
hdr = fd.readline()
rows, cols = [int(s) for s in fd.readline().strip().split()]
tokens = fd.readline().strip().split()
matrix = np.zeros((rows, cols))
Y = []
for i, line in enumerate(fd):
nums = [int(x) for x in line.strip().split()]
Y.append(nums[0])
kv = np.array(nums[1:])
k = np.cumsum(kv[:-1:2])
v = kv[1::2]
matrix[i, k] = v
category = (np.array(Y) * 2) - 1 # -1๊ณผ 1๋ก ๋ณํ
return matrix, tokens, category
- ๊ฐ ๋ฌธ์๋ ์คํธ์ธ์ง ์๋์ง๋ฅผ ๋ํ๋ด๋ ๋ ์ด๋ธ(0 ๋๋ 1)์ ๊ฐ์ง๊ณ ์๋ค. ์ด ๋ ์ด๋ธ์ SVM์์ ์ฌ์ฉํ๋ -1๊ณผ 1๋ก ๋ณํํ์ฌ ๋ฐํํ๋ค.
- matrix๋ ๊ฐ ๋ฌธ์์์ ๋จ์ด ๋น๋์๋ฅผ ๋ํ๋ด๋ ํ๋ ฌ, category๋ ๊ฐ ๋ฌธ์์ ๋ ์ด๋ธ(-1 ๋๋ 1)์ด๋ค.
SVM ๋ชจ๋ธ ์ค์
์ธ ๊ฐ์ง SVM ๋ถ๋ฅ๊ธฐ๋ฅผ ์ค์ ํ๋ค.
- ํ๋ ๋ง์ง SVM (svm_clf_hard): ์ ํ ์ปค๋์ ์ฌ์ฉํ๋ฉฐ, C ๊ฐ์ด ∞๋ก ์ค์ ๋์ด ์์ด ๋งค์ฐ ์๊ฒฉํ ๋ง์ง์ ์ฌ์ฉ
- ์ํํธ ๋ง์ง SVM (svm_clf_soft): C ๊ฐ์ 1๋ก ์ค์ ํ์ฌ ์ํํธ ๋ง์ง์ ์ฌ์ฉ
- ๊ฐ์ฐ์์ RBF ์ปค๋์ ์ฌ์ฉํ๋ SVM (svm_clf_rbf): ๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก RBF ์ปค๋์ ์ฌ์ฉํ๋ฉฐ, gamma์ C ๊ฐ์ ์กฐ์ ํ์ฌ ๋ชจ๋ธ์ ์ค์
๐คโ ์ปค๋ ํธ๋ฆญ(Kernel Trick)์ด๋ โ
๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋๋, ๋ฐ์ดํฐ๋ฅผ ๊ณ ์ฐจ์์ผ๋ก ๋งคํํ์ฌ ์ ํ ๋ถ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค. ์ด๋ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ด ์ปค๋ ํธ๋ฆญ์ด๋ค.
def main():
# Please set a training file that you want to use for this run below
trainMatrix, tokenlist, trainCategory = svm_readMatrix('./data/hw2_MATRIX.TRAIN.400')
testMatrix, tokenlist, testCategory = svm_readMatrix('./data/hw2_MATRIX.TEST')
# SVM Classifier model
# Hard margin SVM
svm_clf_hard = SVC(kernel="linear", C=float("inf"), max_iter=10_000, random_state=42)
# Soft margin SVM
# Find out the best parameters of C, max_iter, and so on
svm_clf_soft = SVC(kernel="linear", C=1, max_iter=10_000, random_state=42)
# Gaussian RBF SVM
# Find out the best parameters of gamma, C, max_iter, and so on
svm_clf_rbf = SVC(kernel="rbf", gamma=8, C=0.001, max_iter=10_000, random_state=42)
scaler = StandardScaler()
# Scaled version for each SVM and we will use these
scaled_svm_clf_hard = make_pipeline(scaler, svm_clf_hard)
scaled_svm_clf_soft = make_pipeline(scaler, svm_clf_soft)
scaled_svm_clf_rbf = make_pipeline(scaler, svm_clf_rbf)
- ์ด๋, StandardScaler๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํ์คํํ๋ค. ํ์คํ๋ ๋ชจ๋ ํน์ฑ์ ํ๊ท 0, ํ์ค ํธ์ฐจ 1๋ก ๋ณํํ์ฌ SVM์ ์ฑ๋ฅ์ ํฅ์์ํจ๋ค.
- ๊ฐ SVM ๋ชจ๋ธ๊ณผ ํ์คํ ์ค์ผ์ผ๋ฌ๋ฅผ make_pipeline()์ผ๋ก ์ฐ๊ฒฐํ์ฌ ํ์ดํ๋ผ์ธ์ ๋ง๋ ๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ํ์คํํ ํ SVM ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์๋ค.
- C ํ๋ผ๋ฏธํฐ: ์ค๋ฅ๋ฅผ ํ์ฉํ๋ ์ ๋๋ฅผ ์กฐ์ . C๊ฐ ํฌ๋ฉด ์ค๋ฅ๋ฅผ ์ ๊ฒ ํ์ฉํ๊ณ , ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ ๋ง์ด ํ์ฉํ์ฌ ์ํํธ ๋ง์ง์ ํ์ฑ.
RBF SVM ์ต์ ์ ํ๋ผ๋ฏธํฐ ์ฐพ๊ธฐ - ๊ทธ๋ฆฌ๋ ์์น (grid search)
๊ทธ๋ฆฌ๋ ์์น(Grid Search)๋ ๋ค์ํ ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ์ ์กฐํฉ์ ์๋ํ์ฌ ๊ทธ ์ค์์ ์ต์ ์ ๊ฐ์ ์ฐพ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊ฐ ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ชจ๋ ์กฐํฉ์ ์๋ํ๋ฉด์, ๊ฐ ์กฐํฉ์ ๋ํ ์ฑ๋ฅ์ ํ๊ฐํ ํ, ์ต์ ์ ์ฑ๋ฅ์ ๋ด๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ํํ๋ค.
SVM ๋ชจ๋ธ ํ์ต
scikit-learn์ SVM ๋ชจ๋ธ์์๋ ํ์ต ๊ณผ์ ์ด fit() ๋ฉ์๋๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ค.
scaled_svm_clf_hard.fit(trainMatrix, trainCategory)
scaled_svm_clf_soft.fit(trainMatrix, trainCategory)
scaled_svm_clf_rbf.fit(trainMatrix, trainCategory)
ํ์ต ๋ฐ์ดํฐ(X)์ ๋ ์ด๋ธ(y)์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ํ์ตํ๋ค.
ํ์ต ๊ณผ์ ์ค์๋ ๋ค์ ์์ ์ด ์ํ๋๋ค.
- ์ต์ ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ์ฐพ์.
- ํ์ต ๋ฐ์ดํฐ์์ ์ํฌํธ ๋ฒกํฐ๋ฅผ ์ ํ.
- ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ์ ์ํ๋ ๊ฐ์ค์น(weight)์ ์ ํธ(bias)์ ํ์ต
ํ ์คํธ ๋ฐ์ดํฐ์ ๋ํ ์์ธก
def svm_test(svm, matrix):
M, N = matrix.shape
output = svm.predict(matrix)
return output
- ์ฌ๊ธฐ์๋ svm.predict()์ ๊ฐ์ ๋ฐฉ์์ผ๋ก SVM ๋ชจ๋ธ์ ์ฌ์ฉํด ์์ธก์ ์ํํ ์ ์๋ค.
- matrix๋ ํ ์คํธ ๋ฐ์ดํฐ์ด๋ฉฐ, ์ด๋ฅผ ์ฌ์ฉํด ๊ฐ ๋ฌธ์๊ฐ ์คํธ์ธ์ง ์๋์ง ์์ธกํ ๊ฒฐ๊ณผ๋ฅผ output ๋ฐฐ์ด์ ์ ์ฅํ๋ค.
SVM ๋ชจ๋ธ ์ฑ๋ฅ ํ๊ฐ
๋ชจ๋ธ์ ์์ธก ๊ฒฐ๊ณผ์ ์ค์ ๋ ์ด๋ธ์ ๋น๊ตํ์ฌ ์ค๋ฅ์จ(error rate) ๋ฅผ ๊ณ์ฐํ๋ค.
def svm_evaluate(output, label):
error = (output != label).sum() * 1. / len(output)
print('Error: %1.4f' % error)
return error
print("\n== compare SVM implementations ==\n")
print("Hard margin SVM ",end="")
svm_evaluate(output_hard, testCategory)
print("Soft margin SVM ",end="")
svm_evaluate(output_soft, testCategory)
print("Gaussian RBF SVM ",end="")
svm_evaluate(output_rbf, testCategory)
print("\n=================================\n")
๊ฒฐ๊ณผ
Hard, Soft ์์ ์ต์ ์๋ฌ์จ์ ๊ธฐ๋กํ๊ณ , RBF ์์๋ ๊ทธ๋ณด๋ค๋ ๋ ๋์ ์๋ฌ์จ์ ๊ธฐ๋กํ๋ค.
ํ์ต ๋ฐ์ดํฐ ์์ ๋ฐ๋ฅธ ๋ชจ๋ธ ์ฑ๋ฅ ๋น๊ต
Test Error vs Training Set Size for Three SVM and Naive Bayes์ ๋ํ ์์ธก:
1. Hard Margin SVM:
- ์์ ํ๋ จ ์ธํธ ํฌ๊ธฐ์์๋ ๊ณผ์ ํฉ(overfitting)์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค. ์๋ํ๋ฉด ํ๋ ๋ง์ง SVM์ ๋ฐ์ดํฐ๋ฅผ ์๋ฒฝํ๊ฒ ๋ถ๋ฆฌํ๋ ค ํ๊ธฐ ๋๋ฌธ์ ์์ ๋ฐ์ดํฐ์์๋ ๊ณผํ๊ฒ ์ ํฉ๋๊ธฐ ์ฝ๋ค.
- ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ๊ณผ์ ํฉ ํ์์ด ์ค์ด๋ค๊ณ , ํ ์คํธ ์ค๋ฅ์จ์ด ์์ ์ ์ผ๋ก ๋ฎ์ ์์ค์ผ๋ก ์๋ ดํ๋ค.
2. Soft Margin SVM:
- ์ด๊ธฐ ์์ ํ๋ จ ์ธํธ ํฌ๊ธฐ์์๋ ์ ๋นํ ์ ์ฐ์ฑ(soft margin) ๋๋ถ์ ํ๋ ๋ง์ง SVM๋ณด๋ค๋ ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ผ ์ ์์ต๋๋ค.
- ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ปค์ง์๋ก ์ ์ฐจ ํ ์คํธ ์ค๋ฅ์จ์ด ๋ฎ์์ง๊ณ ์์ ๋ ๊ฒ์ด๋ค.
- ๊ทธ๋ฌ๋ C ๊ฐ์ด ์ ์ ํ์ง ์์ผ๋ฉด ์ํํธ ๋ง์ง SVM์ด ์ต์ ์ ์ฑ๋ฅ์ ๋ฐํํ์ง ๋ชปํ ์ ์์ต๋๋ค.
- ์ฒ์์๋ ํ ์คํธ ์ค๋ฅ์จ์ด ์ค๊ฐ ์์ค์ ์ ์งํ๋ค๊ฐ, ์ ์ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ๋ฉด์ ์ค๋ฅ์จ์ด ์ค์ด๋ค์ง๋ง ํ๋ ๋ง์ง SVM๋ณด๋ค ์ฒ์ฒํ ์๋ ดํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
3. RBF SVM:
- ์ด๊ธฐ ์์ ํ๋ จ ์ธํธ ํฌ๊ธฐ์์๋ ๋น์ ํ ํน์ฑ์ ์ ํฌ์ฐฉํ์ง ๋ชปํ๊ณ , ์๋ชป๋ ํ์ต์ด ์ด๋ฃจ์ด์ง ์ ์๋ค. ๋ฐ๋ผ์ ์ด๊ธฐ์๋ ๋์ ์ค๋ฅ์จ์ด ๋์ฌ ๊ฐ๋ฅ์ฑ์ด ํฌ๋ค.
- ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด, RBF ์ปค๋์ด ๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ํ์ตํ๊ธฐ ์์ํ๊ณ , ์ค๋ฅ์จ์ด ์ค์ด๋ค ๊ฒ์ด๋ค.
4. Naive Bayes:
- ๋์ด๋ธ ๋ฒ ์ด์ฆ๋ ๋น๊ต์ ๋จ์ํ ๋ชจ๋ธ์ด๋ฏ๋ก ํ๋ จ ๋ฐ์ดํฐ์ ํฌ๊ธฐ์ ํฌ๊ฒ ์ํฅ์ ๋ฐ์ง ์๋๋ค.
- ์์ ๋ฐ์ดํฐ์ธํธ์์๋ ๋น๊ต์ ์์ ์ ์ธ ์ฑ๋ฅ์ ๋ณด์ธ๋ค.
- ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ปค์ ธ๋ ํฐ ๊ฐ์ ์ ๊ธฐ๋ํ ์ ์์ง๋ง, ์ด๊ธฐ๋ถํฐ ๋ฎ์ ์ค๋ฅ์จ์ ์ ์งํ ๊ฐ๋ฅ์ฑ์ด ํฌ๋ค.
๋ฐ๋ผ์, ์ต์ข ์ ์ผ๋ก ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ฆ๊ฐํจ์ ๋ฐ๋ผ ํ๋ ๋ง์ง SVM๊ณผ ์ํํธ ๋ง์ง SVM์ ์ฑ๋ฅ์ด ํฅ์๋ ๊ฒ์ด๋ฉฐ, Naive Bayes๋ ์์ ์ ์ผ๋ก ์ข์ ์ฑ๋ฅ์ ๋ณด์ผ ๊ฒ์ด๋ค. RBF SVM์ ๋งค๊ฐ๋ณ์์ ๋ฐ๋ผ ์ฑ๋ฅ์ด ๊ฒฐ์ ๋์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก ์ด๊ธฐ์๋ ๋ฎ์ ์ฑ๋ฅ์ ๋ณด์ด๋ค๊ฐ ํ๋ จ ์ธํธ ํฌ๊ธฐ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ์ฑ๋ฅ์ด ํฅ์๋ ๊ฒ์ด๋ค.
'CS > ์ธ๊ณต์ง๋ฅ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[24-2] ๐พ ๊ธฐ๊ณํ์ต(ML) ํ๋ก์ ํธ : ์ธ๊ณ ํ์ฑ ์ฐพ๊ธฐ ๐ฝ (0) | 2024.11.25 |
---|---|
k-ํ๊ท ์๊ณ ๋ฆฌ์ฆ (k-means clustering) ๊ตฌํ (0) | 2024.10.18 |
๋์ด๋ธ ๋ฒ ์ด์ฆ๋ฅผ ์ฌ์ฉํ ์คํธ ๋ฉ์ผ ๋ถ๋ฅ๊ธฐ (Spam Classification via Naรฏve Bayes) (3) | 2024.10.17 |
[Tensorflow keras] image generation using Stable Diffusion (0) | 2024.06.24 |
Simple Diffusion Image generate Model (0) | 2024.06.21 |