English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
preview
데이터 과학 및 머신 러닝(파트 06): 경사 하강법(Gradient Descent)

데이터 과학 및 머신 러닝(파트 06): 경사 하강법(Gradient Descent)

MetaTrader 5트레이딩 | 10 2월 2023, 09:46
870 0
Omega J Msigwa
Omega J Msigwa

성급한 최적화는 프로그래밍에서 모든 악의 근원입니다.

-도널드 크누스 

소개

Wikipedia에 따르면 경사 하강법(가장 가파른 강하라고도 함)은 미분 가능 함수의 로컬 최소값을 찾기 위한 1차 반복 최적화 알고리즘입니다. 아이디어는 현재 지점에서 함수의 기울기(또는 대략적인 기울기)의 반대 방향으로 반복되는 단계를 수행하는 것입니다. 이것이 가장 가파른 내리막의 방향이기 때문입니다. 반대로 기울기 방향으로 이동하면 해당 함수의 로컬 최대값이 됩니다; 이 절차는 경사 상승(gradient ascent)으로 알려져 있습니다.


기본적으로 경사 하강법은 함수의 최소값을 찾는 데 사용되는 최적화 알고리즘입니다:

경사하강법 기사 gif

경사 하강법은 데이터 세트에 대해 가장 적합한 모델의 매개변수를 찾는 데 도움이 되므로 머신 러닝에서 매우 중요한 알고리즘입니다. 비용 함수(Cost Function)라는 용어를 먼저 설명하겠습니다.


비용 함수

어떤 사람들은 이것을 손실 함수(loss function)라고도 부릅니다. 이것은 우리 모델이 x와 y 값 사이의 관계를 예측하는 데 얼마나 좋은지 또는 나쁜지를 계산하는 척도입니다.

모델이 예측하는 방법을 결정하는 데 사용할 수 있는 메트릭은 많이 있지만 비용 함수는 전체 데이터 세트에서 평균 손실을 찾습니다. 비용 함수가 클수록 우리의 모델이 데이터 세트에서 관계를 찾는 것에 안 좋은 영향을 미칩니다.

기울기 하강법은 비용 함수가 가장 낮은 모델이 최고의 모델이기 때문에 비용 함수를 최소화하는 것을 목표로 합니다. 방금 설명한 내용을 이해하기 위해 다음과 같은 예제를 살펴보겠습니다.

비용 함수가 방정식이라고 가정합니다. 

파이썬으로 이 함수의 그래프를 그리면 다음과 같이 보일 것입니다:

플롯

비용 함수에 대해 수행해야 하는 첫 번째 단계는 체인 규칙을 사용하여 비용 함수를 차별화하는 것입니다.

방정식y= (x+5)^2는 합성 함수입니다(다른 함수 안에 하나의 함수가 있음). 외부 함수는 (x+5)^2이고 내부 함수는(x+5)입니다. 이를 구별하기 위해 체인 규칙을 적용해 보겠습니다. 이미지를 참조하십시오:

연쇄 법칙

이해하기 어려우시면 동영상 링크를 따라가 보세요. 동영상은 손으로 직접 계산하는 것입니다. 우리가 지금 얻은 이 함수는 기울기입니다. 방정식의 기울기를 찾는 과정은 모든 과정에서 가장 중요한 단계이며 함수를 미분하는 목적은 함수의 기울기를 얻기 위한 것이라고 예전에 수학 선생님들이 말해줬던거 같습니다.

이것이 첫 번째이자 가장 중요한 단계이며 아래는 두 번째 단계입니다.

02단계:

이제 기울기의 음의 방향으로 이동해 봅니다. 여기서 질문이 제기됩니다. 얼마나 이동해야 합니까? 이곳이 학습율이 작동하는 곳입니다.


학습율

정의에 따라 이것은 최소 손실 함수를 향해 이동하는 동안의 각 반복 단계의 크기입니다. 사람이 산을 내려가는 경우와 같은 예를 들어보면 걸음은 학습율이고 걸음이 작을수록 더 오래 걸립니다. 걸음을 통해 산의 바닥에 도달하거나 그 반대의 경우도 마찬가지입니다.

알고리즘 학습율을 0.0001과 같이 너무 작지 않은 작은 값으로 유지하면 알고리즘이 최소값에 도달하는 데 시간이 더 오래 걸릴 수 있으므로 프로그램 실행 시간이 늘어납니다. 반대로 학습율에 큰 숫자를 사용하면 알고리즘이 최소값을 건너뛰게 되어 결국에는 목표로 하는 최소값을 놓칠 수 있습니다.

기본 학습율은 0.01입니다.

반복을 수행하여 알고리즘이 어떻게 작동하는지 살펴보겠습니다.

첫 번째 반복: 임의의 지점을 알고리즘의 시작점으로 선택합니다. 이제 x의 값을 업데이트하기 위해 x의 첫 번째 값으로 0을 선택했습니다. 이것이 공식입니다.

새로운 값 경사하강법

 반복할 때마다 함수의 최소값을 향해 하강하므로 경사 하강법이라는 이름도 마찬가지입니다. 이제 이해 되나요?

말이 돼 이제 말이 돼

이것이 어떻게 작동하는지 자세히 살펴보겠습니다. 무슨 일이 일어나고 있는지 확실하게 이해할 수 있도록 2회 반복에서 수동으로 값을 계산해 보겠습니다.

1차 반복:

공식: x1 = x0 - 학습율 * ( 2*(x+5) )

x1 = 0 - 0.01 * 0.01 * 2*(0+5)

x1 = -0.01 * 10

x1 = -0.1(최종) 

이제 마지막으로 새로운 값을 이전 값에 할당하여 값을 업데이트하고 함수의 최소값에 도달할 때까지 절차를 반복합니다.

x0 = x1

두 번째 반복:

x1 = -0.1 - 0.01 * 2*(-0.1+5)

x1 = -0.198

그러면: x0 = x1

이 절차를 여러 번 반복하면 10회 첫 번째 반복에 대한 출력은 다음과 같습니다.

RS      0       17:15:16.793    gradient-descent test (EURUSD,M1)       Gradient Descent CostFunction CUSTOM
QQ      0       17:15:16.793    gradient-descent test (EURUSD,M1)       1 x0 = 0.0000000000 x1 = -0.1000000000 CostFunction = 10.0000000000
ES      0       17:15:16.793    gradient-descent test (EURUSD,M1)       2 x0 = -0.1000000000 x1 = -0.1980000000 CostFunction = 9.8000000000
PR      0       17:15:16.793    gradient-descent test (EURUSD,M1)       3 x0 = -0.1980000000 x1 = -0.2940400000 CostFunction = 9.6040000000
LE      0       17:15:16.793    gradient-descent test (EURUSD,M1)       4 x0 = -0.2940400000 x1 = -0.3881592000 CostFunction = 9.4119200000
JD      0       17:15:16.793    gradient-descent test (EURUSD,M1)       5 x0 = -0.3881592000 x1 = -0.4803960160 CostFunction = 9.2236816000
IG      0       17:15:16.793    gradient-descent test (EURUSD,M1)       6 x0 = -0.4803960160 x1 = -0.5707880957 CostFunction = 9.0392079680
IG      0       17:15:16.793    gradient-descent test (EURUSD,M1)       7 x0 = -0.5707880957 x1 = -0.6593723338 CostFunction = 8.8584238086
JF      0       17:15:16.793    gradient-descent test (EURUSD,M1)       8 x0 = -0.6593723338 x1 = -0.7461848871 CostFunction = 8.6812553325
NI      0       17:15:16.793    gradient-descent test (EURUSD,M1)       9 x0 = -0.7461848871 x1 = -0.8312611893 CostFunction = 8.5076302258
CK      0       17:15:16.793    gradient-descent test (EURUSD,M1)       10 x0 = -0.8312611893 x1 = -0.9146359656 CostFunction = 8.3374776213

함수의 최소값에 매우 근접할 때 알고리즘의 다른 10개의 값도 살펴보겠습니다.

GK      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1052 x0 = -4.9999999970 x1 = -4.9999999971 CostFunction = 0.0000000060
IH      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1053 x0 = -4.9999999971 x1 = -4.9999999971 CostFunction = 0.0000000059
NH      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1054 x0 = -4.9999999971 x1 = -4.9999999972 CostFunction = 0.0000000058
QI      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1055 x0 = -4.9999999972 x1 = -4.9999999972 CostFunction = 0.0000000057
II      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1056 x0 = -4.9999999972 x1 = -4.9999999973 CostFunction = 0.0000000055
RN      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1057 x0 = -4.9999999973 x1 = -4.9999999973 CostFunction = 0.0000000054
KN      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1058 x0 = -4.9999999973 x1 = -4.9999999974 CostFunction = 0.0000000053
JO      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1059 x0 = -4.9999999974 x1 = -4.9999999974 CostFunction = 0.0000000052
JO      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1060 x0 = -4.9999999974 x1 = -4.9999999975 CostFunction = 0.0000000051
QL      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1061 x0 = -4.9999999975 x1 = -4.9999999975 CostFunction = 0.0000000050
QL      0       17:15:16.800    gradient-descent test (EURUSD,M1)       1062 x0 = -4.9999999975 x1 = -4.9999999976 CostFunction = 0.0000000049
HP      0       17:15:16.800    gradient-descent test (EURUSD,M1)       Local miminum found =-4.999999997546217

1062(천육십이) 반복 후 알고리즘은 이 함수의 로컬 최소값에 도달할 수 있었습니다.

이 알고리즘에서 주목할 점

비용 함수의 값을 살펴보면 처음에는 값이 크게 변경되었다는 것을 볼 수 있지만 비용 함수의 마지막 값에서는 눈에 띄는 변화가 아주 미미합니다.

경사 하강법은 함수의 최소값 근처가 아닐 때 더 큰 단계를 거치지만 함수의 최소값에 가까울 때는 작은 단계를 밟습니다. 산에서 맨 아래쪽의 근처에 있을 때도 마찬가지입니다. 이제 여러분은 경사 하강법이 매우 똑똑하다는 것을 알 수 있을 것입니다!

이렇게 로컬 최소값은 

HP      0       17:15:16.800    gradient-descent test (EURUSD,M1)       Local miminum found =-4.999999997546217

이 함수의 최소값이-5.0이기 때문에 정확한 값입니다!

여기서 질문

기울기는 언제 중지해야 하는지를 어떻게 알 수 있습니까? 우리는 알고리즘이 무한대 또는 적어도 컴퓨터의 계산 능력이 끝날 때까지 계속 반복하도록 할 수 있습니다.

비용 함수가 0일 때 경사 하강법이 작업을 완료했음을 알 수 있습니다.

이제 MQL5에서 이 전체의 작업을 코딩해 보겠습니다:

       while (true)
        {
           iterations++;
           
           x1 = x0 - m_learning_rate * CustomCostFunction(x0);
           
           printf("%d x0 = %.10f x1 = %.10f CostFunction = %.10f",iterations,x0,x1,CustomCostFunction(x0)); 
           
           if (NormalizeDouble(CustomCostFunction(x0),8) == 0) { Print("Local minimum found =",x0);  break;  }
              
           x0 = x1;
        }   

위의 코드 블록은 우리가 원하는 결과였지만CGradientDescent클래스에만 있는 것은 아닙니다. CustomCostFunction함수는 우리의 미분 방정식이 유지되고 계산되는 곳입니다.

double CGradientDescent::CustomCostFunction(double x)
 {
   return(2 * ( x + 5 ));
 }


목적이 무엇일까요?

이 주제를 다룬 기사 시리즈에서 이전의 라이브러리에서 생성한 기본 선형 모델을 사용할 수 있는데 굳이 이러한 계산을 한 목적이 무엇인지 여러분들이 궁금할지도 모릅니다. Newsflash 기본값을 사용하여 만든 모델이 언제나 최상의 모델은 아니므로 오류가 거의 없는 모델(최상의 모델)에 대한 최상의 매개 변수를 컴퓨터가 학습하도록 해야 합니다.

이제 우리는 인공 신경망 구축에 있어 역전파 및 이외 기술에서 신경망이 학습(패턴을 학습)하는 방법을 이해하는 데에 더 가까워지고 있습니다. 경사 하강법은 이 모든 것을 가능하게 만든 가장 인기 있는 알고리즘입니다. 경사 하강법에 대한 확실한 이해 없이는 상황이 복잡해지면서 프로세스를 전혀 이해하지 못할 수도 있습니다.


회귀 모델에 대한 경사 하강법

Salary Dataset을 사용하여 경사 하강법을 사용하여 최상의 모델을 만들어 보겠습니다.

데이터세트 개요

Python의 데이터 시각화:

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


data  = pd.read_csv(r"C:\Users\Omega Joctan\AppData\Roaming\MetaQuotes\Terminal\892B47EBC091D6EF95E3961284A76097\MQL5\Files\Salary_Data.csv")

print(data.head(10))

x = data["YearsExperience"]
y = data["Salary"]

plt.figure(figsize=(16,9))
plt.title("Experience vs Salary")
plt.scatter(x,y,c="green")
plt.xlabel(xlabel="Years of Experience")
plt.ylabel(ylabel="Salary")
plt.show()

이것은 우리의 그래프가 될 것입니다:

경력년수 vs 연봉년수 vs 급여

데이터 세트를 보면 이 데이터 세트가 회귀 문제를 위한 것임을 알 수 있지만 예측하거나 달성하려는 것이 무엇이든 우리에게는 도움이 되는 백만 개의 모델이 있을 수 있습니다.

다중 모드

개인의 경험과 급여를 예측하는 데 사용할 수 있는 최고의 모델은 무엇일까요? 그것이 우리가 알아내려고 하는 것입니다. 먼저 회귀 모델의 비용 함수를 도출해 보겠습니다.

이론

선형 회귀로 돌아가 보겠습니다.

우리는 모든 선형 모델에는 오류가 있다는 사실을 알고 있습니다. 우리는 또한 이 그래프에서 백만 개의 선을 만들 수 있고 그중 가장 잘 맞는 선은 항상 오류가 가장 적은 선이라는 것을 알고 있습니다.

비용 함수는 실제 값과 예측 값 사이의 오차를 나타내며 비용 함수의 공식을 다음과 같이 작성할 수 있습니다:

비용 = 실제 Y - 예측 Y

오류의 크기를 보고 있으므로 제곱을 하면 이제 공식은 다음과 같습니다.

그러나 우리는 전체 데이터 세트에서 오류를 찾고 있습니다. 그러므로 우리는 합계를 만들어야 합니다. 

마지막으로 오류의 합계를 데이터 세트의 항목 수인m으로 나눕니다:

선형 회귀 비용 함수

다음은 수작업으로 수행되는 수학 절차 전체를 보여주는 비디오입니다.

이제 비용 함수가 있으므로 경사 하강법을 코딩하고 두 가지 모두에 가장 적합한 매개변수를 찾아보겠습니다. Bo 로 표시되는 X(Slope)의 계수와B1 로 표시되는 Y 절편 

   
   double cost_B0=0, cost_B1=0;
   
   if (costFunction == MSE)
    {
      int iterations=0;
      for (int i=0; i<m_iterations; i++, iterations++)
        {
        
           cost_B0 = Mse(b0,b1,Intercept);
           cost_B1 = Mse(b0,b1,Slope);
           
           b0 = b0 - m_learning_rate * cost_B0; 
           b1 = b1 - m_learning_rate * cost_B1;
           
           printf("%d b0 = %.8f cost_B0 = %.8f B1 = %.8f cost_B1 = %.8f",iterations,b0,cost_B0,b1,cost_B1);
           
           DBL_MAX_MIN(b0); DBL_MAX_MIN(cost_B0); DBL_MAX_MIN(cost_B1);
           
           if (NormalizeDouble(cost_B0,8) == 0 && NormalizeDouble(cost_B1,8) == 0)  break; 
           
        }
      printf("%d Iterations Local Minima are\nB0(Intercept) = %.5f  ||  B1(Coefficient) = %.5f",iterations,b0,b1);    
    }

경사 하강법 코드에서 몇 가지 사항을 확인해 보시기 바랍니다.

  • 프로세스는 이전에 수행한 프로세스와 동일하지만 이번에는 Bo 및 B1 값을 한 번에 두 번 찾고 업데이트합니다.
  • 제한된 수의 반복이 있습니다. 누군가 무한 루프를 만드는 가장 좋은 방법은 while 루프를 사용하는 것이라고 말했습니다. 이번에는 while 루프를 사용하지 않고 대신 최상의 모델에 대한 계수를 찾기 위해 사용하는 알고리즘이 작동하는 횟수를 제한하려고 합니다.
  • DBL_MAX_MIN 은 컴퓨터의 수학적 한계에 도달했는지 확인하고 알려주는 디버깅 목적의 함수입니다.

이것은 알고리즘 작업의 출력입니다. 학습율 = 0.01 반복 = 10000

PD      0       17:29:17.999    gradient-descent test (EURUSD,M1)       [20]  91738.0000  98273.0000 101302.0000 113812.0000 109431.0000 105582.0000 116969.0000 112635.0000 122391.0000 121872.0000
JS      0       17:29:17.999    gradient-descent test (EURUSD,M1)       Gradient Descent CostFunction MSE
RF      0       17:29:17.999    gradient-descent test (EURUSD,M1)       0 b0 = 1520.06000000 cost_B0 = -152006.00000000 B1 = 9547.97400000 cost_B1 = -954797.40000000
OP      0       17:29:17.999    gradient-descent test (EURUSD,M1)       1 b0 = 1995.08742960 cost_B0 = -47502.74296000 B1 = 12056.69235267 cost_B1 = -250871.83526667
LP      0       17:29:17.999    gradient-descent test (EURUSD,M1)       2 b0 = 2194.02117366 cost_B0 = -19893.37440646 B1 = 12707.81767044 cost_B1 = -65112.53177770
QN      0       17:29:17.999    gradient-descent test (EURUSD,M1)       3 b0 = 2319.78332575 cost_B0 = -12576.21520809 B1 = 12868.77569178 cost_B1 = -16095.80213357
LO      0       17:29:17.999    gradient-descent test (EURUSD,M1)       4 b0 = 2425.92576238 cost_B0 = -10614.24366387 B1 = 12900.42596039 cost_B1 = -3165.02686058
GH      0       17:29:17.999    gradient-descent test (EURUSD,M1)       5 b0 = 2526.58198175 cost_B0 = -10065.62193621 B1 = 12897.99808257 cost_B1 = 242.78778134
CJ      0       17:29:17.999    gradient-descent test (EURUSD,M1)       6 b0 = 2625.48307920 cost_B0 = -9890.10974571 B1 = 12886.62268517 cost_B1 = 1137.53974060
DD      0       17:29:17.999    gradient-descent test (EURUSD,M1)       7 b0 = 2723.61498028 cost_B0 = -9813.19010723 B1 = 12872.93147573 cost_B1 = 1369.12094310
HF      0       17:29:17.999    gradient-descent test (EURUSD,M1)       8 b0 = 2821.23916252 cost_B0 = -9762.41822398 B1 = 12858.67435081 cost_B1 = 1425.71249248

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Last Iterations >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EI      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6672 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
NG      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6673 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
GD      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6674 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
PR      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6675 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
IS      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6676 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
RQ      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6677 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
KN      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6678 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
DL      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6679 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
RM      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6680 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
IK      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6681 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
PH      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6682 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
GF      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6683 b0 = 25792.20019866 cost_B0 = -0.00000001 B1 = 9449.96232146 cost_B1 = 0.00000000
MG      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6684 b0 = 25792.20019866 cost_B0 = -0.00000000 B1 = 9449.96232146 cost_B1 = 0.00000000
LE      0       17:29:48.247    gradient-descent test (EURUSD,M1)       6684 Iterations Local Minima are
OJ      0       17:29:48.247    gradient-descent test (EURUSD,M1)       B0(Intercept) = 25792.20020  ||  B1(Coefficient) = 9449.96232

matplotlib 를 사용하여 그래프를 그리면 

최고의 모델 경사하강법

맞습니다, 경사 하강법은 우리가 시도한 10000개의 모델 중에서 최고의 모델을 성공적으로 얻을 수 있었습니다. 훌륭하지만 우리 모델이 이상하게 작동하거나 원하지 않는 결과를 얻게 만들 수도 있는 중요한 단계가 하나 있습니다.


선형 회귀 입력 변수 데이터 정규화

우리는 서로 다른 데이터 세트에 대해 서로 다른 반복 후에 최고의 모델을 찾을 수 있다는 것을 알고 있습니다. 어떤 것은 최고의 모델에 도달하는 데 100회의 반복이 필요할 수 있고 일부는 비용 함수가 0이 되는 데 10000 또는 최대 백만번의 반복이 걸릴 수 있습니다. 학습율이 잘못된 값으로 인해 로컬 최소값을 놓치게 될 수도 있으며 해당 목표를 놓치면 결국 컴퓨터의 수학적 한계에 도달하게 됩니다. 이러한 케이스를 살펴보겠습니다.

학습율 = 0.1 반복 1000


시스템에서 허용하는 최대 double 값에 도달했습니다. 다음은 로그입니다.

GM      0       17:28:14.819    gradient-descent test (EURUSD,M1)       Gradient Descent CostFunction MSE
OP      0       17:28:14.819    gradient-descent test (EURUSD,M1)       0 b0 = 15200.60000000 cost_B0 = -152006.00000000 B1 = 95479.74000000 cost_B1 = -954797.40000000
GR      0       17:28:14.819    gradient-descent test (EURUSD,M1)       1 b0 = -74102.05704000 cost_B0 = 893026.57040000 B1 = -512966.08473333 cost_B1 = 6084458.24733333
NM      0       17:28:14.819    gradient-descent test (EURUSD,M1)       2 b0 = 501030.91374462 cost_B0 = -5751329.70784622 B1 = 3356325.13824362 cost_B1 = -38692912.22976952
LH      0       17:28:14.819    gradient-descent test (EURUSD,M1)       3 b0 = -3150629.51591119 cost_B0 = 36516604.29655810 B1 = -21257352.71857720 cost_B1 = 246136778.56820822
KD      0       17:28:14.819    gradient-descent test (EURUSD,M1)       4 b0 = 20084177.14287909 cost_B0 = -232348066.58790281 B1 = 135309993.40314889 cost_B1 = -1565673461.21726084
OQ      0       17:28:14.819    gradient-descent test (EURUSD,M1)       5 b0 = -127706877.34210962 cost_B0 = 1477910544.84988713 B1 = -860620298.24803317 cost_B1 = 9959302916.51181984
FM      0       17:28:14.819    gradient-descent test (EURUSD,M1)       6 b0 = 812402202.33122230 cost_B0 = -9401090796.73331833 B1 = 5474519904.86084747 cost_B1 = -63351402031.08880615
JJ      0       17:28:14.819    gradient-descent test (EURUSD,M1)       7 b0 = -5167652856.43381691 cost_B0 = 59800550587.65039062 B1 = -34823489070.42410278 cost_B1 = 402980089752.84948730
MP      0       17:28:14.819    gradient-descent test (EURUSD,M1)       8 b0 = 32871653967.62362671 cost_B0 = -380393068240.57440186 B1 = 221513298448.70788574 cost_B1 = -2563367875191.31982422
MM      0       17:28:14.819    gradient-descent test (EURUSD,M1)       9 b0 = -209097460110.12799072 cost_B0 = 2419691140777.51611328 B1 = -1409052343513.33935547 cost_B1 = 16305656419620.47265625
HD      0       17:28:14.819    gradient-descent test (EURUSD,M1)       10 b0 = 1330075004152.67309570 cost_B0 = -15391724642628.00976562 B1 = 8963022367351.18359375 cost_B1 = -103720747108645.23437500
DP      0       17:28:14.819    gradient-descent test (EURUSD,M1)       11 b0 = -8460645083849.12207031 cost_B0 = 97907200880017.93750000 B1 = -57014041694401.67187500 cost_B1 = 659770640617528.50000000

이는 학습율이 잘못되면 최상의 모델을 찾을 가능성이 희박하거나 가능성이 없을 수도 있으며 방금 경고를 본 것처럼 컴퓨터의 수학적 한계에 도달할 가능성이 높다는 것을 의미합니다.

하지만 이 데이터 세트에서 학습율로0.01을 시도하면 학습 프로세스가 훨씬 느려지더라도 문제가 발생하지 않지만 만약 이 dataset에 이 학습 속도를 사용하면 수학적 한계에 도달하게 될 것입니다. 이제 우리는 모든 데이터 세트에 학습율이 있다는 것을 알고 있지만 때로는 여러 변수가 있는 데이터 세트와 복잡한 문제가 있기 때문에 학습율을 최적화할 기회가 없을 수도 있습니다. 이는 전체 프로세스를 수행하는 비효율적인 방법입니다.

이 모든 것에 대한 해결책은 전체 데이터 세트를 정규화 하여 동일한 척도에 있게 하는 것입니다. 이렇게 하면 동일한 축에 값을 그릴 때 가독성이 향상 되고 정규화된 값이 일반적으로0부터 1까지의 범위에 있기 때문에훈련 시간이 향상됩니다. 학습율0.01과 같이 학습율 매개변수가 하나만 있으면 모든 데이터 세트에 사용할 수 있기 때문에 더 이상 학습율에 대해 걱정할 필요가 없습니다. 정규화에 대해 자세히 알고 싶으시다면 여기를 읽어보세요.

마지막으로 중요한 것은

우리는 급여 데이터 값이 평균39,343에서 121,782 인 반면 경력 년수는 1.1에서 10.5까지라는 것을 알고 있습니다. 이러한 방식으로 데이터를 유지하면 급여 값이 엄청나게 되고 모델은 급여가 더 중요하다고 여기게 될 수 있습니다. 그렇게 되면 급여가 경험에 비해 더 큰 영향을 미치게 됩니다. 다른 변수와 동일한 영향을 미치게 하려면 독립 변수가 필요합니다. 이제 값을 정규화 하는 것이 얼마나 중요한지 알 수 있을 것입니다.


(정규화) 최소-최대 스칼라

이 접근 방식에서는 데이터를0과 1범위 내로 정규화 합니다. 공식은 아래와 같습니다:

정규화 최소-최대-스칼라

이 공식을 MQL5의 코드로 변환하면 다음과 같습니다:

void CGradientDescent::MinMaxScaler(double &Array[])
 {
   double mean = Mean(Array);
   double max,min;
   double Norm[];
   
   ArrayResize(Norm,ArraySize(Array));
   
   max = Array[ArrayMaximum(Array)];   min = Array[ArrayMinimum(Array)];
   
    for (int i=0; i<ArraySize(Array); i++)
         Norm[i] = (Array[i] - min) / (max - min); 
   
   printf("Scaled data Mean = %.5f Std = %.5f",Mean(Norm),std(Norm));
   
   ArrayFree(Array);
   ArrayCopy(Array,Norm);
 }
 

std()함수는 데이터가 정규화 된 후 표준 편차를 알려주기 위한 것입니다. 코드는 다음과 같습니다:

double CGradientDescent::std(double &data[])
 {
   double mean =  Mean(data);
   double sum = 0;
   
    for (int i=0; i<ArraySize(data); i++)
       sum += MathPow(data[i] - mean,2);
    
    return(MathSqrt(sum/ArraySize(data)));  
 }

이제 이 모든 것을 호출하고 출력을 인쇄하여 어떻게 되는지 살펴보겠습니다:

void OnStart()
  {
//---
      string filename = "Salary_Data.csv";

      double XMatrix[];
      double YMatrix[];
      
      
      grad = new CGradientDescent(1, 0.01,1000);
      
      grad.ReadCsvCol(filename,1,XMatrix);
      grad.ReadCsvCol(filename,2,YMatrix);
       
      grad.MinMaxScaler(XMatrix);
      grad.MinMaxScaler(YMatrix);
      
      ArrayPrint("Normalized X",XMatrix);
      ArrayPrint("Normalized Y",YMatrix);
      
      
      grad.GradientDescentFunction(XMatrix,YMatrix,MSE);
      
      delete (grad);
  }

출력:

OK      0       18:50:53.387    gradient-descent test (EURUSD,M1)       Scaled data Mean = 0.44823 Std = 0.29683
MG      0       18:50:53.387    gradient-descent test (EURUSD,M1)       Scaled data Mean = 0.45207 Std = 0.31838
MP      0       18:50:53.387    gradient-descent test (EURUSD,M1)       Normalized X
JG      0       18:50:53.387    gradient-descent test (EURUSD,M1)       [ 0] 0.0000 0.0213 0.0426 0.0957 0.1170 0.1915 0.2021 0.2234 0.2234 0.2766 0.2979 0.3085 0.3085 0.3191 0.3617
ER      0       18:50:53.387    gradient-descent test (EURUSD,M1)       [15] 0.4043 0.4255 0.4468 0.5106 0.5213 0.6064 0.6383 0.7234 0.7553 0.8085 0.8404 0.8936 0.9043 0.9787 1.0000
NQ      0       18:50:53.387    gradient-descent test (EURUSD,M1)       Normalized Y
IF      0       18:50:53.387    gradient-descent test (EURUSD,M1)       [ 0] 0.0190 0.1001 0.0000 0.0684 0.0255 0.2234 0.2648 0.1974 0.3155 0.2298 0.3011 0.2134 0.2271 0.2286 0.2762
IS      0       18:50:53.387    gradient-descent test (EURUSD,M1)       [15] 0.3568 0.3343 0.5358 0.5154 0.6639 0.6379 0.7151 0.7509 0.8987 0.8469 0.8015 0.9360 0.8848 1.0000 0.9939

이제 그래프는 다음과 같이 표시됩니다:

정상화 가격 그래프 정상화

로지스틱 회귀를 위한 경사 하강법

경사 하강법의 리니어 측면을 살펴보았으므로 이제 로지스틱 측면을 살펴보겠습니다.

여기서 우리는 선형 회귀 부분에서 수행한 것과 동일한 프로세스를 수행합니다. 로지스틱 회귀가 선형 모델의 프로세스보다 더 복잡하다는 사실 이외 관련된 프로세스가 완전히 동일합니다. 먼저 비용 함수를 살펴보겠습니다.

로지스틱 회귀 모델의 비용 함수는 아래 주어진 Binary Cross Entropy AKA Log Loss입니다. 우리는 이미 로지스틱 회귀와 관련한 시리즈의 두 번째 기사에서 샆펴본 적이 있습니다.

이진 교차 엔트로피 또는 로그 손실

이제 어려운 부분을 먼저 해봅시다. 이 함수를 미분하여 기울기를 얻습니다.

미분 계수를 찾은 후 

의 미분비용 함수 의 미분

Binary Cross Entropy를 나타내는 BCE 함수 내에서 수식을 MQL5 코드로 변환해 보겠습니다.

double CGradientDescent::Bce(double Bo,double B1,Beta wrt)
 {
   double sum_sqr=0;
   double m = ArraySize(Y);
   double x[];
   
   MatrixColumn(m_XMatrix,x,2);
   
    if (wrt == Slope)
      for (int i=0; i<ArraySize(Y); i++)
        { 
          double Yp = Sigmoid(Bo+B1*x[i]);
          
          sum_sqr += (Y[i] - Yp) * x[i];
        }
        
    if (wrt == Intercept)
      for (int i=0; i<ArraySize(Y); i++)
         {
            double Yp = Sigmoid(Bo+B1*x[i]);
            sum_sqr += (Y[i] - Yp);
         } 
    return((-1/m)*sum_sqr);
 }

분류 모델을 다루기 때문에 선택한 데이터 세트는 로지스틱 회귀에서 사용한 Titanic 데이터 세트입니다. 우리의 독립 변수는Pclass(Passenger class)이고 종속 변수는 Survived입니다.

클래스 대 서바이벌 타이타닉 데이터 세트

분류된 산점도

생존 vs 클래스 산점도

이제 경사 하강법 클래스를 호출할 것이지만 이번에는BCE(Binary Cross Entropy)를 비용 함수로 사용합니다.

      filename = "titanic.csv";
      
      ZeroMemory(XMatrix);
      ZeroMemory(YMatrix);
      
      grad.ReadCsvCol(filename,3,XMatrix);
      grad.ReadCsvCol(filename,2,YMatrix);
      
      grad.GradientDescentFunction(XMatrix,YMatrix,BCE);
      
      delete (grad);
      

결과를 봅시다:

CP      0       07:19:08.906    gradient-descent test (EURUSD,M1)       Gradient Descent CostFunction BCE
KD      0       07:19:08.906    gradient-descent test (EURUSD,M1)       0 b0 = -0.01161616 cost_B0 = 0.11616162 B1 = -0.04057239 cost_B1 = 0.40572391
FD      0       07:19:08.906    gradient-descent test (EURUSD,M1)       1 b0 = -0.02060337 cost_B0 = 0.08987211 B1 = -0.07436893 cost_B1 = 0.33796541
KE      0       07:19:08.906    gradient-descent test (EURUSD,M1)       2 b0 = -0.02743120 cost_B0 = 0.06827832 B1 = -0.10259883 cost_B1 = 0.28229898
QE      0       07:19:08.906    gradient-descent test (EURUSD,M1)       3 b0 = -0.03248925 cost_B0 = 0.05058047 B1 = -0.12626640 cost_B1 = 0.23667566
EE      0       07:19:08.907    gradient-descent test (EURUSD,M1)       4 b0 = -0.03609603 cost_B0 = 0.03606775 B1 = -0.14619252 cost_B1 = 0.19926123
CF      0       07:19:08.907    gradient-descent test (EURUSD,M1)       5 b0 = -0.03851035 cost_B0 = 0.02414322 B1 = -0.16304363 cost_B1 = 0.16851108
MF      0       07:19:08.907    gradient-descent test (EURUSD,M1)       6 b0 = -0.03994229 cost_B0 = 0.01431946 B1 = -0.17735996 cost_B1 = 0.14316329
JG      0       07:19:08.907    gradient-descent test (EURUSD,M1)       7 b0 = -0.04056266 cost_B0 = 0.00620364 B1 = -0.18958010 cost_B1 = 0.12220146
HE      0       07:19:08.907    gradient-descent test (EURUSD,M1)       8 b0 = -0.04051073 cost_B0 = -0.00051932 B1 = -0.20006123 cost_B1 = 0.10481129
ME      0       07:19:08.907    gradient-descent test (EURUSD,M1)       9 b0 = -0.03990051 cost_B0 = -0.00610216 B1 = -0.20909530 cost_B1 = 0.09034065
JQ      0       07:19:08.907    gradient-descent test (EURUSD,M1)       10 b0 = -0.03882570 cost_B0 = -0.01074812 B1 = -0.21692190 cost_B1 = 0.07826600
        <<<<<<  Last  10 iterations >>>>>>

FN      0       07:19:09.725    gradient-descent test (EURUSD,M1)       6935 b0 = 1.44678930 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
PN      0       07:19:09.725    gradient-descent test (EURUSD,M1)       6936 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
NM      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6937 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
KL      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6938 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
PK      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6939 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
RK      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6940 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
MJ      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6941 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
HI      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6942 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
CH      0       07:19:09.726    gradient-descent test (EURUSD,M1)       6943 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
MH      0       07:19:09.727    gradient-descent test (EURUSD,M1)       6944 b0 = 1.44678931 cost_B0 = -0.00000001 B1 = -0.85010666 cost_B1 = 0.00000000
QG      0       07:19:09.727    gradient-descent test (EURUSD,M1)       6945 b0 = 1.44678931 cost_B0 = -0.00000000 B1 = -0.85010666 cost_B1 = 0.00000000
NG      0       07:19:09.727    gradient-descent test (EURUSD,M1)       6945 Iterations Local Minima are
MJ      0       07:19:09.727    gradient-descent test (EURUSD,M1)       B0(Intercept) = 1.44679  ||  B1(Coefficient) = -0.85011

선형 회귀에서는 분류된 데이터를 정규화 하거나 확장하지만 로지스틱 회귀에서는 그렇지 않습니다.

여기 가장 중요한 두 가지 머신 러닝 모델에 대한 경사 하강법이 있습니다. 이해하기 쉽고 유용한 Python 코드가 되었으면 좋겠습니다. 데이터 세트는 이 GitHub에 연결되어 있습니다. Gradient-Descent-MQL5 저장소 .


결론

우리는 하나의 독립 변수와 하나의 종속 변수에 대한 경사 하강법을 보았습니다. 여러 독립 변수에 대해서라면 벡터/행렬 형태의 방정식을 사용해야 합니다. 그리 어렵지는 않을 것입니다. 우리에게는 최근 MQL5에서 출시한 행렬용 라이브러리가 있습니다. 행렬에 대한 도움이 필요하시면 언제든지 저에게 연락해 주세요. 기꺼이 도와드리겠습니다.

감사합니다

미적분에 대해 더 알아보려면:


MetaQuotes 소프트웨어 사를 통해 영어가 번역됨
원본 기고글: https://www.mql5.com/en/articles/11200

파일 첨부됨 |
트레이딩 Expert Advisor를 처음부터 개발하기(16부): 웹에서 데이터 액세스하기(II) 트레이딩 Expert Advisor를 처음부터 개발하기(16부): 웹에서 데이터 액세스하기(II)
웹에서 Expert Advisor에 데이터를 입력하는 방법은 그리 당연하지 않습니다. MetaTrader 5가 제공하는 모든 가능성을 이해하지 않고는 그렇게 쉬운 일이 아닙니다.
CCI 지표. 업그레이드 및 새로운 기능 CCI 지표. 업그레이드 및 새로운 기능
이 기사에서는 CCI 지표를 업그레이드 하는 가능성에 대해 알아봅니다. 또한 저는 지표의 수정을 제시할 것입니다.
Expert Advisor 개발 기초부터(17부): 웹에서 데이터 액세스하기(III) Expert Advisor 개발 기초부터(17부): 웹에서 데이터 액세스하기(III)
이 문서에서는 웹에서 데이터를 가져와 Expert Advisor에서 사용하는 방법에 대해 계속 살펴봅니다. 이번에는 대체 시스템 개발에 대해 알아볼 것입니다.
Williams PR로 트레이딩 시스템을 설계하는 방법 알아보기 Williams PR로 트레이딩 시스템을 설계하는 방법 알아보기
이 기사는 MetaTrader 5 MQL5의 가장 인기 있는 기술 지표를 사용하여 거래 시스템을 설계하는 방법을 알아보는 시리즈의 새로운 기사입니다. 이 기사에서는 Williams의 %R 지표로 거래 시스템을 설계하는 방법에 대해 알아봅니다.