์ง€๋„ ํ•™์Šต ์•Œ๊ณ ๋ฆฌ์ฆ˜

- ๋ถ„๋ฅ˜ : ์ƒ˜ํ”Œ์„ ๋ช‡ ๊ฐœ์˜ ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๋กœ ๋ถ„๋ฅ˜

- ํšŒ๊ท€ : ์ •ํ•ด์ง„ ํด๋ž˜์Šค๊ฐ€ ์—†๊ณ  ์ž„์˜์˜ ์–ด๋–ค ์ˆ˜์น˜๋ฅผ ์˜ˆ์ธกํ•˜๋Š” ๋ฌธ์ œ


๋†์–ด(perch) ๋ฌด๊ฒŒ ์˜ˆ์ธก

๋†์–ด์˜ ๊ธธ์ด, ๋†’์ด, ๋‘๊ป˜ ๋ฐ์ดํ„ฐ ์žˆ์Œ ~ ๋†์–ด ๋ฌด๊ฒŒ ์˜ˆ์ธก ๋ชจ๋ธ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค!

03-1. K-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ๋ถ„๋ฅ˜ 

์˜ˆ์ธกํ•˜๋ ค๋Š” ์ƒ˜ํ”Œ์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ˜ํ”Œ k๊ฐœ๋ฅผ ์„ ํƒ -> ์ƒ˜ํ”Œ๋“ค์˜ ํด๋ž˜์Šค๋ฅผ ํ™•์ธ

-> ๋‹ค์ˆ˜ ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กœ์šด ์ƒ˜ํ”Œ์˜ ํด๋ž˜์Šค๋กœ ์˜ˆ์ธก

k=3 (์ƒ˜ํ”Œ์ด 3๊ฐœ)๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋ฉด, ์‚ฌ๊ฐํ˜•์ด 2๊ฐœ๋กœ ๋‹ค์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ˜ํ”Œ x์˜ ํด๋ž˜์Šค๋Š” ์‚ฌ๊ฐํ˜•

 

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€

๋ถ„๋ฅ˜์™€ ๋˜‘๊ฐ™์ด ์˜ˆ์ธกํ•˜๋ ค๋Š” ์ƒ˜ํ”Œ์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ˜ํ”Œ k๊ฐœ๋ฅผ ์„ ํƒ

์ด์›ƒํ•œ ์ƒ˜ํ”Œ์˜ ํƒ€๊นƒ์€ ์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์ž„์˜์˜ ์ˆ˜์น˜

ํƒ€๊นƒ ์˜ˆ์ธก ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ• = ์ด์›ƒ์ˆ˜์น˜๋“ค์˜ ํ‰๊ท 

์ด์›ƒํ•œ ์ƒ˜ํ”Œ์˜ ํƒ€๊นƒ๊ฐ’์ด 100, 80, 60 ์ด๋ฅผ ํ‰๊ท ํ•˜๋ฉด ์ƒ˜ํ”Œ x์˜ ์˜ˆ์ธก ํƒ€๊นƒ๊ฐ’์€ 80

 


๋ฐ์ดํ„ฐ ์ค€๋น„

๋†์–ด์˜ ๊ธธ์ด = ํŠน์„ฑ, ๋ฌด๊ฒŒ = ํƒ€๊นƒ

import numpy as np    # numpy ์ˆซ์ž ํŒŒ์ด์ฌ -> ์—ฐ์‚ฐ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜ ํŒจํ‚ค์ง€ํ™” ๋˜์–ด ์ €์žฅ๋˜์–ด ์žˆ์Œ
# numpy๋ฅผ np๋กœ ์ •์˜
perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
       21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
       23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
       27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
       39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
       44.0])
perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
       115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
       150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
       218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
       556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
       850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
       1000.0])

 

์‚ฐ์ ๋„ 

ํ•˜๋‚˜์˜ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—

ํŠน์„ฑ ๋ฐ์ดํ„ฐ x์ถ•, ํƒ€๊นƒ ๋ฐ์ดํ„ฐ y์ถ•

import matplotlib.pyplot as plt         # ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ๋ฅผ ๋ ๋Š”์ง€ ์‚ฐ์ ๋„๋กœ ํ‘œ์‹œ!
plt.scatter(perch_length, perch_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

๋†์–ด์˜ ๊ธธ์ด๊ฐ€ ์ปค์ง์— ๋”ฐ๋ผ ๋ฌด๊ฒŒ๋„ ๋Š˜์–ด๋‚จ

 

ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ„๊ธฐ

train_test_split( ) ํ•จ์ˆ˜ ์‚ฌ์šฉ

from sklearn.model_selection import train_test_split  # ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ„๊ธฐ
train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42) # ์ฑ…๊ณผ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋žœ๋ค์Šคํ…Œ์ดํŠธ ์œ ์ง€

์‚ฌ์ดํ‚ท๋Ÿฐ์— ์‚ฌ์šฉํ•  ํ›ˆ๋ จ ์„ธํŠธ๋Š” 2์ฐจ์› ๋ฐฐ์—ด์ด์–ด์•ผ ํ•จ

perch_length๊ฐ€ 1์ฐจ์› ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๋‚˜๋ˆˆ train_input๊ณผ test_input๋„ 1์ฐจ์› ๋ฐฐ์—ด

1์ฐจ์› ๋ฐฐ์—ด์„ 1๊ฐœ์˜ ์—ด์ด ์žˆ๋Š” 2์ฐจ์› ๋ฐฐ์—ด๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•จ

1์ฐจ์› ๋ฐฐ์—ด์˜ ํฌ๊ธฐ = ์›์†Œ๊ฐ€ 1๊ฐœ์ธ ํŠœํ”Œ

->  ํฌ๊ธฐ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” reshape( ) ์‚ฌ์šฉ!

 

ex) [1,2,3] ํฌ๊ธฐ(3, )  -> [[1],[2],[3]] ํฌ๊ธฐ(3,1)

 

 

๋ฐฐ์—ด ํฌ๊ธฐ ๋ณ€๊ฒฝ

* reshape( ) : ๋ฐ”๊พธ๋ ค๋Š” ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •

                  ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ๋ฐ˜ํ™˜ํ•  ๋•Œ ์ง€์ •ํ•œ ํฌ๊ธฐ๊ฐ€ ์›๋ณธ ๋ฐฐ์—ด์— ์žˆ๋Š” ์›์†Œ์˜ ๊ฐœ์ˆ˜์™€ ๋‹ค๋ฅด๋ฉด ์—๋Ÿฌ

                  ex) (4, ) -> (2,3) ์—๋Ÿฌ / ์›๋ณธ ์›์†Œ 4๊ฐœ์ธ๋ฐ 2x3=6๊ฐœ๋กœ ๋ฐ”๊พธ๋ ค๊ณ  ํ•ด์„œ

ํฌ๊ธฐ์— -1 : ๋‚˜๋จธ์ง€ ์›์†Œ ๊ฐœ์ˆ˜๋กœ ๋ชจ๋‘ ์ฑ„์šฐ๊ธฐ (ํฌ๊ธฐ ์ž๋™ ์ง€์ •)

 

ex) ์ฒซ ๋ฒˆ์งธ ํฌ๊ธฐ๋ฅผ ๋‚˜๋จธ์ง€ ์›์†Œ ๊ฐœ์ˆ˜๋กœ ์ฑ„์šฐ๊ณ , ๋‘ ๋ฒˆ์žฌ ํฌ๊ธฐ๋ฅผ 1

     train_input.reshape(-1,1)

# ์‚ฌ์ดํ‚ท๋Ÿฐ์—์„œ ์‚ฌ์šฉํ•  ํ›ˆ๋ จ์„ธํŠธ๋Š” 2์ฐจ์› ๋ฐฐ์—ด, ํ˜„์žฌ ํ›ˆ๋ จ,ํ…Œ์ŠคํŠธ ์„ธํŠธ๋Š” 1์ฐจ์› ๋ฐฐ์—ด์ด๋ฏ€๋กœ ๋ณ€๊ฒฝ

train_input = train_input.reshape(-1, 1)  # reshape( )๋Š” ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •, ํฌ๊ธฐ์— -1์„ ์ง€์ •ํ•˜๋ฉด ๋‚˜๋จธ์ง€ ์›์†Œ ๊ฐœ์ˆ˜๋กœ ๋ชจ๋‘ ์ฑ„์›Œ๋ผ!!
test_input = test_input.reshape(-1, 1)
print(train_input.shape, test_input.shape)

(42, 1) (14, 1)

 

reshape(-1, 1) ๋ฐฐ์—ด์˜ ์ „์ฒด ์›์†Œ ๊ฐœ์ˆ˜๋ฅผ ๋งค๋ฒˆ ์™ธ์šฐ์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ ํŽธ๋ฆฌ

 


๊ฒฐ์ •๊ณ„์ˆ˜(R์ œ๊ณฑ)

K-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํด๋ž˜์Šค = KNeighborsRegressor

์‚ฌ์šฉ๋ฒ• : ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  fit( ) ๋ฉ”์„œ๋“œ๋กœ ํšŒ๊ท€ ๋ชจ๋ธ ํ›ˆ๋ จ

 

๊ฐ์ฒด ์ƒ์„ฑ ํšŒ๊ท€ ๋ชจ๋ธ ํ›ˆ๋ จ

# ์‚ฌ์ดํ‚ท๋Ÿฐ์—์„œ k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค_KNeighborsRegressor
from sklearn.neighbors import KNeighborsRegressor 
knr = KNeighborsRegressor()

# k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€ ๋ชจ๋ธ์„ ํ›ˆ๋ จ
knr.fit(train_input, train_target)

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ํ™•์ธ

print(knr.score(test_input, test_target)

0.992809406101064

 

์ด ์ ์ˆ˜๋Š” ๋ฌด์—‡์ผ๊นŒ์š”??

 

๋ถ„๋ฅ˜ : ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ์žˆ๋Š” ์ƒ˜ํ”Œ์„ ์ •ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฅ˜ํ•œ ๊ฐœ์ˆ˜์˜ ๋น„์œจ = ์ •ํ™•๋„ = ์ •๋‹ต์„ ๋งžํžŒ ๊ฐœ์ˆ˜์˜ ๋น„์œจ

 

ํšŒ๊ท€ : ์˜ˆ์ธกํ•˜๋Š” ๊ฐ’์ด๋‚˜ ํƒ€๊นƒ ๋ชจ๋‘ ์ž„์˜์˜ ์ˆ˜์น˜ -> ์ •ํ™•ํ•œ ์ˆซ์ž ๋งžํžˆ๊ธฐ ๋ถˆ๊ฐ€๋Šฅ

         ํšŒ๊ท€๋Š” ๊ฒฐ์ •๊ณ„์ˆ˜(R์ œ๊ณฑ)์œผ๋กœ ๊ฐ’์„ ํ‰๊ฐ€

 

> ๊ฒฐ์ •๊ณ„์ˆ˜(R์ œ๊ณฑ) ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•

1. ๊ฐ ์ƒ˜ํ”Œ์˜ ํƒ€๊นƒ๊ณผ ์˜ˆ์ธกํ•œ ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ๋”ํ•œ๋‹ค

2. ํƒ€๊นƒ๊ณผ ํƒ€๊นƒ ํ‰๊ท ์˜ ์ฐจ์ด๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ๋”ํ•œ ๊ฐ’์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค

 

ํƒ€๊นƒ์˜ ํ‰๊ท  ์ •๋„๋ฅผ ์˜ˆ์ธกํ•˜๋Š” ์ˆ˜์ค€์ด๋ผ๋ฉด R์ œ๊ณฑ์€ 0์— ๊ฐ€๊นŒ์›Œ์ง€๊ณ 

์˜ˆ์ธก์ด ํƒ€๊นƒ์— ๊ฐ€๊นŒ์›Œ์ง€๋ฉด 1์— ๊ฐ€๊นŒ์šด ๊ฐ’

 

ํƒ€๊นƒ๊ณผ ์˜ˆ์ธกํ•œ ๊ฐ’ ์‚ฌ์ด์˜ ์ฐจ์ด๋ฅผ ๊ตฌํ•ด ๋ณด๋ฉด ์–ด๋А ์ •๋„ ์˜ˆ์ธก์ด ๋ฒ—์–ด๋‚ฌ๋Š”์ง€ ๊ฐ€๋Š  ๊ฐ€๋Šฅ

-> mean_absolute_error ์ด์šฉ

 

* mean_absolute_errror : ํƒ€๊นƒ๊ณผ ์˜ˆ์ธก์˜ ์ ˆ๋Œ“๊ฐ’ ์˜ค์ฐจ๋ฅผ ํ‰๊ท ํ•˜์—ฌ ๋ฐ˜ํ™˜

 

mean_absolute_error (MAE)

# ํƒ€๊นƒ๊ณผ ์˜ˆ์ธกํ•œ ๊ฐ’ ์‚ฌ์ด์˜ ์ฐจ์ด๋ฅผ ๊ตฌํ•ด ๋ณด๋ฉด ์˜ˆ์ธก์— ์–ผ๋งˆ๋‚˜ ๋ฒ—์–ด๋‚ฌ๋Š”์ง€ ๊ฐ€๋Š ํ•˜๊ธฐ ์ข‹๋‹ค!
# ๊ฒฐ๊ณผ๋Š” ํƒ€๊นƒ๊ฐ’๊ณผ ์–ผ๋งˆ๋‚˜ ๋‹ค๋ฅธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

from sklearn.metrics import mean_absolute_error

# ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์˜ˆ์ธก์„ ๋งŒ๋“ฆ
test_prediction = knr.predict(test_input)

# ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ํ‰๊ท  ์ ˆ๋Œ“๊ฐ’ ์˜ค์ฐจ๋ฅผ ๊ณ„์‚ฐํ•จ
mae = mean_absolute_error(test_target, test_prediction)
print(mae)

19.157142857142862

๊ฒฐ๊ณผ์—์„œ ์˜ˆ์ธก์ด ํ‰๊ท ์ ์œผ๋กœ 19 ์ •๋„ ํƒ€๊นƒ๊ฐ’๊ณผ ๋‹ค๋ฅด๋‹ค

 

ํ›ˆ๋ จ ์„ธํŠธ ์ ์ˆ˜ ํ™•์ธ

print(knr.score(train_input, train_target))

0.9698823289099254

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ 0.992809406101064

ํ›ˆ๋ จ ์„ธํŠธ 0.9698823289099254


๊ณผ๋Œ€์ ํ•ฉ VS ๊ณผ์†Œ์ ํ•ฉ

๊ณผ๋Œ€์ ํ•ฉ 

ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ์ ์ˆ˜๊ฐ€ ์ข‹์•˜๋Š”๋ฐ, ํ…Œ์ŠคํŠธ ์„ธํŠธ์—์„œ๋Š” ์ ์ˆ˜๊ฐ€ ๋‚˜์˜๋‹ค

 - ํ›ˆ๋ จ์„ธํŠธ์—๋งŒ ์ž˜ ๋งž๋Š” ๋ชจ๋ธ์ด๋ผ ํ…Œ์ŠคํŠธ ์„ธํŠธ์™€ ์ƒˆ๋กœ์šด ์ƒ˜ํ”Œ์— ๋Œ€ํ•œ ์˜ˆ์ธก์„ ๋งŒ๋“ค ๋•Œ ์ž˜ ๋™์ž‘ X

 

๊ณผ์†Œ์ ํ•ฉ 

ํ›ˆ๋ จ ์„ธํŠธ๋ณด๋‹ค ํ…Œ์ŠคํŠธ ์„ธํŠธ์˜ ์ ์ˆ˜๊ฐ€ ๋†’๊ฑฐ๋‚˜, ๋‘ ์ ์ˆ˜๊ฐ€ ๋ชจ๋‘ ๋„ˆ๋ฌด ๋‚ฎ์„ ๊ฒฝ์šฐ

 - ๋ชจ๋ธ์ด ๋„ˆ๋ฌด ๋‹จ์ˆœํ•˜์—ฌ ํ›ˆ๋ จ์„ธํŠธ์— ์ ์ ํžˆ ํ›ˆ๋ จ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

 

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ 0.992809406101064  >  ํ›ˆ๋ จ ์„ธํŠธ 0.9698823289099254    -> ๊ณผ์†Œ์ ํ•ฉ

 

ํ›ˆ๋ จ ์„ธํŠธ์— ๋” ์ž˜ ๋งž๊ฒŒ ๋งŒ๋“ค๋ฉด ํ…Œ์ŠคํŠธ ์„ธํŠธ์˜ ์ ์ˆ˜ ์กฐ๊ธˆ ๋‚ฎ์•„์ง

K-์ตœ๊ทผ์ ‘ ์ด์›ƒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ชจ๋ธ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ• : ์ด์›ƒ์˜ ๊ฐœ์ˆ˜ K๋ฅผ ์ค„์ด๋Š” ๊ฒƒ

์ด์›ƒ ๊ฐœ์ˆ˜ ์ค„์ด๋ฉด - ํ›ˆ๋ จ์„ธํŠธ์— ์žˆ๋Š” ๊ตญ์ง€์ ์ธ ํŒจํ„ด์— ๋ฏผ๊ฐ

์ด์›ƒ ๊ฐœ์ˆ˜ ๋Š˜๋ฆฌ๋ฉด - ๋ฐ์ดํ„ฐ ์ „๋ฐ˜์— ์žˆ๋Š” ์ผ๋ฐ˜์ ์ด๋‹ˆ ํŒจํ„ด ๋”ฐ๋ฆ„

 

์ด์›ƒ k ๊ฐœ์ˆ˜ 3์œผ๋กœ ๋ณ€๊ฒฝ

K-์ตœ๊ทผ์ ‘ ์ด์›ƒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ธฐ๋ณธ K ๊ฐ’์€ 5 -> 3์œผ๋กœ ๋‚ฎ์ถฐ๋ณด์ž

-> n_neighbors ์†์„ฑ๊ฐ’ ๋ณ€๊ฒฝ

# ๊ณผ์†Œ์ ํ•ฉ์€ ๋ชจ๋ธ์„ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด ํ•ด๊ฒฐ์ด ๋ฉ๋‹ˆ๋‹ค!
# k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชจ๋ธ์„ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์ด์›ƒ์˜ ๊ฐœ์ˆ˜ k๋ฅผ ์ค„์ด๊ธฐ

# ์ด์›ƒ์˜ ๊ฐœ์ˆ˜๋Š” ๊ธฐ๋ณธ 5๋กœ ์„ค์ •๋˜์–ด์žˆ๋Š”๋ฐ 3์œผ๋กœ ๋ณ€๊ฒฝ
knr.n_neighbors = 3

# ๋ชจ๋ธ์„ ๋‹ค์‹œ ํ›ˆ๋ จ
knr.fit(train_input, train_target)
print(knr.score(train_input, train_target))

0.9804899950518966

k ๊ฐ’์„ ์ค„์˜€๋”๋‹ˆ ํ›ˆ๋ จ ์„ธํŠธ์˜ R์ œ๊ณฑ ์ ์ˆ˜๊ฐ€ ๋†’์•„์ง

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ํ™•์ธ

print(knr.score(test_input, test_target))

0.9746459963987609

๊ณผ์†Œ์ ํ•ฉ ํ•ด๊ฒฐ


03-2. ์„ ํ˜• ํšŒ๊ท€

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ์˜ ํ•œ๊ณ„

๋ฐ์ดํ„ฐ, ๋ชจ๋ธ ์ค€๋น„ -> ํ›ˆ๋ จ ์„ธํŠธ, ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ„๊ธฐ -> ์ตœ๊ทผ์ ‘ ์ด์›ƒ ๊ฐœ์ˆ˜ 3 ๋ชจ๋ธ

# ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ”
from sklearn.model_selection import train_test_split

train_input,  test_input, train_target, test_target = train_test_split(
    perch_length, perch_weight, random_state=42)

# ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋ฅผ 2์ฐจ์› ๋ฐฐ์—ด๋กœ ๋ฐ”๊ฟˆ
train_input = train_input.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)

from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor(n_neighbors=3)

# k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•จ
knr.fit(train_input, train_target)

๊ธธ์ด๊ฐ€ 50cm์ธ ๋†์–ด ๋ฌด๊ฒŒ ์˜ˆ์ธก

print(knr.predict([[50]]))

[1033.33333333]

์‹ค์ œ ๋†์–ด ๋ฌด๊ฒŒ๋Š” ๋” ๋‚˜๊ฐ ๋ญ๊ฐ€ ๋ฌธ์ œ????

 

์‚ฐ์ ๋„

ํ›ˆ๋ จ ์„ธํŠธ, 50cm ๋†์–ด, ์ด ๋†์–ด์˜ ์ตœ๊ทผ์ ‘ ์ด์›ƒ ํ‘œ์‹œ

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ๋ชจ๋ธ kneighbors( ) ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ - ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ด์›ƒ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ์™€ ์ด์›ƒ ์ƒ˜ํ”Œ ์ธ๋ฑ์Šค get

import matplotlib.pyplot as plt

# 50cm ๋†์–ด์˜ ์ด์›ƒ์„ ๊ตฌํ•˜๊ธฐ
distances, indexes = knr.kneighbors([[50]])

# ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„ ๊ทธ๋ฆฌ๊ธฐ
plt.scatter(train_input, train_target)

# ํ›ˆ๋ จ ์„ธํŠธ ์ค‘์—์„œ ์ด์›ƒ ์ƒ˜ํ”Œ๋งŒ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ธฐ
plt.scatter(train_input[indexes], train_target[indexes], marker='D')

# 50cm ๋†์–ด ๋ฐ์ดํ„ฐ
plt.scatter(50, 1033, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()                      # 50cm ๋†์–ด์˜ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ 45cm ๊ทผ๋ฐฉ์ด๊ธฐ ๋–„๋ฌธ์— ์ฃผ๋ณ ์ƒ˜ํ”Œ๋“ค์˜ ๋ฌด๊ฒŒ๋ฅผ ํ‰๊ท ํ•˜๋ฉด ์‹ค์ œ ๊ฐ’๊ณผ ์ฐจ์ด ์กด์žฌ

๊ธธ์ด๊ฐ€ 50cm ๋ฌด๊ฒŒ๊ฐ€ 1033g ๋†์–ด๋Š” โ–ฒ(marker='^')๋กœ ํ‘œ์‹œ ๊ทธ ์ฃผ๋ณ€์˜ ์ƒ˜ํ”Œ์€ โ—†(marker='D') 

50cm ๋†์–ด์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ 45cm ๊ทผ๋ฐฉ - k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ด ์ƒ˜ํ”Œ๋“ค ๋ฌด๊ฒŒ ํ‰๊ท 

 

์ด์›ƒ ์ƒ˜ํ”Œ์˜ ํƒ€๊นƒ ํ‰๊ท 

# ์ด์›ƒ์ƒ˜ํ”Œ์˜ ํƒ€๊นƒ์˜ ํ‰๊ท ์„ ๊ตฌํ•ด๋ณด์ž!

print(np.mean(train_target[indexes]))   # ๋ชจ๋ธ์ด ์˜ˆ์ธกํ•œ ๊ฐ’๊ณผ ์ผ์น˜. ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ˜ํ”Œ์„ ์ฐพ์•„ ํƒ€๊นƒ์„ ์˜ˆ์ธกํ•˜๋ฉด ์—‰๋šฑํ•œ ๊ฐ’์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ์Œ

1033.3333333333333

 

๋ชจ๋ธ์ด ์˜ˆ์ธกํ•œ ๊ฐ’๊ณผ ์ผ์น˜

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ˜ํ”Œ์„ ์ฐพ์•„ ํƒ€๊นƒ์„ ํ‰๊ท ํ•จ

-> ์ƒˆ๋กœ์šด ์ƒ˜ํ”Œ์ด ํ›ˆ๋ จ ์„ธํŠธ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์—‰๋šฑํ•œ ๊ฐ’ ์˜ˆ์ธก

 

๊ธธ์ด 100cm ์˜ˆ์ธก

# ์˜ˆ๋ฅผ ๋“ค์–ด ๊ธธ์ด๊ฐ€ 100cm ๋†์–ด๋„ ์•„๋งˆ๋„ 1,033g์œผ๋กœ ์˜ˆ์ธกํ•  ๊ฒƒ์œผ๋กœ ์ถ”์ธก๋จ

print(knr.predict([[100]]))

[1033.33333333]

 

์‚ฐ์ ๋„

# ๊ทธ๋ž˜ํ”„๋กœ ๊ทธ๋ ค์„œ ํ™•์ธํ•ด๋ณด์ž
distances, indexes = knr.kneighbors([[100]])

# ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„ ๊ทธ๋ฆฌ๊ธฐ
plt.scatter(train_input, train_target)

# ํ›ˆ๋ จ ์„ธํŠธ ์ค‘์—์„œ ์ด์›ƒ ์ƒ˜ํ”Œ๋งŒ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ธฐ
plt.scatter(train_input[indexes], train_target[indexes], marker='D')

# 100cm ๋†์–ด ๋ฐ์ดํ„ฐ
plt.scatter(100, 1033, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()                        # ์ด๋Ÿฐ ์‹์ด๋ฉด ๋†์–ด๊ฐ€ ์•„๋ฌด๋ฆฌ ์ปค๋„ ๋ฌด๊ฒŒ๊ฐ€ ๋” ๋Š˜์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค!

์ด๋Ÿฐ ์‹์ด๋ฉด ๋†์–ด๊ฐ€ ์•„๋ฌด๋ฆฌ ์ปค๋„ ๋ฌด๊ฒŒ๊ฐ€ ๋” ๋Š˜์–ด๋‚˜์ง€ ์•Š์Œ

-> ๋‹ค๋ฅธ ๋ชจ๋ธ ์ฐพ์•„๋ณด์ž

 

์„ ํ˜• ํšŒ๊ท€

ํŠน์„ฑ์ด ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ ์–ด๋–ค ์ง์„ ์„ ํ•™์Šตํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ทธ ํŠน์„ฑ์„ ๊ฐ€์žฅ ์ž˜ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ์ง์„  ์ฐพ๊ธฐ

sklearn.linear_model ํŒจํ‚ค์ง€ ์•„๋ž˜ LinearRegression ํด๋ž˜์Šค๋กœ ์„ ํ˜• ํšŒ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„

 

( ์‚ฌ์ดํ‚ท๋Ÿฐ ๋ชจ๋ธ ํด๋ž˜์Šค๋Š” fit( ) ํ›ˆ๋ จ, score( ) ํ‰๊ฐ€, predict( ) ์˜ˆ์ธก ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ๋ชจ๋‘ ๋™์ผ)

## ์„ ํ˜• ํšŒ๊ท€_ ์ง์„ ์„ ํ•™์Šตํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

from sklearn.linear_model import LinearRegression
lr = LinearRegression()

# ์„ ํ˜• ํšŒ๊ท€ ๋ชจ๋ธ์„ ํ›ˆ๋ จ
lr.fit(train_input, train_target)

# 50cm ๋†์–ด์— ๋Œ€ํ•ด ์˜ˆ์ธก
print(lr.predict([[50]]))

[1241.83860323]

 

k-์ตœ๊ทผ์ ‘ ์ด์›ƒ ํšŒ๊ท€๋ณด๋‹ค ์„ ํ˜• ํšŒ๊ท€๊ฐ€ ๋†์–ด์˜ ๋ฌด๊ฒŒ๋ฅผ ์•„์ฃผ ๋†’๊ฒŒ ์˜ˆ์ธก

-> ์„ ํ˜• ํšŒ๊ท€๊ฐ€ ํ•™์Šตํ•œ ์ง์„  ๊ทธ๋ ค ๋ณด์ž

 

ํ•˜๋‚˜์˜ ์ง์„ ์„ ๊ทธ๋ฆฌ๋ ค๋ฉด ๊ธฐ์šธ๊ธฐ์™€ ์ ˆํŽธ์ด ์žˆ์–ด์•ผ ํ•จ

y = a * x + b 

 

x๋ฅผ ๋†์–ด์˜ ๊ธธ์ด, y๋ฅผ ๋†์–ด์˜ ๋ฌด๊ฒŒ๋กœ ๋ฐ”๊พธ๋ฉด ์œ„์™€ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„

 

 

lr๊ฐ์ฒด ๊ธฐ์šธ๊ธฐ ์ ˆํŽธ 

LinearRegression ํด๋ž˜์Šค๊ฐ€ ์ฐพ์€ a(๊ธฐ์šธ๊ธฐ), b(์ ˆํŽธ)๋Š” lr ๊ฐ์ฒด์˜ coef_ (๊ธฐ์šธ๊ธฐ) ์™€ intercept_ (์ ˆํŽธ) ์†์„ฑ์— ์ €์žฅ

print(lr.coef_, lr.intercept_)

[39.01714496] -709.0186449535477

-> ๊ธฐ์šธ๊ธฐ 39.0174496  ์ ˆํŽธ -709.0186449535477

 

* ๋ชจ๋ธ ํŒŒ๋ผ๋ฏธํ„ฐ : coef_ intercept_ ์ฒ˜๋Ÿผ ๋จธ์‹ ๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ฐพ์€ ๊ฐ’

 

ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„, ์ง์„  ๊ทธ๋ฆฌ๊ธฐ

๋†์–ด ๊ธธ์ด 15์—์„œ 50๊นŒ์ง€ ์ง์„ 

(15, 15*39 -709)์™€ (50, 50*39 -709) ๋‘ ์ ์„ ์ด์œผ๋ฉด ๋จ

๋†์–ด์˜ ๊ธธ์ด 15์—์„œ 50๊นŒ์ง€ ์ง์„ ์œผ๋กœ ๊ทธ๋ ค์„œ ๊ทธ๋ฆผ์œผ๋กœ ๋ณด์ž!

# ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„๋ฅผ ๊ทธ๋ฆผ
plt.scatter(train_input, train_target)

# 15์—์„œ 50๊นŒ์ง€ 1์ฐจ ๋ฐฉ์ •์‹ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ฆผ
plt.plot([15, 50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])

# 50cm ๋†์–ด ๋ฐ์ดํ„ฐ
plt.scatter(50, 1241.8, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# ๊ธธ์ด๊ฐ€ 50cm์ธ ๋†์–ด์˜ ์˜ˆ์ธก์ด ์ง์„ ์˜ ์—ฐ์žฅ์„ ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Œ.

์„ ํ˜• ํšŒ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ด ๋ฐ์ดํ„ฐ์…‹์—์„œ ์ฐพ์€ ์ตœ์ ์˜ ์ง์„ 

-> ํ›ˆ๋ จ ์„ธํŠธ ๋ฒ”์œ„ ๋ฒ—์–ด๋‚œ ๋†์–ด ๋ฌด๊ฒŒ ์˜ˆ์ธก ๊ฐ€๋Šฅ!

 

ํ›ˆ๋ จ ์„ธํŠธ, ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ R์ œ๊ณฑ ์ ์ˆ˜ ํ™•์ธ

# ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ R^2์ ์ˆ˜๋ฅผ ํ™•์ธ
print(lr.score(train_input, train_target)) # ํ›ˆ๋ จ ์„ธํŠธ
print(lr.score(test_input, test_target))   # ํ…Œ์ŠคํŠธ ์„ธํŠธ

ํ›ˆ๋ จ, ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ๋†’์ง€ ์•Š์Œ... ๊ณผ์†Œ์ ํ•ฉ


๋‹คํ•ญ ํšŒ๊ท€

์„ ํ˜• ํšŒ๊ท€๊ฐ€ ๋งŒ๋“  ์ง์„ ์€ ์™ผ์ชฝ ์•„๋ž˜๋กœ ์ญ‰ ๋ป—์–ด ์žˆ์Œ

์ด ์ง์„ ๋Œ€๋กœ๋ผ๋ฉด ๋†์–ด์˜ ๋ฌด๊ฒŒ๊ฐ€ 0g ์ดํ•˜๋กœ ๋‚ด๋ ค๊ฐ .. ์žˆ์„ ์ˆ˜ ์—†๋Š”์ผ!

 

๋†์–ด ๊ธธ์ด์™€ ๋ฌด๊ฒŒ์— ๋Œ€ํ•œ ์‚ฐ์ ๋„๋ฅผ ๋ณด๋ฉด ์ผ์ง์„ ์ด๋ผ๊ธฐ๋ณด๋‹ค ์™ผ์ชฝ ์œ„๋กœ ์กฐ๊ธˆ ๊ตฌ๋ถ€๋Ÿฌ์ง„ ๊ณก์„ 

2์ฐจ ๋ฐฉ์ •์‹์˜ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ฆฌ๋ ค๋ฉด ๊ธธ์ด๋ฅผ ์ œ๊ณฑํ•œ ํ•ญ์ด ํ›ˆ๋ จ ์„ธํŠธ์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•จ

 

๋†์–ด์˜ ๊ธธ์ด๋ฅผ ์ œ๊ณฑํ•ด์„œ ์›๋ž˜ ๋ฐ์ดํ„ฐ ์•ž์— ๋ถ™์ด๊ธฐ

* column_stack( ) : 1์ฐจ์›์˜ ๋ฐฐ์—ด์„ 2์ฐจ์› ๋ฐฐ์—ด์— ์—ด๋กœ ์Œ“๋Š”๋‹ค

train_input์„ ์ œ๊ณฑํ•œ ๊ฒƒ๊ณผ train_input ๋‘ ๋ฐฐ์—ด์„ ๋‚˜๋ž€ํžˆ ๋ถ™์ด๊ธฐ test_input๋„ ๋งˆ์ฐฌ๊ฐ€์ง€

# ์ง์„ ๋Œ€๋กœ ์˜ˆ์ธกํ•˜๋ฉด ๋†์–ด์˜ ๋ฌด๊ฒŒ๊ฐ€ 0g ์ดํ•˜์ธ -๊นŒ์ง€ ๋‚ด๋ ค๊ฐˆํ…๋ฐ ํ˜„์‹ค์—์„œ๋Š” ์žˆ์„์ˆ˜ ์—†๋‹ค!
# -๊ฐ€ ์•„๋‹Œ ๊ณก์„ ์— ๊ฐ€๊นŒ์šฐ๋ฏ€๋กœ ์ตœ์ ์˜ ๊ณก์„ ์„ ์ฐพ๋Š”๊ฒŒ ๋ณด๋‹ค ํ˜„์‹ค์ ์ด๋‹ค!

## ๋‹คํ•ญ ํšŒ๊ท€_ 2์ฐจ๋ฐฉ์ •์‹์˜ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ฆฌ๋ ค๋ฉด ์ œ๊ณฑํ•œ ํ•ญ์ด ํ›ˆ๋ จ์„ธํŠธ์— ์ถ”๊ฐ€
# ๋†์–ด์˜ ๊ธธ์ด๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์•ž์— ์ถ”๊ฐ€
train_poly = np.column_stack((train_input ** 2, train_input))
test_poly = np.column_stack((test_input ** 2, test_input))

train_input **2 ์‹์—๋„ ๋„˜ํŒŒ์ด ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ… ์ ์šฉ

= train_input์— ์žˆ๋Š” ๋ชจ๋“  ์›์†Œ๋ฅผ ์ œ๊ณฑํ•œ๋‹ค

 

์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“  ๋ฐ์ดํ„ฐ์…‹ ํฌ๊ธฐ ํ™•์ธ

# ๋ชจ๋“  ์›์†Œ๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์…‹์˜ ํฌ๊ธฐ๋ฅผ ํ™•์ธ
print(train_poly.shape, test_poly.shape)

(42, 2) (14, 2)

์›๋ž˜ ํŠน์„ฑ์ธ ๊ธธ์ด๋ฅผ ์ œ๊ณฑํ•˜์—ฌ ์™ผ์ชฝ ์—ด์— ์ถ”๊ฐ€ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ›ˆ๋ จ ์„ธํŠธ, ํ…Œ์ŠคํŠธ ์„ธํŠธ ๋ชจ๋‘ ์—ด์ด 2๊ฐœ๋กœ ๋Š˜์–ด๋‚จ

 

 

train_poly ์‚ฌ์šฉ ์„ ํ˜• ํšŒ๊ท€ ๋ชจ๋ธ ๋‹ค์‹œ ํ›ˆ๋ จ

2์ฐจ ๋ฐฉ์ •์‹ ๊ทธ๋ž˜ํ”„๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ํ›ˆ๋ จ ์„ธํŠธ ์ œ๊ณฑ ํ•ญ์„ ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ, ํƒ€๊นƒ๊ฐ’์€ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ

๋ชฉํ‘œํ•˜๋Š” ๊ฐ’์€ ์–ด๋–ค ๊ทธ๋ž˜ํ”„๋ฅผ ํ›ˆ๋ จํ•˜๋“  ๋ฐ”๊ฟ€ ํ•„์š” X

 

ํ…Œ์ŠคํŠธํ•  ๋•Œ๋Š” ์ด ๋ชจ๋ธ์— ๋†์–ด ๊ธธ์ด์˜ ์ œ๊ณฑ๊ณผ ์›๋ž˜ ๊ธธ์ด๋ฅผ ํ•จ๊ป˜ ๋„ฃ์–ด์•ผ ํ•จ

# ์„ ํ˜•ํšŒ๊ท€ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•œ ๋‹ค์Œ 50cm ๋†์–ด์— ๋Œ€ํ•ด ๋ฌด๊ฒŒ ์˜ˆ์ธก 
lr = LinearRegression()
lr.fit(train_poly, train_target)

print(lr.predict([[50**2, 50]]))    # ์•ž์„œ ํ›ˆ๋ จํ•œ ๋ชจ๋ธ๋ณด๋‹ค ๋” ๋†’์€ ๊ฐ’์„ ์˜ˆ์ธกํ•จ

[1573.98423528]

 

๋ชจ๋ธ์ด ํ›ˆ๋ จํ•œ ๊ณ„์ˆ˜์™€ ์ ˆํŽธ ์ถœ๋ ฅ

print(lr.coef_, lr.intercept_)

[ 1.01433211 -21.55792498] 116.0502107827827

 

๋ฌด๊ฒŒ = 1.01 * ๊ธธ์ด์ œ๊ณฑ - 21.6 * ๊ธธ์ด + 116.05

 

์ด๋Ÿฐ ๋ฐฉ์ •์‹์„ ๋‹คํ•ญ์‹์ด๋ผ ๋ถ€๋ฅด๋ฉฐ, ๋‹คํ•ญ์‹์„ ์‚ฌ์šฉํ•œ ์„ ํ˜• ํšŒ๊ท€๋ฅผ ๋‹คํ•ญ ํšŒ๊ท€๋ผ ํ•จ

 

ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„์— ๊ทธ๋ž˜ํ”„

์งง์€ ์ง์„ ์„ ์ด์–ด์„œ ๊ทธ๋ฆฌ๋ฉด ๋งˆ์น˜ ๊ณก์„ ์ฒ˜๋Ÿผ ํ‘œํ˜„ ๊ฐ€๋Šฅ1์”ฉ ์งง๊ฒŒ ๋Š์–ด์„œ ๊ทธ๋ฆฌ๊ธฐ

#๋‹คํ•ญํšŒ๊ท€์˜ ์‚ฐ์ ๋„ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ ค์„œ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•ด๋ณด์ž! 

# ๊ตฌ๊ฐ„๋ณ„ ์ง์„ ์„ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด 15์—์„œ 49๊นŒ์ง€ ์ •์ˆ˜ ๋ฐฐ์—ด์„ ๋งŒ๋“ฆ
point = np.arange(15, 50)

# ํ›ˆ๋ จ ์„ธํŠธ์˜ ์‚ฐ์ ๋„๋ฅผ ๊ทธ๋ฆผ
plt.scatter(train_input, train_target)

# 15์—์„œ 49๊นŒ์ง€ 2์ฐจ ๋ฐฉ์ •์‹ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ฆผ
plt.plot(point, 1.01*point**2 - 21.6*point + 116.05)

# 50cm ๋†์–ด ๋ฐ์ดํ„ฐ
plt. scatter([50], [1574], marker= '^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

ํ›ˆ๋ จ ์„ธํŠธ์˜ ๊ฒฝํ–ฅ์„ ์ž˜ ๋”ฐ๋ฅด๊ณ , ๋ฌด๊ฒŒ๊ฐ€ ์Œ์ˆ˜๋กœ ๋‚˜์˜ค์ง€ X

 

ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ์˜ R์ œ๊ณฑ ์ ์ˆ˜ ํ‰๊ฐ€

# ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ์˜ R^2 ์ ์ˆ˜๋ฅผ ํ‰๊ฐ€ํ•ด๋ณด์ž
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))   # ๊ณผ์†Œ์ ํ•ฉ์ด ๋‚จ์•„์žˆ์œผ๋ฏ€๋กœ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ๋ชจ๋ธ์ด ํ•„์š”ํ•จ.

0.9706807451768623

0.9775935108325122

 

๊ณผ์†Œ์ ํ•ฉ์ด ๋‚จ์•„ ์žˆ์Œ -> ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ๋ชจ๋ธ ํ•„์š”


3-3. ํŠน์„ฑ ๊ณตํ•™๊ณผ ๊ทœ์ œ

๋‹ค์ค‘ ํšŒ๊ท€

์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•œ ์„ ํ˜• ํšŒ๊ท€

 

ํŠน์„ฑ 1๊ฐœ - ์ง์„  ํ•™์Šต

ํŠน์„ฑ 2๊ฐœ - ํ‰๋ฉด ํ•™์Šต

              ํƒ€๊นƒ = a * ํŠน์„ฑ1 + b * ํŠน์„ฑ2 + ์ ˆํŽธ

 

ํŠน์„ฑ๊ณตํ•™ : ๊ธฐ์กด์˜ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํŠน์„ฑ์„ ๋ฝ‘์•„๋‚ด๋Š” ์ž‘์—…


๋ฐ์ดํ„ฐ ์ค€๋น„

* ํŒ๋‹ค์Šค : ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์€ ํŒ๋‹ค์Šค์˜ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

# ์กฐ๊ธˆ๋” ๋ณต์žกํ•œ ๋ชจ๋ธ์„ ๋งŒ๋“œ๋ ค๋ฉด ์ œ๊ณฑ๋ณด๋‹ค ๋” ๊ณ ์ฐจํ•ญ์„ ๋„ฃ์–ด์•ผ ํ•˜๋Š”๋ฐ ํŠน์ง•์„ ์ถ”๊ฐ€ํ•ด์„œ ๊ณ ์ฐจํ•ญ์œผ๋กœ ๋งŒ๋“ค์ž
# ํŠน์„ฑ ๊ณตํ•™ - ๊ธฐ์กด์˜ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด ํŠน์„ฑ์„ ๋ฝ‘์•„๋‚ด ํŠน์ง•์„ ์ถ”๊ฐ€

## ๋ฐ์ดํ„ฐ ์ค€๋น„
import pandas as pd     # pd๋Š” ๊ด€๋ก€์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํŒ๋‹ค์Šค์˜ ๋ณ„์นญ
df = pd.read_csv('http://bit.ly/perch_csv')
perch_full = df.to_numpy()
print(perch_full)

read.csv() ํ•จ์ˆ˜๋กœ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„ ๋งŒ๋“  ๋‹ค์Œ to_numpy() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋„˜ํŒŒ์ด ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝ

 

ํƒ€๊นƒ ๋ฐ์ดํ„ฐ ์ค€๋น„

import numpy as np
perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0,
                         110.0, 115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0,
                         130.0, 150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0,
                         197.0, 218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0,
                         514.0, 556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0,
                         820.0, 850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 
                         1000.0, 1000.0])

 

ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ

perch_full๊ณผ perch_weight๋ฅผ ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆˆ๋‹ค

# ํ›ˆ๋ จ ์„ธํŠธ์™€ ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋‚˜๋ˆ„๊ธฐ
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_full, perch_weight, random_state=42)

์‚ฌ์ดํ‚ท๋Ÿฐ ๋ณ€ํ™˜๊ธฐ

์‚ฌ์ดํ‚ท๋Ÿฐ์€ ํŠน์„ฑ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์ „์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํด๋ž˜์Šค ์ œ๊ณต. ์ด๋Ÿฐ ํด๋ž˜์Šค๋ฅผ ๋ณ€ํ™˜๊ธฐ๋ผ๊ณ  ํ•จ

๋ชจ๋ธ ํด๋ž˜์Šค - fit( ), score( ), predict( )

๋ณ€ํ™˜๊ธฐ ํด๋ž˜์Šค - fit( ), transform( )

 

์‚ฌ์šฉํ•  ๋ณ€ํ™˜๊ธฐ๋Š” polynomialfeatures ํด๋ž˜์Šค

sklearn.preprocessing ํŒจํ‚ค์ง€์— ํฌํ•จ๋˜์–ด ์žˆ์Œ

## ์‚ฌ์ดํ‚ท๋Ÿฐ์˜ ๋ณ€ํ™˜๊ธฐ_ ํŠน์„ฑ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์ „์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํด๋ž˜์Šค ์ œ๊ณต
from sklearn.preprocessing import PolynomialFeatures

 

ํด๋ž˜์Šค ๊ฐ์ฒด -> fit() -> transform()

ํ›ˆ๋ จ(fit)์„ ํ•ด์•ผ ๋ณ€ํ™˜(transform) ๊ฐ€๋Šฅ

# ์˜ˆ์‹œ1
poly = PolynomialFeatures()
poly.fit([[2, 3]])               # ํ›ˆ๋ จ fit์„ ํ•ด์•ผ ๋ณ€ํ™˜ transform์ด ๊ฐ€๋Šฅํ•จ 
print(poly.transform([[2, 3]]))   # 1์€ ์ ˆํŽธ์— ๊ณฑํ•ด์ง„ ์ˆ˜

[[1. 2. 3. 4. 6. 9.]]

 

fit( ) ๋ฉ”์„œ๋“œ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค ํŠน์„ฑ ์กฐํ•ฉ ์ฐพ๊ณ  transform( ) ๋ฉ”์„œ๋“œ๋Š” ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜

๋ณ€ํ™˜๊ธฐ๋Š” ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ํƒ€๊นƒ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Œ

๋ชจ๋ธ ํด๋ž˜์Šค์™€ ๋‹ค๋ฅด๊ฒŒ fit( ) ๋ฉ”์„œ๋“œ์— ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋งŒ ์ „๋‹ฌ

 

PolynomialFeatures ๊ฐ ํŠน์„ฑ์„ ์ œ๊ณฑํ•œ ํ•ญ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ํŠน์„ฑ๋ผ๋ฆฌ ์„œ๋กœ ๊ณฑํ•œ ํ•ญ ์ถ”๊ฐ€

[[1 , 2 , 3 , 2*2, 2*3, 3*3 ]]

1์ด ์ถ”๊ฐ€๋œ ์ด์œ ?

๋ฌด๊ฒŒ = a*๊ธธ์ด + b*๋†’์ด + c*๋‘๊ป˜ +d*1

์„ ํ˜• ๋ฐฉ์ •์‹์˜ ์ ˆํŽธ์„ ํ•ญ์ƒ ๊ฐ’์ด 1์ธ ํŠน์„ฑ๊ณผ ๊ณฑํ•ด์ง€๋Š” ๊ณ„์ˆ˜

ํŠน์„ฑ์€ (๊ธธ์ด, ๋†’์ด, ๋‘๊ป˜, 1)์ด ๋จ

ํ•˜์ง€๋งŒ ์‚ฌ์ดํ‚ท๋Ÿฐ ์„ ํ˜• ๋ชจ๋ธ์€ ์ž๋™์œผ๋กœ ์ ˆํŽธ์ถ”๊ฐ€ ํ•˜๋ฏ€๋กœ ๊ตณ์ด 1 ํŠน์„ฑ ๋งŒ๋“คํ•„์š” x

include_bias=False ์ง€์ • 1 ์ œ๊ฑฐ

# ์˜ˆ์‹œ2
poly = PolynomialFeatures(include_bias=False) # ์‚ฌ์ดํ‚ท ๋Ÿฐ ์„ ํ˜•๋ชจ๋ธ์€ ์ž๋™ ์ ˆํŽธ์„ ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ ์ œ๊ฑฐ 
poly.fit([[2,3]])
print(poly.transform([[2, 3]]))

[[2. 3. 4. 6. 9.]]

 

์ ˆํŽธ์„ ์œ„ํ•œ ํ•ญ์ด ์ œ๊ฑฐ๋˜๊ณ  ํŠน์„ฑ์˜ ์ œ๊ณฑ๊ณผ ํŠน์„ฑ๋ผ๋ฆฌ ๊ณฑํ•œ ํ•ญ๋งŒ ์ถ”๊ฐ€๋จ

 

์ด ๋ฐฉ์‹์œผ๋กœ train_input ์ ์šฉ

train_input์„ ๋ณ€ํ™˜ํ•œ ๋ฐ์ดํ„ฐ train_poly ์ €์žฅ, ๋ฐฐ์—ด ํฌ๊ธฐ ํ™•์ธ

# ํŠน์„ฑ ๋งŒ๋“ค๊ธฐ๋ฅผ ์ ์šฉ, ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ํ™•์ธ_9๊ฐœ์˜ ํŠน์„ฑ
poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
print(train_poly.shape)

(42, 9)

 

ํŠน์„ฑ ์กฐํ•ฉ

* get_feature_names_out( ) : ํŠน์„ฑ์ด ๊ฐ๊ฐ ์–ด๋–ค ์ž…๋ ฅ์˜ ์กฐํ•ฉ์„ ๋งŒ๋“ค์–ด์กŒ๋Š”์ง€ ์•Œ๋ ค์คŒ

# 9๊ฐœ์˜ ํŠน์„ฑ์ด ๊ฐ๊ฐ ์–ด๋–ค ์ž…๋ ฅ์˜ ์กฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋Š”๊ฐ€
poly.get_feature_names()

['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2', 'x2^2']

 

x0 ์ฒซ๋ฒˆ์งธ ํŠน์„ฑ

x0^2 ์ฒซ๋ฒˆ์งธ ํŠน์„ฑ์˜ ์ œ๊ณฑ

x0 x1 ์ฒซ๋ฒˆ์งธ ํŠน์„ฑ๊ณผ ๋‘๋ฒˆ์จฐ ํŠน์„ฑ์˜ ๊ณฑ

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ ๋ณ€ํ™˜

# ํ…Œ์ŠคํŠธ ์„ธํŠธ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋‹ค์ค‘ ํšŒ๊ท€ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜์ž
test_poly = poly.transform(test_input)

๋‹ค์ค‘ ํšŒ๊ท€ ๋ชจ๋ธ ํ›ˆ๋ จํ•˜๊ธฐ

LinearRegression ํด๋ž˜์Šค ์ž„ํฌํŠธ, train_ploy ์‚ฌ์šฉ ๋ชจ๋ธ ํ›ˆ๋ จ

## ๋‹ค์ค‘ ํšŒ๊ท€ ๋ชจ๋ธ ํ›ˆ๋ จํ•˜๊ธฐ

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))   # ํŠน์„ฑ์ด ๋Š˜์–ด๋‚˜๋ฉด ์„ ํ˜• ํšŒ๊ท€์˜ ๋Šฅ๋ ฅ์€ ์•„์ฃผ ๊ฐ•๋ ฅํ•˜๋‹ค

0.9903183436982124

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ํ™•์ธ

#ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์ ์ˆ˜๋„ ํ™•์ธ
print(lr.score(test_poly, test_target))   # ์•ž์„  ๊ณผ์†Œ์ ํ•ฉ ๋ฌธ์ œ๋Š” ๋”์ด์ƒ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Œ

 

ํŠน์„ฑ ์ถ”๊ฐ€

* degree : ํ•„์š”ํ•œ ๊ณ ์ฐจํ•ญ์˜ ์ตœ๋Œ€ ์ฐจ์ˆ˜ ์ง€์ •

#ํŠน์„ฑ์„ ๋” ๋งŽ์ด ์ถ”๊ฐ€ํ•˜๋ฉด ์–ด๋–จ๊นŒ? 5์ œ๊ณฑ๊นŒ์ง€ ํŠน์„ฑ์„ ๋งŒ๋“ค์–ด ์ถœ๋ ฅํ•ด๋ณด์ž
poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)

print(train_poly.shape)   # ๋งŒ๋“ค์–ด์ง„ ํŠน์„ฑ์˜ ๊ฐœ์ˆ˜๊ฐ€ 55๊ฐœ๋‚˜ ๋œ๋‹ค!

(42, 55)

train_poly ๋ฐฐ์—ด์˜ ์—ด์˜ ๊ฐœ์ˆ˜๊ฐ€ ํŠน์„ฑ์˜ ๊ฐœ์ˆ˜

ํŠน์„ฑ 55๊ฐœ

 

์„ ํ˜• ํšŒ๊ท€ ๋ชจ๋ธ ๋‹ค์‹œ ํ›ˆ๋ จ

# 5์ œ๊ณฑ ํŠน์„ฑ์„ ์ ์šฉํ•œ ์„ ํ˜• ํšŒ๊ท€ ๋ชจ๋ธ์„ ๋‹ค์‹œ ํ›ˆ๋ จํ•ด๋ณด์ž
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))   # ๊ฑฐ์˜ ์™„๋ฒฝ์— ๊ฐ€๊นŒ์šด ์ ์ˆ˜๊ฐ€ ๋‚˜ํƒ€๋‚จ!

0.9999999999991097

 

ํ…Œ์ŠคํŠธ ์„ธํŠธ ์ ์ˆ˜ ํ™•์ธ

# 5์ œ๊ณฑ ํŠน์„ฑ์„ ์ ์šฉํ•œ ํ…Œ์ŠคํŠธ ์„ธํŠธ์— ๋Œ€ํ•œ ์ ์ˆ˜๋ฅผ ์•Œ์•„๋ณด์ž
print(lr.score(test_poly, test_target))     # ๊ณผ๋Œ€์ ํ•ฉ๋˜์–ด ํ…Œ์ŠคํŠธ ์ ์ˆ˜์—์„œ๋Š” ํ˜•ํŽธ์—†๋Š” ์ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋ƒ„

ํŠน์„ฑ์˜ ๊ฐœ์ˆ˜๋ฅผ ํฌ๊ฒŒ ๋Š˜๋ฆฌ๋ฉด ์„ ํ˜• ๋ชจ๋ธ์€ ์•„์ฃผ ๊ฐ•๋ ฅํ•ด์ง

ํ›ˆ๋ จ ์„ธํŠธ์— ๋Œ€ํ•ด ๊ฑฐ์˜ ์™„๋ฒฝํ•˜๊ฒŒ ํ•™์Šต

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ชจ๋ธ์€ ํ›ˆ๋ จ ์„ธํŠธ์— ๋„ˆ๋ฌด ๊ณผ๋Œ€์ ํ•ฉ - ํ…Œ์ŠคํŠธ ์„ธํŠธ์—์„œ๋Š” ํ˜•ํŽธ์—†๋Š” ์ ์ˆ˜

 


๊ทœ์ œ

๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์ด ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ ๋„ˆ๋ฌด ๊ณผ๋„ํ•˜๊ฒŒ ํ•™์Šตํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ›ผ๋ฐฉํ•˜๋Š” ๊ฒƒ

 

ํŠน์„ฑ์˜ ์Šค์ผ€์ผ์ด ์ •๊ทœํ™”๋˜์ง€ ์•Š์œผ๋ฉด ์—ฌ๊ธฐ์— ๊ณฑํ•ด์ง€๋Š” ๊ณ„์ˆ˜ ๊ฐ’๋„ ์ฐจ์ด ๋‚˜๊ฒŒ ๋จ

์„ ํ˜• ํšŒ๊ท€ ๋ชจ๋ธ์— ๊ทœ์ œ๋ฅผ ์ ์šฉํ•  ๋•Œ ๊ณ„์ˆ˜ ๊ฐ’์˜ ํฌ๊ธฐ๊ฐ€ ์„œ๋กœ ๋งŽ์ด ๋‹ค๋ฅด๋ฉด ๊ณต์ •ํ•˜๊ฒŒ ์ œ์–ด X

๋จผ์ € ์ •๊ทœํ™” !  StandafdScaler ํด๋ž˜์Šค ์‚ฌ์šฉ

## ๊ทœ์ œ_๋„ˆ๋ฌด ๊ณผ๋„ํ•˜๊ฒŒ ํ•™์Šตํ•˜์ง€ ์•Š๋„๋ก ํ›ผ๋ฐฉํ•˜์ž!

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
ss.fit(train_poly)

train_scaled = ss.transform(train_poly)   # training set๊ณผ ๊ฐ™์€ ๊ธฐ์ค€์„ ์ ์šฉ
test_scaled = ss.transform(test_poly)

StandadScaler ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ss๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ํ›„ PoltnomialFeatures ํด๋ž˜์Šค๋กœ ๋งŒ๋“  train_poly ์‚ฌ์šฉํ•ด ๊ฐ์ฒด ํ›ˆ๋ จ

ํ›ˆ๋ จ ์„ธํŠธ๋กœ ํ•™์Šตํ•œ ๋ณ€ํ™˜๊ธฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธ ์„ธํŠธ๊นŒ์ง€ ๋ณ€ํ™˜

 

 

 

 


์ฐธ๊ณ ๋„์„œ : ํ˜ผ์ž๊ณต๋ถ€ํ•˜๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ + ๋”ฅ๋Ÿฌ๋‹, ๋ฐ•ํ•ด์„ , ํ•œ๋น›๋ฏธ๋””์–ด, 2020๋…„

๋ฐ˜์‘ํ˜•

BELATED ARTICLES

more