๐Ÿš€ ์˜ค๋Š˜์˜ ํ•ญํ•ด: ๋จธ์‹ ๋Ÿฌ๋‹์˜ ๋ฐ”๋‹ค๋กœ ๋– ๋‚˜๋‹ค

์˜ค๋Š˜์€ ์ธ๊ณต์ง€๋Šฅ ์—”์ง€๋‹ˆ์–ด์˜ ๊ธธ์„ ๊ฑท๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋จผ์ € ๋งŒ๋‚˜์•ผ ํ•  ๋‘ ๊ฑฐ์ธ, ํ†ต๊ณ„์™€ ๋จธ์‹ ๋Ÿฌ๋‹์„ ๋งŒ๋‚ฌ๋‹ค. ๋‹จ์ˆœํžˆ ๋ˆˆ์œผ๋กœ๋งŒ ์ฝ๋Š” ๊ณต๋ถ€๊ฐ€ ์•„๋‹ˆ๋ผ, ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๋ฌด๋ฅด๊ณ , ํ†ต๊ณ„์˜ ์›๋ฆฌ๋ฅผ ํŒŒํ—ค์น˜๋ฉฐ ๋”ฅ๋Ÿฌ๋‹์˜ ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„์ธ ํผ์…‰ํŠธ๋ก ๊นŒ์ง€ ์ง์ ‘ ๋งŒ๋“ค์–ด๋ณด๋Š” ๊ฒฝํ—˜์„ ํ–ˆ๋‹ค. ๐Ÿ˜„

:guard: โ€œ๋ฐ์ดํ„ฐ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋ฉด, ๋ชจ๋ธ์€ ๊ทธ์ € ํ—ˆ์ƒ์ผ ๋ฟ์ด๋‹ค.โ€

๋ชจ๋ธ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์–ด์ฉŒ๋ฉด ์‰ฌ์šธ์ง€๋„ ๋ชจ๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ ๋ชจ๋ธ์ด ์™œ ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€, ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋จน๊ณ  ์ž๋ž๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค๋ฉด, ์ž‘์€ ๋ณ€ํ™”์—๋„ ์‰ฝ๊ฒŒ ๋ฌด๋„ˆ์ง€๋Š” ๋ชจ๋ž˜์„ฑ์„ ์Œ“๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.


๐Ÿ ๊ธฐ๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค€๋น„

๋ชจ๋“  ์ฝ”๋“œ๋Š” ํ™˜๊ฒฝ์„ค์ •๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค! ๋ฐ์ดํ„ฐ ๋ถ„์„๊ณผ ๋จธ์‹ ๋Ÿฌ๋‹์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์œผ๋กœ ํ•™์Šต์„ ์‹œ์ž‘ํ–ˆ๋‹ค.

import warnings # ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€ ๋ฌด์‹œ
warnings.filterwarnings('ignore')

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# numpy ์ถœ๋ ฅ ์˜ต์…˜ ๋ณ€๊ฒฝ (์ง€์ˆ˜ํ‘œ๊ธฐ๋ฒ• ๋ฐฉ์ง€)
np.set_printoptions(suppress=True)

๐Ÿ“Š ๊ธฐ์ˆ ํ†ต๊ณ„: ๋ฐ์ดํ„ฐ์˜ ๋ฏผ๋‚ฏ ๋“ค์—ฌ๋‹ค๋ณด๊ธฐ

์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์•ฝ, ๋ฌ˜์‚ฌ, ์„ค๋ช…ํ•˜๋Š” ๊ธฐ์ˆ ํ†ต๊ณ„๋Š” ๋ฐ์ดํ„ฐ์˜ ์ „๋ฐ˜์ ์ธ ํŠน์ง•์„ ํŒŒ์•…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

1. ์ค‘์‹ฌ์— ๋Œ€ํ•œ ํ†ต๊ณ„ (feat. ๋„๋ฏธ ๋ฐ์ดํ„ฐ :fish:)

๋ฐ์ดํ„ฐ์˜ ์ค‘์‹ฌ ๊ฒฝํ–ฅ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’๋“ค์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ๋„๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ pandas์˜ DataFrame์œผ๋กœ ๋งŒ๋“ค์–ด ๊ฐ์ข… ํ†ต๊ณ„๋Ÿ‰์„ ์ง์ ‘ ๊ตฌํ•ด๋ณด์•˜๋‹ค.

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

# ๋„๋ฏธ ๋ฐ์ดํ„ฐ (๊ธธ์ด, ๋ฌด๊ฒŒ)
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

df = pd.DataFrame(zip(bream_length, bream_weight), columns=['length', 'weight'])

- ํ‰๊ท , ์ค‘์•™๊ฐ’, ์ตœ๋นˆ๊ฐ’ ๊ณ„์‚ฐ

describe() ํ•จ์ˆ˜๋กœ ๊ธฐ๋ณธ์ ์ธ ํ†ต๊ณ„๋Ÿ‰์„ ํ•œ ๋ฒˆ์— ํ™•์ธํ•˜๊ณ , value_counts()๋กœ ์ตœ๋นˆ๊ฐ’์„ ๊ตฌํ–ˆ๋‹ค.

# ๊ธฐ๋ณธ ํ†ต๊ณ„๋Ÿ‰ (ํ‰๊ท -mean, ์ค‘์•™๊ฐ’-50%)
df.describe()

# ์ตœ๋นˆ๊ฐ’ (๊ฐ€์žฅ ๋งŽ์ด ๋“ฑ์žฅํ•˜๋Š” ๊ฐ’)
df.length.value_counts().head(1)
๊ตฌ๋ถ„ ์„ค๋ช…
ํ‰๊ท  (Mean) ๋ชจ๋“  ๊ฐ’์„ ๋”ํ•ด ๊ฐœ์ˆ˜๋กœ ๋‚˜๋ˆˆ ๊ฐ’. describe()์˜ mean์— ํ•ด๋‹น
์ค‘์•™๊ฐ’ (Median) ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ–ˆ์„ ๋•Œ ์ค‘์•™์— ์œ„์น˜ํ•˜๋Š” ๊ฐ’. describe()์˜ 50%์— ํ•ด๋‹น
์ตœ๋นˆ๊ฐ’ (Mode) ๊ฐ€์žฅ ์ž์ฃผ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฐ’. value_counts()๋กœ ํ™•์ธ ๊ฐ€๋Šฅ

2. ์‚ฐํฌ์— ๋Œ€ํ•œ ํ†ต๊ณ„

๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘์‹ฌ์œผ๋กœ๋ถ€ํ„ฐ ์–ผ๋งˆ๋‚˜ ํฉ์–ด์ ธ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

- ๋ถ„์‚ฐ๊ณผ ํ‘œ์ค€ํŽธ์ฐจ ๊ณ„์‚ฐ

# 1. ํŽธ์ฐจ (Deviation)
mean_ = df.length.mean()
deviation = df.length - mean_

# 2. ๋ณ€๋™ (Variation) - ํŽธ์ฐจ์˜ ์ œ๊ณฑํ•ฉ
variation = deviation**2

# 3. ๋ถ„์‚ฐ (Variance)
variance = sum(variation) / len(variation)

# 4. ํ‘œ์ค€ํŽธ์ฐจ (Standard Deviation)
std = np.sqrt(variance)

3. ์ •๊ทœํ™”์™€ ํ‘œ์ค€ํ™”

๋ฐ์ดํ„ฐ์˜ ๋‹จ์œ„๋ฅผ ๋งž์ถฐ์ฃผ์–ด(์Šค์ผ€์ผ๋ง) ๋ชจ๋ธ์ด ๋” ์ž˜ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค.

- ํ‘œ์ค€ํ™” (Standardization, Z-score)

๋ฐ์ดํ„ฐ์—์„œ ํ‰๊ท ์„ ๋นผ๊ณ  ํ‘œ์ค€ํŽธ์ฐจ๋กœ ๋‚˜๋ˆ„์–ด, ํ‰๊ท  0, ํ‘œ์ค€ํŽธ์ฐจ 1์ธ ๋ถ„ํฌ๋กœ ๋ณ€ํ™˜

# ๋„๋ฏธ ๊ธธ์ด(length)๋ฅผ ํ‘œ์ค€ํ™”
z_length = (df.length - df.length.mean()) / np.std(df.length)

# ๋„๋ฏธ ๋ฌด๊ฒŒ(weight)๋ฅผ ํ‘œ์ค€ํ™”
z_weight = (df.weight - df.weight.mean()) / np.std(df.weight)

# ํ‘œ์ค€ํ™”๋œ ๋ฐ์ดํ„ฐ ํ™•์ธ
new_df = pd.DataFrame(zip(z_length, z_weight), columns=['length_z', 'weight_z'])
new_df.describe()

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด mean์€ 0์— ๊ฐ€๊น๊ณ , std๋Š” 1์— ๊ฐ€๊นŒ์šด ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๐ŸŽ‰


:brain: ๋”ฅ๋Ÿฌ๋‹: ํผ์…‰ํŠธ๋ก ์œผ๋กœ ๋ง›๋ณด๊ธฐ

๋”ฅ๋Ÿฌ๋‹์˜ ๊ธฐ๋ณธ ๋‹จ์œ„์ธ ๋‰ด๋Ÿฐ(ํผ์…‰ํŠธ๋ก )์ด ์–ด๋–ป๊ฒŒ ํ•™์Šตํ•˜๋Š”์ง€ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.

- ํผ์…‰ํŠธ๋ก  ํ•™์Šต ๊ณผ์ •

x=1์ด ์ž…๋ ฅ๋˜๋ฉด y=0์„ ์ถœ๋ ฅํ•˜๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ•œ ๋‰ด๋Ÿฐ

# y = wx + b
w = np.random.uniform(0, 1) # ๊ฐ€์ค‘์น˜(w)๋Š” ๋žœ๋ค ๊ฐ’์œผ๋กœ ์‹œ์ž‘
x = 1
y = 0
eta = 0.1  # ํ•™์Šต๋ฅ  (learning rate)

for i in range(10): # 10๋ฒˆ ๋ฐ˜๋ณต ํ•™์Šต
    output = w * x      # ์˜ˆ์ธก๊ฐ’ ๊ณ„์‚ฐ
    error = y - output  # ์‹ค์ œ๊ฐ’๊ณผ ์˜ˆ์ธก๊ฐ’์˜ ์ฐจ์ด(์˜ค์ฐจ) ๊ณ„์‚ฐ
    
    # ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•: ์˜ค์ฐจ์˜ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€์ค‘์น˜๋ฅผ ์—…๋ฐ์ดํŠธ
    w = w + (x * error) * eta
    
    print(f"{i+1}ํšŒ์ฐจ ๊ฐ€์ค‘์น˜: {w:.4f}, ์˜ค์ฐจ: {error:.4f}")

print(f"\n์ตœ์ข… ์˜ˆ์ธก๊ฐ’: {w*x:.4f}")

ํ•™์Šต์ด ๋ฐ˜๋ณต๋ ์ˆ˜๋ก ๊ฐ€์ค‘์น˜(w)๊ฐ€ ์ ์ฐจ ๊ฐฑ์‹ ๋˜๋ฉด์„œ ์˜ค์ฐจ(error)๊ฐ€ 0์— ๊ฐ€๊นŒ์›Œ์ง€๊ณ , ์ตœ์ข… ์˜ˆ์ธก๊ฐ’์ด ๋ชฉํ‘œ์ธ 0์— ์ˆ˜๋ ดํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. :bulb:


โœจ ์˜ค๋Š˜์˜ ํšŒ๊ณ 

์˜ค๋Š˜ ํ•™์Šต์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์™€ ๋ชจ๋ธ์˜ ๊ด€๊ณ„๋ฅผ ์–ด๋ ดํ’‹์ด๋‚˜๋งˆ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํŠนํžˆ ๊ฐ„๋‹จํ•œ ํผ์…‰ํŠธ๋ก  ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด, ๋ณต์žกํ•˜๊ฒŒ๋งŒ ๋А๊ปด์กŒ๋˜ โ€˜ํ•™์Šตโ€™์ด๋ผ๋Š” ๊ณผ์ •์ด ๊ฒฐ๊ตญ โ€˜์˜ค์ฐจ๋ฅผ ์ค„์—ฌ๋‚˜๊ฐ€๋Š” ์—ฌ์ •โ€™์ด๋ผ๋Š” ๊ฒƒ์„ ์ฒด๊ฐํ–ˆ๋‹ค.
์•ž์œผ๋กœ ๋ฐฐ์šธ ๋” ๋ณต์žกํ•œ ๋ชจ๋ธ๋“ค๋„ ๊ฒฐ๊ตญ์€ ์ด ๊ธฐ๋ณธ ์›๋ฆฌ ์œ„์— ์„œ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์„ ํ•˜๋‹ˆ, ์™ ์ง€ ๋ชจ๋ฅผ ์ž์‹ ๊ฐ์ด ์ƒ๊ธด๋‹ค. ๋‹ค์Œ์—๋Š” ๋” ๋‹ค์–‘ํ•œ ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ๋“ค์„ ๋งŒ๋‚˜๊ณ , ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์งˆ ์˜ˆ์ •์ด๋‹ค.๐Ÿ”ฅ