본문 바로가기
카테고리 없음

파도!(15) - 라쏘회귀와 4차방정식까지

🍿 '파도'는 파이스크립트 도전기의 줄임말입니다.

지난 게시글에서 연재되는 글입니다. : https://itadventure.tistory.com/555

 

파도!(14) - 릿지 리그레션으로 정확도가 높아진다구?

※ '파도'는 파이스크립트 도전기의 준말입니다. 지난 게시글에 연재되는 글입니다 : https://itadventure.tistory.com/554 파도!(13) - 음? 인공지능 적중율이?! - 평균가격 추가 '파도'는 파이스크립트 도전

itadventure.tistory.com

 

제목은 4차 방정식이지만 실제 4차 방정식을 계산할 일은 없으니 겁먹지 마시기 바랍니다 :)

지난 시간에는 차수를 이용하여 머신러닝 결과가 좀 더 원본에 근접하도록 했었지요.
하지만 훈련데이터에 특화되다 보니 정작 테스트데이터를 예측할 때 거리가 먼 문제를 해결하기 위해
릿지 리그레션(Ridge Regression) 를 사용하여 과적합이라 불리는 문제를 해결했습니다.

이번 시간에는 릿지 리그레션과 비슷한 과적합 문제를 방지하기 위해 라쏘 리그레션(Lasso Regression)을 적용해볼텐데요.
사실 어떤게 더 나은지 아직 감은 안 옵니다. 하지만 알아둬서 나쁠건 없기 때문에 도전해 보기로 했습니다 :)

 

차수를 더 많이 줘볼까?

 

지난번에는 연도의 제곱, 월의 제곱, 평균가의 제곱 등을 추가 데이터로 넣어 정확도가 많이 높아졌었지요.
이번에는 연도의 세제곱, 연도의 네제곱과 같은 값도 제공하도록 해봅시다.
아울러 연도와 월을 곱한 수치도 넣고, 평균가와 일의 제곱을 곱한 수치도 넣고..
이걸 언제 다 넣지....?
갑자기 귀차니즘이 생겨서 그만 글을 쓰렵니다.
그러면 여러분 안녕히- ( 이봐... )
   


   .. 🚀 ..🚀 ..🚀
 

흠흠.. 요는 이런 귀찮은 일을 하지 말자는 겁니다.
그럼 어떻게 하냐구요?
바로 머신 러닝에게 맡기면 되는 겁니다:)

이러한  각각의 원본데이터의 제곱, 세제곱, 네제곱, 연도 x 월 같은 데이터를 일일히 하나씩 추가하는 건 꽤나 귀찮은 일입니다.
지난번 제곱수만 추가하는데 코드가 이만큼이었는데,

주간매출데이터훈련_넘파이 = np.column_stack(( 
  주간매출데이터훈련_넘파이 ,
  주간매출데이터훈련_넘파이[:,0] ** 2,
  주간매출데이터훈련_넘파이[:,1] ** 2,
  주간매출데이터훈련_넘파이[:,2] ** 2,
  주간매출데이터훈련_넘파이[:,3] ** 2,
  주간매출데이터훈련_넘파이[:,4] ** 2,
  주간매출데이터훈련_넘파이[:,5] ** 2
))

네제곱까지, 게다가 각각의 항목을 조합해서 곱한다고 칠 때,
어휴 그 양이 무시무시하겠지요. 생각하기도 복잡하구요.

싸이킷런에는 이런 무식한 일을 방지하기 위한 기능이 마련되어 있는데요.
바로 PolynomialFeatures ( 폴리노미얼 피쳐 ), 다항특성 모듈입니다.
이 글에서는 간단히 '폴리'라는 애칭(?)을 주어 부르도록 하겠습니다.'폴리'모듈 사용법은 3단계로 아래와 같은데요

1) 폴리 모듈을 불러와 다항식 모델을 만듭니다.

from sklearn.preprocessing import PolynomialFeatures

폴리 = PolynomialFeatures(degree=4, include_bias=False)

2) 훈련용데이터를 넣어 틀에 맞게 훈련시킵니다.

폴리.fit(훈련용데이터)

3) 훈련된 다항식 모델에 데이터를 넣으면 새로운 데이터가 나옵니다.

훈련용데이터_가공 = 폴리.transform(훈련용데이터)
테스트데이터_가공 = 폴리.transform(테스트데이터)

그러면 이랬던 훈련용 데이터가,

[1420297200.0 2015 1 4 1.3012962962962962]

이런 '훈련용데이터_가공'으로 바뀝니다!!
원래 6개의 자료가 120개가 넘게 되었군요!

[1.42029720e+09 2.01500000e+03 1.00000000e+00 4.00000000e+00 1.30129630e+00 
2.01724414e+18 2.86189886e+12 1.42029720e+09 5.68118880e+09 1.84822749e+09 
4.06022500e+06 2.01500000e+03 8.06000000e+03 2.62211204e+03 1.00000000e+00 
4.00000000e+00 1.30129630e+00 1.60000000e+01 5.20518519e+00 1.69337205e+00 
2.86508620e+27 4.06474693e+21 2.01724414e+18 8.06897655e+18 2.62503232e+18 
5.76672620e+15 2.86189886e+12 1.14475954e+13 3.72417838e+12 1.42029720e+09 
5.68118880e+09 1.84822749e+09 2.27247552e+10 7.39290994e+09 2.40509158e+09 
8.18135338e+09 4.06022500e+06 1.62409000e+07 5.28355575e+06 2.01500000e+03 
8.06000000e+03 2.62211204e+03 3.22400000e+04 1.04884481e+04 3.41214468e+03 
1.00000000e+00 4.00000000e+00 1.30129630e+00 1.60000000e+01 5.20518519e+00 
1.69337205e+00 6.40000000e+01 2.08207407e+01 6.77348820e+00 2.20357878e+00 
4.06927391e+36 5.77314869e+30 2.86508620e+27 1.14603448e+28 3.72832606e+27 
8.19046507e+24 4.06474693e+21 1.62589877e+22 5.28944013e+21 2.01724414e+18 
8.06897655e+18 2.62503232e+18 3.22759062e+19 1.05001293e+19 3.41594484e+18 
1.16199533e+19 5.76672620e+15 2.30669048e+16 7.50421944e+15 2.86189886e+12 
1.14475954e+13 3.72417838e+12 4.57903817e+13 1.48967135e+13 4.84625954e+12 
1.42029720e+09 5.68118880e+09 1.84822749e+09 2.27247552e+10 7.39290994e+09 
2.40509158e+09 9.08990208e+10 2.95716398e+10 9.62036633e+09 3.12973677e+09 
1.64854271e+13 8.18135338e+09 3.27254135e+10 1.06463648e+10 4.06022500e+06
1.62409000e+07 5.28355575e+06 6.49636000e+07 2.11342230e+07 6.87547153e+06 
2.01500000e+03 8.06000000e+03 2.62211204e+03 3.22400000e+04 1.04884481e+04 
3.41214468e+03 1.28960000e+05 4.19537926e+04 1.36485787e+04 4.44021124e+03 
1.00000000e+00 4.00000000e+00 1.30129630e+00 1.60000000e+01 5.20518519e+00 
1.69337205e+00 6.40000000e+01 2.08207407e+01 6.77348820e+00 2.20357878e+00 
2.56000000e+02 8.32829630e+01 2.70939528e+01 8.81431511e+00 2.86750890e+00]

위 숫자들의 정체는은 아래 명령을 이용해 특성 목록을 출력하면 알 수 있는데요.

print(폴리.get_feature_names_out())

그 결과는 아래와 같습니다. 

['x0' 'x1' 'x2' 'x3' 'x4' 
'x0^2' 'x0 x1' 'x0 x2' 'x0 x3' 'x0 x4' 
'x1^2' 'x1 x2' 'x1 x3' 'x1 x4' 'x2^2' 
'x2 x3' 'x2 x4' 'x3^2' 'x3 x4' 'x4^2' 
'x0^3' 'x0^2 x1' 'x0^2 x2' 'x0^2 x3' 'x0^2 x4' 
'x0 x1^2' 'x0 x1 x2' 'x0 x1 x3' 'x0 x1 x4' 'x0 x2^2' 
'x0 x2 x3' 'x0 x2 x4' 'x0 x3^2' 'x0 x3 x4' 'x0 x4^2' 
'x1^3' 'x1^2 x2' 'x1^2 x3' 'x1^2 x4' 'x1 x2^2' 
'x1 x2 x3' 'x1 x2 x4' 'x1 x3^2' 'x1 x3 x4' 'x1 x4^2' 
'x2^3' 'x2^2 x3' 'x2^2 x4' 'x2 x3^2' 'x2 x3 x4' 
'x2 x4^2' 'x3^3' 'x3^2 x4' 'x3 x4^2' 'x4^3' 
'x0^4' 'x0^3 x1' 'x0^3 x2' 'x0^3 x3' 'x0^3 x4' 
'x0^2 x1^2' 'x0^2 x1 x2' 'x0^2 x1 x3' 'x0^2 x1 x4' 'x0^2 x2^2'
'x0^2 x2 x3' 'x0^2 x2 x4' 'x0^2 x3^2' 'x0^2 x3 x4' 'x0^2 x4^2' 
'x0 x1^3' 'x0 x1^2 x2' 'x0 x1^2 x3' 'x0 x1^2 x4' 'x0 x1 x2^2' 
'x0 x1 x2 x3' 'x0 x1 x2 x4' 'x0 x1 x3^2' 'x0 x1 x3 x4' 'x0 x1 x4^2' 
'x0 x2^3' 'x0 x2^2 x3' 'x0 x2^2 x4' 'x0 x2 x3^2' 'x0 x2 x3 x4' 
'x0 x2 x4^2' 'x0 x3^3' 'x0 x3^2 x4' 'x0 x3 x4^2' 'x0 x4^3' 
'x1^4' 'x1^3 x2' 'x1^3 x3' 'x1^3 x4' 'x1^2 x2^2' 
'x1^2 x2 x3' 'x1^2 x2 x4' 'x1^2 x3^2' 'x1^2 x3 x4' 'x1^2 x4^2' 
'x1 x2^3' 'x1 x2^2 x3' 'x1 x2^2 x4' 'x1 x2 x3^2' 'x1 x2 x3 x4' 
'x1 x2 x4^2' 'x1 x3^3' 'x1 x3^2 x4' 'x1 x3 x4^2' 'x1 x4^3' 
'x2^4' 'x2^3 x3' 'x2^3 x4' 'x2^2 x3^2' 'x2^2 x3 x4' 
'x2^2 x4^2' 'x2 x3^3' 'x2 x3^2 x4' 'x2 x3 x4^2' 'x2 x4^3'
'x3^4' 'x3^3 x4' 'x3^2 x4^2' 'x3 x4^3' 'x4^4']

x0, x1, x2, .. 등은 각각 첫번째, 두번째, 세번째 데이터이고
'x1^2'은  두번째 데이터의 제곱이고,
'x0^2 x1 x4' 는 첫번째 데이터의 제곱, 두번째 데이터, 5번째 데이터를 곱한겁니다.
간단히 말해 제곱이나 곱하기할 수 있는 경우의 수가 모두 나열되었다고 생각하시면 됩니다.

 

많아진 차수로 머신 러닝을!

 

이렇게 많아진 데이터로 머신러닝하면 결과가 좀 더 나아질까요?
나아지더라구요 :)

주의할 점은 이렇게 다항으로 데이터를 뿔린 다음에 스케일러를 적용해야지,
그 순서가 바뀌면 머신러닝이 안드로메다로 가버립니다 :)

이 후 스케일러 적용 단계가 이어집니다.

from sklearn.preprocessing import StandardScaler
스케일러 = StandardScaler()
스케일러.fit(훈련용데이터_가공)
훈련용데이터_가공 = 스케일러.transform(훈련용데이터_가공)
테스트데이터_가공 = 스케일러.transform(테스트데이터_가공)


이번에는 라쏘 모델을 적용해 보려고 하는데요.

기왕이면 릿지 모델과 비교해보기 위해 릿지 모델과 라쏘 모델을 동시에 훈련시켜 보았습니다.
그래도 되냐구요? 컴퓨터가 버텨주기만 한다면야 문제될게 없지요 :)

#=====================================
# 릿지모델
from sklearn.linear_model import Ridge
릿지모델 = Ridge(alpha=10)
릿지모델.fit(훈련용데이터_가공, 훈련용목표)

# 종류가 목표가 아닌 이상 정확도는 측정 불가
print("릿지 훈련용모델 정확도")
print(릿지모델.score(훈련용데이터_가공, 훈련용목표))
print("릿지 테스트모델 정확도")
print(릿지모델.score(테스트데이터_가공, 테스트목표))

훈련용목표예측_릿지 = 릿지모델.predict(훈련용데이터_가공)
테스트목표예측_릿지 = 릿지모델.predict(테스트데이터_가공)

#=====================================
# 라쏘모델
from sklearn.linear_model import Lasso
라쏘모델 = Lasso(alpha=10)
라쏘모델.fit(훈련용데이터_가공, 훈련용목표)

# 종류가 목표가 아닌 이상 정확도는 측정 불가
print("라쏘 훈련용모델 정확도")
print(라쏘모델.score(훈련용데이터_가공, 훈련용목표))
print("라쏘 테스트모델 정확도")
print(라쏘모델.score(테스트데이터_가공, 테스트목표))

훈련용목표예측_라쏘 = 라쏘모델.predict(훈련용데이터_가공)
테스트목표예측_라쏘 = 라쏘모델.predict(테스트데이터_가공)

엇 그런데 알파값을 보니 지난번에는 0.1이었는데, 이번에는 10 이군요?

지난 게시글 알파값 적용

릿지모델 = Ridge(alpha=알파값)


이번 게시글 알파값 적용

릿지모델 = Ridge(alpha=10)
   :
라쏘모델 = Lasso(alpha=10)

이는 항이 많을수록 더욱 데이터에 과적합이 될 수 있기 떄문입니다.

만일 이렇게 항이 많은데 알파값 0.1 정도를 주게 되면. 2개의 알고리즘 모두 이렇게 되버리더라구요.
(회색:원본, 녹색:릿지, 빨강:라쏘)
항이 많을수록 알파값을 더 높게 줘야 하는데, 본 소스에서 알아낸 최적의 값이 10입니다.

 

최종 소스

 

이제 하나의 그래프에 원본, 릿지, 라쏘 그래프를 함께 그릴일만 남았군요.
그래프쪽 소스는 별로 변동된 부분이 없어 ( 색상만 변동 )
추가 설명 없이 전체 소스로 매듭을 짓습니다.

<html> 
    <head>
      <title>다항회귀 + 라쏘 리그레션</title>
      <link rel="stylesheet" 
        href="https://pyscript.net/alpha/pyscript.css" /> 
      <script defer 
        src="https://pyscript.net/alpha/pyscript.js"></script> 
<py-env>
  - pandas
  - matplotlib
  - seaborn
  - scikit-learn
  - paths:
    - ./NANUMMYEONGJO.TTF
    - ./NANUMMYEONGJOBOLD.TTF
    - ./common.py
</py-env>
    </head>
  <body> 
    <link rel="stylesheet" href="pytable.css"/>
<py-script>
import pandas as pd
from pyodide.http import open_url
from common import *
import numpy as np

from datetime import datetime

# 경고 문구 제거
import warnings
warnings.filterwarnings( 'ignore' )

import gc

# 판다스에서 csv 를 데이터 프레임으로 읽어옴
매출데이터 = pd.read_csv(open_url(
  "http://dreamplan7.cafe24.com/pyscript/csv/avocado.csv"
))      

# 3개 필드만 추려서 데이터 프레임을 다시 만듬
매출데이터 = 매출데이터[[
  'Date', 
  'Total Volume',
  'AveragePrice'
]]   

# 영문 제목을 한글로 변경
매출데이터.columns = [
  '날짜', 
  '매출량',
  '평균가격'
]

주간매출_매출량=매출데이터.fillna(0) \
  .groupby('날짜', as_index=False)[['매출량']].sum() \
  .sort_values(by='날짜', ascending=True)
  
주간매출_평균가=매출데이터.fillna(0) \
  .groupby('날짜', as_index=False)[['평균가격']].mean() \
  .sort_values(by='날짜', ascending=True)

주간매출데이터=pd.merge(주간매출_매출량, 주간매출_평균가, on='날짜')

# 날짜(시간값) 추가
주간매출데이터.insert(1, '날짜(시간값)',
  '',
  True)
  
for i in 주간매출데이터['날짜'].index:
  주간매출데이터['날짜(시간값)'].loc[i]=time.mktime(
    datetime.strptime(
      주간매출데이터['날짜'].loc[i], 
      '%Y-%m-%d'
    ).timetuple()
  )

# 10000으로 나눈 매출량 필드 추가
주간매출데이터.insert(3, '매출량(만)', 
  주간매출데이터['매출량']/10000, 
  True)

# 훈련학습용으로 날짜를 연도, 월, 일로 나눈다
주간매출데이터.insert(4, '연도', '', True)
주간매출데이터.insert(5, '월', '', True)
주간매출데이터.insert(6, '일', '', True)
주간매출데이터.insert(7, '주', '', True)

for i in 주간매출데이터['날짜'].index:
  임시=str(주간매출데이터['날짜'].loc[i]).split('-')
  연도=int(임시[0])
  월=int(임시[1])
  일=int(임시[2])
  주간매출데이터['연도'].loc[i]=연도
  주간매출데이터['월'].loc[i]=월
  주간매출데이터['일'].loc[i]=일
  주간매출데이터['주'].loc[i]=str(
    datetime(연도, 월, 일).isocalendar()[1]
  )

createElementDiv(
  document, 
  Element, 
  'output2'
).write(주간매출데이터)

주간매출데이터훈련_넘파이 = 주간매출데이터[['날짜(시간값)', '연도', '월', '일', '평균가격']].to_numpy()
주간매출데이터목표_넘파이 = 주간매출데이터['매출량(만)'].to_numpy()
주간매출데이터날짜_넘파이 = 주간매출데이터['날짜'].to_numpy()

from sklearn.model_selection import train_test_split

훈련용데이터, 테스트데이터, 훈련용목표, 테스트목표 = \
  train_test_split(
    주간매출데이터훈련_넘파이, 
    주간매출데이터목표_넘파이,
    random_state=100,
    shuffle=False)


from sklearn.preprocessing import PolynomialFeatures
폴리 = PolynomialFeatures(degree=4, include_bias=False) # 절편 속성은 제거
폴리.fit(훈련용데이터) # 특성을 다항으로 자동으로 불림
#print(폴리.get_feature_names_out())
훈련용데이터_가공 = 폴리.transform(훈련용데이터) # 학습에 추가된 파라미터에 맞게 다항 변환
테스트데이터_가공 = 폴리.transform(테스트데이터) # 테스트 세트도 다항 변환, fit했던 훈련 poly 를 사용.

#print(훈련용데이터[0]);
#print(훈련용데이터_가공[0]);

#=====================================
from sklearn.preprocessing import StandardScaler
스케일러 = StandardScaler()
스케일러.fit(훈련용데이터_가공)
훈련용데이터_가공 = 스케일러.transform(훈련용데이터_가공)
테스트데이터_가공 = 스케일러.transform(테스트데이터_가공)

#=====================================
# 릿지모델
from sklearn.linear_model import Ridge
릿지모델 = Ridge(alpha=10)
릿지모델.fit(훈련용데이터_가공, 훈련용목표)

# 종류가 목표가 아닌 이상 정확도는 측정 불가
print("릿지 훈련용모델 정확도")
print(릿지모델.score(훈련용데이터_가공, 훈련용목표))
print("릿지 테스트모델 정확도")
print(릿지모델.score(테스트데이터_가공, 테스트목표))

훈련용목표예측_릿지 = 릿지모델.predict(훈련용데이터_가공)
테스트목표예측_릿지 = 릿지모델.predict(테스트데이터_가공)

#=====================================
# 라쏘모델
from sklearn.linear_model import Lasso
라쏘모델 = Lasso(alpha=10)
라쏘모델.fit(훈련용데이터_가공, 훈련용목표)

# 종류가 목표가 아닌 이상 정확도는 측정 불가
print("라쏘 훈련용모델 정확도")
print(라쏘모델.score(훈련용데이터_가공, 훈련용목표))
print("라쏘 테스트모델 정확도")
print(라쏘모델.score(테스트데이터_가공, 테스트목표))

훈련용목표예측_라쏘 = 라쏘모델.predict(훈련용데이터_가공)
테스트목표예측_라쏘 = 라쏘모델.predict(테스트데이터_가공)

#=====================================

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib as mat

# 기준 폰트 변경 : legend 의 한글을 적용하려면 필수
fm.fontManager.addfont('./NANUMMYEONGJO.TTF') #  폰트명 : NanumMyeongjo
mat.rc('font', family='NanumMyeongjo')

###################
# 폰트 목록 출력 ( 폰트 추가 후 정확한 이름을 확인하려면 필요
#font_list = [font.name for font in fm.fontManager.ttflist]
#for f in font_list:
#  print(f)      
###################        

# 개별 폰트 적용
NanumMyengjo = fm.FontProperties(
  fname='./NANUMMYEONGJO.TTF'
)
NanumMyengjoBold = fm.FontProperties(
  fname='./NANUMMYEONGJOBOLD.TTF'
)

# 그래프
fig = plt.figure(
  figsize=(15, 7)
)

plt.xticks(
  주간매출데이터훈련_넘파이[:, 0],
  주간매출데이터날짜_넘파이, 
  rotation=90, fontsize=8)

plt.title('주간 아보카도 매출량(릿지,라쏘)',  
  fontproperties=NanumMyengjoBold, 
  fontsize=32
);

line_alpha=0.5

# 원본
plt.plot(        
  훈련용데이터[:,0],
  훈련용목표,
  #marker='o',
  color='gray',
  label='원본',
  alpha=line_alpha
)
plt.plot(        
  테스트데이터[:, 0],
  테스트목표,
  #marker='o',
  color='gray',
  alpha=line_alpha
)

# 릿지
plt.plot(        
  훈련용데이터[:,0],
  훈련용목표예측_릿지,
  marker='d',
  color='blue',
  label='훈련패턴(릿지)',
  alpha=line_alpha
)
# 라쏘
plt.plot(        
  훈련용데이터[:,0],
  훈련용목표예측_라쏘,
  marker='d',
  color='red',
  label='훈련패턴(라쏘)',
  alpha=line_alpha
)

# 릿지 예측
plt.plot(        
  테스트데이터[:, 0],
  테스트목표예측_릿지,
  marker='*',
  color='green',
  label='예측패턴(릿지)',
  alpha=line_alpha
)

# 라쏘 예측
plt.plot(        
  테스트데이터[:, 0],
  테스트목표예측_라쏘,
  marker='*',
  color='red',
  label='예측패턴(라쏘)',
  alpha=line_alpha
)

plt.xlabel('날짜', fontsize=16)
plt.ylabel('매출량(단위:만)', fontsize=12)

plt.legend(
  shadow=True
)

ax = plt.gca()
# 축만 그리드
ax.xaxis.grid(True)

# 배경색, 마진 조정
ax.set_facecolor('#e8e7d2')
ax.margins(x=0.01, y=0.02)

# 주위 이상한 여백 없애기
fig.tight_layout() 
fig

</py-script> 
  </body> 
</html>

정확도는 지난번보다 약간 더 좋아졌습니다.
릿지보다 라쏘가 더 정확도가 높은데요. 뭐 이건 상황에 따라 다르다고 하더라구요.

릿지 훈련용모델 정확도
0.7248403810426859
릿지 테스트모델 정확도
0.7511139286301507
라쏘 훈련용모델 정확도
0.7256643900380024
라쏘 테스트모델 정확도
0.7615459788185178

그래프에서 어떤게 릿지고 어떤게 라쏘인지는 왼쪽에 표시되는 범례를 확인해 주세요 :)

본 예제의 실행결과는 크레이의 홈페이지에서도 확인하실 수 있습니다.
http://dreamplan7.cafe24.com/pyscript/py10-6.html

 

마무~리

 

오늘은 데이터의 차수를 4차 방정식까지 적용할 수 있게,
그것도 수동이 아닌 자동으로 적용하는 방법을 살펴보았습니다.
아울러 과적합 방지용 릿지 리그레션과 라쏘 리그레션을 동시에 머신러닝하고,
동시에 그래프에 표기하는 부분을 살펴보았는데요.

지금까지는 알파값을 알아내기 위해 계속 페이지를 새로 고침하고 새로 고침하는 방법을 써왔습니다만,
다음 게시글에서는 파이스크립트의 특장점을 살리는 방법을 살펴보겠습니다.
미리 만들어 놓았으니 크레이가 큰 소리를 치는 거겠지요 :)

 

아무쪼록 필요하신 분께 도움이 되셨을지요 :)
방문해주시는 모든 분들께 늘 감사드립니다.

유익하셨다면 공감  한방, 댓글은 굿잡!
감사합니다~


다음 게시글 : https://itadventure.tistory.com/558

 

파도(16) - 파이스크립트의 특좌앙~점으로 머신러닝!

🐳 '파도'는 크레이가 도전하고 있는 파이스크립트 도전기의 줄임말입니다. 지난 게시글에서 연재되는 글입니다. : https://itadventure.tistory.com/557 파도!(15) - 라쏘회귀와 4차방정식까지 🍿 '파도'는

itadventure.tistory.com