240603 Today I Learn
๋จธ์ ๋ฌ๋์ด๋?
๐ก ๋จธ์ ๋ฌ๋(Machine Learning, ML)
๊ด์ธก๋ ํจํด์ ๊ธฐ๋ฐ์ผ๋ก ์์ฌ ๊ฒฐ์ ์ ํ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ. ๊ธฐ์ ํต๊ณ ๋ฑ์ ํตํ์ฌ ์ง๊ณ๋ ์ ๋ณด๋ก ์์ฌ๊ฒฐ์ ์ ํ๋ ๊ณผ๊ฑฐ์ ๋ฌ๋ฆฌ ๋ฐ์ดํฐ ์์ง๊ณผ ์ฒ๋ฆฌ ๊ธฐ์ ์ ๋ฐ์ ์ผ๋ก ๋์ฉ๋ ๋ฐ์ดํฐ์ ํจํด์ ์ธ์ํ๊ณ ์ด๋ฅผ ๋ฐํ์ผ๋ก ์์ธก, ๋ถ๋ฅํ๋ ๋ฐฉ๋ฒ๋ก .
๋จธ์ ๋ฌ๋์ ์ข ๋ฅ
- ์ง๋ํ์ต : ๋ฌธ์ ์ ์ ๋ต์ ๋ชจ๋ ์๋ ค์ฃผ๊ณ ๊ณต๋ถ์ํค๋ ๋ฐฉ๋ฒ
- ์์ธก
- ๋ถ๋ฅ
- ๋น์ง๋ํ์ต : ๋ต์ ์๋ ค์ฃผ์ง ์๊ณ ๊ณต๋ถ์ํค๋ ๋ฐฉ๋ฒ
- ์ฐ๊ด๊ท์น
- ๊ตฐ์ง
- ๊ฐํํ์ต : ๋ณด์์ ํตํด ์์ ์ต๋ํ, ๋ฒ์ ์ต์ํ ํ๋ ๋ฐฉํฅ์ผ๋ก ํ์๋ฅผ ๊ฐํ
์ ํํ๊ท๋ถ์ ์ด๋ก
๐ก์ ํํ๊ท(Linear Regression)
์ข ์ ๋ณ์ y์ ํ ๊ฐ ์ด์์ ๋ ๋ฆฝ ๋ณ์ (๋๋ ์ค๋ช ๋ณ์) X์์ ์ ํ ์๊ด ๊ด๊ณ๋ฅผ ๋ชจ๋ธ๋งํ๋ ํ๊ท๋ถ์ ๊ธฐ๋ฒ
→ ํ๊ท ๊ณ์ ํน์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ ์๋ฉด X๊ฐ ์ฃผ์ด์ก์ ๋ Y๊ฐ์ ์์ธกํ ์ ์๋ค.
ํ๊ฐ์งํ
๐ก MSE (Mean Squared Error)
์ค์ฐจ ์ ๊ณฑํฉ(SSE)์ ๋ฐ์ดํฐ์ ์๋ก ๋๋ ๊ฒ
๐ก R-squared
์ ์ฒด ๋ชจํ์์ ํ๊ท์ ์ผ๋ก ์ค๋ช ํ ์ ์๋ ์ ๋ / ์ ์ฒด y ์ ๋ณ๋๋ ์ค์ ํ๊ท๋ชจํ์ด ์ค๋ช ํ๋ ๋ณ๋๋(SSreg)์ ๋น์จ
์ ํํ๊ท๋ถ์ ์ค์ต
ํ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ/ ํจ์
# ํ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
import sklearn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
์ ํํ๊ท์ ์ ํฉํ๊ธฐ
# ์ ํํ๊ท ๋ชจ๋ธ์ model_lr๋ก ๋ถ๋ฌ์ค๊ธฐ
from sklearn.linear_model import LinearRegression
model_lr = LinearRegression()
# ๋ฐ์ดํฐ ํ๋ จ
model_lr.fit(X = body_df[['weight']], # 'X='์ ์
๋ ฅํ๊ณ ์ถ๋ค๋ฉด ๋ฐ๋์ ๋๋ฌธ์๋ก!
y = body_df[['height']])
# ๊ฐ์ค์น(w1)
w1 = model_lr.coef_[0][0]
w1 = w1.round(2) #๋ฐ์ฌ๋ฆผ
# ํธํฅ(bias, w0)
w0 = model_lr.intercept_[0]
w0 = w0.round(2) #๋ฐ์ฌ๋ฆผ
# ํ๊ท์
print(f'y = {w1}x + {w0}')
## y = 0.86x + 109.37
๋ฐฉ๋ฒ 1 | W0, W1 ๊ฐ์ ์ถ์ถํด ํ๊ท์์ผ๋ก predict ๊ณ์ฐํ๊ธฐ
body_df['y_pred1'] = body_df['weight']*w1 + w0
๋ฐฉ๋ฒ 2| predict ์ด์ฉํ๊ธฐ
y_pred2 = model_lr.predict(body_df[['weight']])
## array([[184.40385835],
## [179.22878362],
## [180.09129608],
## [188.71642061],
## [186.99139571],
## [161.97853455],
## [183.54134589],
## [166.29109682],
## [168.87863418],
## [168.87863418]])
๋ชจ๋ธ ํ๊ฐํ๊ธฐ
- ํ๊ท : MSE
- R-Squared ๊ฐ์ด 1์ ๊ฐ๊น์ธ ์๋ก ๋์๊ฒ
๋ฐฉ๋ฒ 1 | ์ง์ MSE ๊ณ์ฐํ๊ธฐ
# ์์ธก๊ฐ ์ปฌ๋ผ(pred) ๋ง๋ค๊ธฐ
body_df['pred'] = body_df['weight']*w1 + w0
# ์ค์ ๊ฐ(body_df['height'])๊ณผ ์์ธก๊ฐ(body_df['pred'])์ ์ฐจ์ด
body_df['error'] = body_df['height'] - body_df['pred']
# ์๋ฌ ์ ๊ณฑ ๊ณ์ฐํ๊ธฐ
body_df['squared_error'] = body_df['error']*body_df['error']
# MSE๊ณ์ฐ ์๋ฃ 10
body_mse = body_df['squared_error'].sum()/len(body_df)
body_mse
## 10.190499999999975
๋ฐฉ๋ฒ 2 | sklearn ํจํค์ง ์ด์ฉํ๊ธฐ
# ํจํค์ง ๋ถ๋ฌ์ค๊ธฐ
from sklearn.metrics import mean_squared_error, r2_score
# ํ๊ฐํจ์๋ ๊ณตํต์ ์ผ๋ก ์ ๋ต(์ค์ true), ์์ธก๊ฐ(pred)
y_true = body_df['height']
y_pred = body_df['pred']
mean_squared_error(y_true, y_pred) ## 10.152939045376318
r2_score(y_true, y_pred) ## 0.8899887415172141
๊ทธ๋ํ์ ํ๊ท ์ ๋ํ๋ด๊ธฐ
# weight์ height๊ฐ์ ์ฐ์ ๋(scatter plot) ๊ทธ๋ฆฌ๊ธฐ
sns.scatterplot( data = body_df, x = 'weight', y = 'height')
plt.title('Weight vs Height')
plt.xlabel('weight(kg)')
plt.ylabel('Height (cm)')
plt.show()
# ์ฐ์ ๋ ์์ lineplot(ํ๊ท์ ๊ทธ๋ํ) ์ถ๊ฐํ๊ธฐ
sns.lineplot(data = body_df, x = 'weight', y = 'pred', color = 'red')
์ ํํ๊ท๋ถ์ ์ค์ต - Tips
# ์ฌ์ฉ ๋ฐ์ดํฐ์
tips = sns.load_dataset('tips')
๐ ๋ฌธ์
์๋น์์ ํํธํ์์ผ๋ก ์ผํ๊ณ ์๋ ๋จธ์ ์ด๋ ์ด๋ฒ์๋ tip ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ ์ฉํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค. ๋์ ๋ง์ด ๋ฒ๊ณ ์ถ์๋ ๋จธ์ ์ด๋ ์ ์ฒด ๊ธ์ก(X)๋ฅผ ์๋ฉด ๋ฐ์ ์ ์๋ ํ(Y)์ ๋ํ ํ๊ท๋ถ์์ ์งํํด๋ณผ ์์ ์ ๋๋ค.
# ์ ํํ๊ท ํ๋ จ(์ ํฉ)
from sklearn.linear_model import LinearRegression
model_lr = LinearRegression()
# ์ ์ฒด ๊ธ์ก(X)๋ฅผ ์๋ฉด ๋ฐ์ ์ ์๋ ํ(Y)์ ๋ํ ํ๊ท๋ถ์
model_lr.fit(X = tips[['total_bill']],
y = tips[['tip']])
# ํ๊ท์ ๊ตฌํ๊ธฐ
w1_tips = model_lr.coef_[0][0]
w0_tips = model_lr.intercept_[0]
print(f'y = {w1_tips:.2f}x + {w0_tips:.2f}') ## y = 0.11x + 0.92
# ๋ชจ๋ธ ํ๊ฐํ๊ธฐ
from sklearn.metrics import mean_squared_error, r2_score
y_pred_tip = model_lr.predict(tips[['total_bill']]) # ์์ธก๊ฐ
mse_tip = mean_squared_error(tips['tip'], y_pred_tip) # mse : 1.036019442011377
r_squared_tip = r2_score(tips['tip'], y_pred_tip) #r-squared : 0.45661658635167657
- mse๋ ๊ฐ์ ๋ฐ์ดํฐ ์ ์ ๋ํด ๋ค๋ฅธ ๋ชจ๋ธ์ ๋น๊ตํ๋๋ฐ ์ฌ์ฉ (→ ๋จ์๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์)
- r-squared์ ๊ฒฝ์ฐ ์ฝ 0.46์ผ๋ก ์ข์ ๋ชจ๋ธ์ ์๋ (1์ ๊ฐ๊น์ธ ์๋ก ์ข์ ๋ชจ๋ธ)
# ์ฐ์ ๋ ๊ทธ๋ฆฌ๊ธฐ
sns.scatterplot(data=tips, x='total_bill', y = 'tip', alpha = 0.7, color = 'pink')
plt.title('Tip Distribution by Total Bill')
# ํ๊ท์ ์ถ๊ฐํ๊ธฐ
tips['pred'] = y_pred_tip
sns.lineplot(data=tips, x = 'total_bill', y = 'pred', color = 'green')