๐Ÿ’ป My Work/๐Ÿง  AI

[์ธ๊ณต์ง€๋Šฅ/ํ˜ผ๊ณต๋จธ์‹ ] 04-2. ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• (2)

Jaeseo Kim 2022. 12. 9. 23:41

์•„๋ž˜ ์ฒจ๋ถ€ํ•œ ๊ธ€์€ ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• ๊ฐœ๋…์— ๋Œ€ํ•ด ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

 

[์ธ๊ณต์ง€๋Šฅ/ํ˜ผ๊ณต๋จธ์‹ ] 04-2. ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• (1)

์ ์ง„์ ์ธ ํ•™์Šต์„ ์œ„ํ•œ ๋ฌธ์ œ ์ธ์‹ ๋ชจ๋ธ์ด ๋งค๋ฒˆ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์ƒˆ๋กญ๊ฒŒ ํ›ˆ๋ จํ•˜๋Š” ๋ฐ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ๋ฒˆ์— ์ค€๋น„๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์กฐ๊ธˆ์”ฉ ์ „๋‹ฌ๋œ๋‹ค๋ฉด, ๊ณ 

avoc-o-d.tistory.com

 

์•„๋ž˜ ์ž‘์„ฑํ•œ ๊ธ€์€ ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• ๊ฐœ๋… ๋ฐ ์‹ค์Šต ๊ณผ์ •์— ๋Œ€ํ•ด ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. ๐Ÿš€

 

๋ฐ์ดํ„ฐ ์ค€๋น„ํ•˜๊ธฐ

๋‹ค์ค‘ ๋ถ„๋ฅ˜๋ฅผ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐธ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

 

[์ธ๊ณต์ง€๋Šฅ/ํ˜ผ๊ณต๋จธ์‹ ] 04-1. ๋กœ์ง€์Šคํ‹ฑ ํšŒ๊ท€

๐Ÿ“Œ ๋กœ์ง€์Šคํ‹ฑ ํšŒ๊ท€ ์„ ํ˜• ๋ฐฉ์ •์‹์„ ์‚ฌ์šฉํ•œ ๋ถ„๋ฅ˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํ˜• ํšŒ๊ท€์™€ ๋‹ฌ๋ฆฌ, ์‹œ๊ทธ๋ชจ์ด๋“œ ํ•จ์ˆ˜๋‚˜ ์†Œํ”„ํŠธ๋งฅ์Šค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ํ™•๋ฅ ์„ ๊ตฌํ•จ ๐Ÿ“๋ชฉํ‘œ! ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์ƒ์„ ์ด ์žˆ์„ ๋•Œ, ํ•ด๋‹น ์ƒ์„ 

avoc-o-d.tistory.com

import pandas as pd
fish = pd.read_csv("https://bit.ly/fish_csv_data")

# Species ์—ด์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์—ด์€ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋กœ, Species ์—ด์€ ํƒ€๊นƒ ๋ฐ์ดํ„ฐ๋กœ ๋ฐฐ์—ด ๋ณ€ํ™˜
fish_input = fish[["Weight","Length","Diagonal","Height","Width"]].to_numpy()
fish_target = fish["Species"].to_numpy()

# ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์™€ ํƒ€๊นƒ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ๊ฐ ํ›ˆ๋ จ ์„ธํŠธ, ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ„๊ธฐ
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(fish_input, fish_target, random_state=42)

# ํ‘œ์ค€ํ™” ์ „์ฒ˜๋ฆฌ (์ •๊ทœํ™”)
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input) # ๊ผญ ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ํ•™์Šตํ•œ ํ†ต๊ณ„ ๊ฐ’์œผ๋กœ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋„ ๋ณ€ํ™˜

ํ˜„์žฌ ๋ณ€์ˆ˜ ์ƒํƒœ ์ฐธ๊ณ 

์ด๋ ‡๊ฒŒ ํŠน์„ฑ๊ฐ’์˜ ์Šค์ผ€์ผ์„ ๋งž์ถ˜ ๋‘ ๋„˜ํŒŒ์ด ๋ฐฐ์—ด๊นŒ์ง€ ์ค€๋น„๋ฅผ ๋งˆ์ณค์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์ด์ œ ํ›ˆ๋ จ์„ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ“Œ SGDClassifier

๐Ÿ“Œ ์‚ฌ์ดํ‚ท๋Ÿฐ์˜ SGDClassifier : ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ถ„๋ฅ˜์šฉ ํด๋ž˜์Šค

- ๋งค๊ฐœ๋ณ€์ˆ˜ loss : ์†์‹คํ•จ์ˆ˜์˜ ์ข…๋ฅ˜
- ๋งค๊ฐœ๋ณ€์ˆ˜ max_iter : ์ˆ˜ํ–‰ํ•  ์—ํฌํฌ ํšŸ์ˆ˜
  • loss = "log" ๋กœ ์ง€์ •ํ•˜์—ฌ ๋กœ์ง€์Šคํ‹ฑ ์†์‹ค ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • max_iter = 10 ๋กœ ์ง€์ •ํ•˜์—ฌ ์ „์ฒด ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ 10ํšŒ ๋ฐ˜๋ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
from sklearn.linear_model import SGDClassifier

# loss ์†์‹ค ํ•จ์ˆ˜์˜ ์ข…๋ฅ˜ ์ง€์ •
sc = SGDClassifier(loss='log', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)

์ ์ˆ˜ ํ™•์ธ

๐Ÿค” ์ •ํ™•๋„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค..? ํ›ˆ๋ จ ํšŸ์ˆ˜๊ฐ€ ์ ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๐Ÿ’ก ํ•ด๊ฒฐ ! ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์€ ์ ์ง„์  ํ•™์Šต์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ˜„์žฌ ํ›ˆ๋ จํ•œ ๋ชจ๋ธ์„ ์ถ”๊ฐ€๋กœ ์ด์–ด์„œ ๋” ํ›ˆ๋ จํ•ด๋ด…์‹œ๋‹ค.

 

+) ๐Ÿค” ์˜๋ฌธ? train_scaled, train_target์„ ํ•œ ๋ฒˆ์— ๋ชจ๋‘ ์‚ฌ์šฉํ–ˆ์œผ๋‹ˆ ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์ด ์•„๋‹ˆ๋ผ ๋ฐฐ์น˜ ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•(์ „์ฒด ์ƒ˜ํ”Œ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹)์ด ์•„๋‹Œ๊ฐ€์š”?

๐Ÿ’ก ๋Œ€๋‹ต ! ์•„๋‹™๋‹ˆ๋‹ค. SGDClassifier์— ํ•œ ๋ฒˆ์— ํ›ˆ๋ จ ์„ธํŠธ ์ „์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ธด ํ–ˆ์ง€๋งŒ, ํ•ด๋‹น ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ „๋‹ฌ๋ฐ›์€ ํ›ˆ๋ จ ์„ธํŠธ์—์„œ 1๊ฐœ์”ฉ ์ƒ˜ํ”Œ์„ ๊บผ๋‚ด์–ด ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

๐Ÿ“Œ SGDClassifier์˜ partial_fit() : 1 ์—ํฌํฌ์”ฉ ์ด์–ด์„œ ํ›ˆ๋ จํ•˜๋Š” ํ•จ์ˆ˜
- fit() ๊ณผ ์‚ฌ์šฉ๋ฒ•์ด ๊ฐ™์ง€๋งŒ, ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค 1 ์—ํฌํฌ์”ฉ ์ด์–ด์„œ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
sc.partial_fit(train_scaled, train_target)

์ ์ˆ˜ ํ™•์ธ

์ •ํ™•๋„๊ฐ€ ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ์ด ๋ชจ๋ธ์„ ์—ฌ๋Ÿฌ ์—ํฌํฌ์—์„œ ๋” ํ›ˆ๋ จํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์–ด๋ณด์ž…๋‹ˆ๋‹ค.

 

๐Ÿค” ์˜๋ฌธ? ์–ผ๋งˆ๋‚˜ ๋” ํ›ˆ๋ จํ•ด์•ผ ํ•˜๋‚˜์š”?

๐Ÿ’ก ๋Œ€๋‹ต ! ๊ทธ ๊ธฐ์ค€์„ ์‚ดํŽด๋ณด๊ธฐ ์œ„ํ•ด, ์—ํฌํฌ์™€ ๊ณผ๋Œ€/๊ณผ์†Œ์ ํ•ฉ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ“Œ ์—ํฌํฌ์™€ ๊ณผ๋Œ€/๊ณผ์†Œ์ ํ•ฉ

๐Ÿ“ ํ™•๋ฅ ์  ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์„ ์‚ฌ์šฉํ•œ ๋ชจ๋ธ์€ ์—ํฌํฌ ํšŸ์ˆ˜์— ๋”ฐ๋ผ ๊ณผ์†Œ์ ํ•ฉ์ด๋‚˜ ๊ณผ๋Œ€์ ํ•ฉ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์—ํฌํฌ ํšŸ์ˆ˜๊ฐ€ ์ ์œผ๋ฉด, ๋ชจ๋ธ์ด ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ ๋œ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. โ–ถ๏ธ ๊ณผ์†Œ์ ํ•ฉ๋œ ๋ชจ๋ธ์ผ ๊ฐ€๋Šฅ์„ฑ
  • ์—ํฌํฌ ํšŸ์ˆ˜๊ฐ€ ์ถฉ๋ถ„ํžˆ ๋งŽ์œผ๋ฉด, ๋ชจ๋ธ์ด ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ ์™„์ „ํžˆ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. โ–ถ๏ธ ๊ณผ๋Œ€์ ํ•ฉ๋œ ๋ชจ๋ธ์ผ ๊ฐ€๋Šฅ์„ฑ

์—ํฌํฌ์— ๋Œ€ํ•œ ๋ชจ๋ธ์˜ ์ •ํ™•๋„ ๊ทธ๋ž˜ํ”„

๐Ÿ“ ์กฐ๊ธฐ ์ข…๋ฃŒ : ๊ณผ๋Œ€์ ํ•ฉ(์—ํฌํฌ๊ฐ€ ์ง„ํ–‰๋ ์ˆ˜๋ก ํ›ˆ๋ จ ์„ธํŠธ ์ ์ˆ˜๋Š” ๊พธ์ค€ํžˆ ์ฆ๊ฐ€ํ•˜์ง€๋งŒ, ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜๊ฐ€ ๊ฐ์†Œํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๊ฐ„)์ด ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํ›ˆ๋ จ์„ ๋ฉˆ์ถ”๋Š” ๊ฒƒ

 

๊ทธ๋Ÿผ ์šฐ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋กœ ์œ„์™€ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ“ fit() ๋ฉ”์†Œ๋“œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , partial_fit() ๋ฉ”์†Œ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ›ˆ๋ จ ์„ธํŠธ์— ์žˆ๋Š” ์ „์ฒด ํด๋ž˜์Šค์˜ ๋ ˆ์ด๋ธ”์„ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํ›ˆ๋ จ ์„ธํŠธ์— ์žˆ๋Š” 7๊ฐœ ์ƒ์„  ์ข…๋ฅ˜ class๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

import numpy as np
sc = SGDClassifier(loss="log", random_state=42)

# ์—ํฌํฌ๋งˆ๋‹ค ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์ ์ˆ˜๋ฅผ ๊ธฐ๋ก
train_score = []
test_score = []

# ํ›ˆ๋ จ ์„ธํŠธ์— ์žˆ๋Š” 7๊ฐœ ์ƒ์„  ์ข…๋ฅ˜ class๋ฅผ ์ค€๋น„
classes = np.unique(train_target)

 300๋ฒˆ ์—ํฌํฌ ๋™์•ˆ ํ›ˆ๋ จ์„ ๋ฐ˜๋ณตํ•˜์—ฌ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

for _ in range(0, 300):
  sc.partial_fit(train_scaled, train_target, classes = classes)
  # ํ›ˆ๋ จ ์„ธํŠธ, ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ๊ณ„์‚ฐ
  train_score.append(sc.score(train_scaled, train_target))
  test_score.append(sc.score(test_scaled, test_target))

ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์ ์ˆ˜๋ฅผ ๊ทธ๋ž˜ํ”„๋กœ ๊ทธ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

import matplotlib.pyplot as plt

plt.plot(train_score)
plt.plot(test_score)
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.show()

300๋ฒˆ ์—ํฌํฌ ๋™์•ˆ ๊ธฐ๋กํ•œ ํ›ˆ๋ จ, ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์ ์ˆ˜ ๊ทธ๋ž˜ํ”„ (ํŒŒ๋ž€์ƒ‰ : ํ›ˆ๋ จ ์„ธํŠธ, ์ฃผํ™ฉ์ƒ‰ : ํ…Œ์ŠคํŠธ ์„ธํŠธ)

์ดˆ๊ธฐ์—๋Š” ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ ๋‘˜ ๋‹ค ์ ์ˆ˜๊ฐ€ ๋‚ฎ์•„ ๊ณผ์†Œ์ ํ•ฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ ,

100๋ฒˆ์งธ ์—ํฌํฌ ์ดํ›„๋ถ€ํ„ฐ ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜๊ฐ€ ์กฐ๊ธˆ์”ฉ ๋ฒŒ์–ด์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

=> 100๋ฒˆ์งธ ์—ํฌํฌ๊ฐ€ ์ ์ ˆํ•œ ๋ฐ˜๋ณต ํšŸ์ˆ˜์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๐Ÿ˜

 

๊ทธ๋Ÿผ, SGDClassifier ์˜ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ 100์œผ๋กœ ๋งž์ถ”๊ณ  ๋‹ค์‹œ ํ›ˆ๋ จํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ SGDClassifier์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ tol : ์ •๋ฐ€๋„, ํ–ฅ์ƒ๋  ์ตœ์†Ÿ๊ฐ’์„ ์ง€์ •
- SGDClassifier๋Š” ์ผ์ • ์—ํฌํฌ ๋™์•ˆ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์ง€ ์•Š์œผ๋ฉด ๋” ํ›ˆ๋ จํ•˜์ง€ ์•Š๊ณ  ์ž๋™์œผ๋กœ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค.
- None์œผ๋กœ ์ง€์ •ํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  max_iter์— ์ง€์ •ํ•œ ๋งŒํผ ๋ฌด์กฐ๊ฑด ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
sc = SGDClassifier(loss="log", max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)

์ ์ˆ˜ ํ™•์ธ

์ตœ์ข… ์ ์ˆ˜๊ฐ€ ์•„์ฃผ ์ข‹์Šต๋‹ˆ๋‹ค~! ํ›ˆ๋ จ ์„ฑ๊ณต~! โœจโœจ


๐Ÿ“ SGDClassifier์˜ loss ๋งค๊ฐœ๋ณ€์ˆ˜

  • ๊ธฐ๋ณธ๊ฐ’ : hinge
    • ํžŒ์ง€ ์†์‹ค : ์„œํฌํŠธ ๋ฒกํ„ฐ ๋จธ์‹ ์„ ์œ„ํ•œ ์†์‹ค ํ•จ์ˆ˜