Skip to content

Commit 0af66a5

Browse files
author
Anh-Duy Le
committed
DLE-190520-Impl polynomial model (bonus)
1 parent 579dd58 commit 0af66a5

File tree

5 files changed

+108
-8
lines changed

5 files changed

+108
-8
lines changed

__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def mainProcess(self):
5959

6060
elif(option == 3):
6161
self.validateInput(option, checkedDate, baseCurrency, toCurrency)
62-
checkedDaysPerMonth = 6
62+
checkedDaysPerMonth = 20
6363

6464
service = ExchangeRateService()
6565
data = service.predicted_long_exrate_bytrainnedmodel(self.ApiGetExcRateConfig, self.checkedDate, self.baseCurrency, self.toCurrency, checkedDaysPerMonth)

core_utils/util_logic.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def calLinearRegressionOfY(self, lstSampleValueX, lstSampleValueY, xVal):
3636
intercept = (sumY - slope*sumX) / numberOfVal
3737

3838
#calculate approximate Y value (predict Y) for specific X value by regression equation: y = a + bx
39+
print("Formula Equation: y = {0}x + {1}".format(slope, intercept))
3940
equationResult = intercept + slope*xVal
4041

4142
return equationResult
@@ -60,3 +61,37 @@ def calLinearRegressionOfListY(self, lstSampleValueX, lstSampleValueY, lstXVal):
6061

6162
return None
6263

64+
def calPolynomialRegressionOfY(self, lstSampleValueX, lstSampleValueY, xVal):
65+
try:
66+
lstSpX = 0
67+
lstSpY = 0
68+
69+
if lstSampleValueX and len(lstSampleValueX) > 0:
70+
lstSpX = lstSampleValueX
71+
if lstSampleValueY and len(lstSampleValueY) > 0:
72+
lstSpY = lstSampleValueY
73+
74+
numberOfVal = (len(lstSpX) > len(lstSpY)) and len(lstSpX) or len(lstSpY)
75+
sumX = self.calTotalSumOfSeries(lstSpX)
76+
sumY = self.calTotalSumOfSeries(lstSpY)
77+
sumXY = sum([x * y for (x, y) in zip(lstSpX, lstSpY)])
78+
sumXX = sum([x1 * x2 for (x1, x2) in zip(lstSpX, lstSpX)])
79+
sumXXX = sum([x1 * x2 * x3 for (x1, x2, x3) in zip(lstSpX, lstSpX, lstSpX)])
80+
sumXXXX = sum([x1 * x2 * x3 * x4 for (x1, x2, x3, x4) in zip(lstSpX, lstSpX, lstSpX, lstSpX)])
81+
sumXXY = sum([x1 * x2 * y for (x1, x2, y) in zip(lstSpX, lstSpX, lstSpY)])
82+
83+
#the more list of value X and Y passed in, the more calculation for coefficients be matched
84+
coefficientA = (sumXXY * sumXX - sumXY * sumXXX) / (sumXX * sumXXXX - pow(sumXXX, 2))
85+
coefficientB = (sumXY * sumXXXX - sumXXY * sumXXX) / (sumXX * sumXXXX - pow(sumXXX, 2))
86+
coefficientC = (sumY/numberOfVal) - (coefficientB * (sumX/numberOfVal)) - (coefficientA * (sumXX/numberOfVal))
87+
88+
#calculate approximate Y value (predict Y) for specific X value by quadratic equation: y = ax^2 + bx + c
89+
print("Formula Equation: y = {0}x^2 + {1}x + {2}".format(coefficientA, coefficientB, coefficientC))
90+
equationResult = coefficientA*pow(xVal, 2) + coefficientB*xVal + coefficientC
91+
92+
return equationResult
93+
94+
except ValueError as ex:
95+
print('Error: ', ex)
96+
97+
return 0

service/banking/exchangerate_service.py

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import os, sys
22
import inspect, types
33
from datetime import timedelta, date, datetime
4+
from array import *
45

56
import matplotlib.pyplot as plt
67

78
import sklearn.utils._cython_blas
9+
from sklearn import linear_model
810
from sklearn.linear_model import LinearRegression
11+
from sklearn.preprocessing import PolynomialFeatures
12+
from sklearn.pipeline import Pipeline
913
from sklearn.model_selection import train_test_split
1014
import joblib
1115
from pathlib import Path
@@ -106,12 +110,13 @@ def display_graph(self, listdata):
106110
plt.show()
107111

108112

109-
def training_linear_model(self, listdata):
113+
def training_linear_model(self, listdata, valueNeedPredict):
110114
date = [[x.OnDate] for x in listdata]
111115
rate = [[x.RateValue] for x in listdata]
112116

113117
#Use 80% of data as training, rest 20% to Test model
114118
x_train, x_test, y_train, y_test = train_test_split(date, rate, test_size=0.2)
119+
115120
# training model
116121
linear = LinearRegression()
117122
linear.fit(x_train, y_train)
@@ -125,23 +130,67 @@ def training_linear_model(self, listdata):
125130
joblib.dump(linear, modelPathDir)
126131

127132
# loading model
133+
not valueNeedPredict and x_test or x_test.insert(0, [valueNeedPredict])
128134
clf = joblib.load(modelPathDir)
129135
predicted = clf.predict(x_test)#linear.predict(x_test)
136+
print("###Predicted by Linear Model")
137+
print("Predicted Max:", predicted.max())
138+
print("Predicted Min:", predicted.min())
139+
print("Predicted: ", predicted)
140+
141+
return predicted
142+
143+
144+
def training_polynomial_model(self, listdata, valueNeedPredict):
145+
date = [[x.OnDate] for x in listdata]
146+
rate = [[x.RateValue] for x in listdata]
147+
148+
#Use 80% of data as training, rest 20% to Test model
149+
x_train, x_test, y_train, y_test = train_test_split(date, rate, test_size=0.2)
150+
151+
# training model
152+
poly = Pipeline([('poly', PolynomialFeatures(interaction_only=True, degree=2)),
153+
('linear', linear_model.LinearRegression(fit_intercept=False))])
154+
poly.fit(x_train, y_train)
155+
156+
# evaluating model
157+
score_trained = poly.score(x_test, y_test)
158+
print("Model scored:", score_trained)
159+
160+
# saving model
161+
modelPathDir = Path(ROOT_DIR + r'/model_trained/poly_model.pkl')
162+
joblib.dump(poly, modelPathDir)
163+
164+
# loading model
165+
not valueNeedPredict and x_test or x_test.insert(0, [valueNeedPredict])
166+
clf = joblib.load(modelPathDir)
167+
predicted = clf.predict(x_test)#poly.predict(x_test)
168+
print("###Predicted by Polynomial Model")
130169
print("Predicted Max:", predicted.max())
131170
print("Predicted Min:", predicted.min())
132171
print("Predicted: ", predicted)
133172

134173
return predicted
135174

136175

137-
def calculate_exrate_forSpecificDate(self, listdata, checkedDate):
176+
def calculate_exrate_bypurelinearmodel(self, listdata, checkedDate):
138177
date = [x.OnDate for x in listdata]
139178
rate = [x.RateValue for x in listdata]
140179
chkDate = datetime.timestamp(checkedDate)
141180

142181
predictedRate = self.util_logic.calLinearRegressionOfY(lstSampleValueX=date, lstSampleValueY=rate, xVal=chkDate)
143182

144183
return predictedRate
184+
185+
186+
def calculate_exrate_bypurepolynomialmodel(self, listdata, checkedDate):
187+
date = [x.OnDate for x in listdata]
188+
rate = [x.RateValue for x in listdata]
189+
chkDate = datetime.timestamp(checkedDate)
190+
191+
predictedRate = self.util_logic.calPolynomialRegressionOfY(lstSampleValueX=date, lstSampleValueY=rate, xVal=chkDate)
192+
193+
return predictedRate
145194

146195

147196
def predicted_quick_exrate_bytrainnedmodel(self, apiConfig, strPredictedDate, baseCurrency, toCurrency):
@@ -154,7 +203,8 @@ def predicted_quick_exrate_bytrainnedmodel(self, apiConfig, strPredictedDate, ba
154203

155204
data = self.get_specific_exrate_byDateRange(apiConfig, dateLastMonth, dateLastYear, checkedDate, baseCurrency, toCurrency)
156205

157-
self.training_linear_model(data)
206+
self.training_linear_model(data, datetime.timestamp(predictedDate))
207+
self.training_polynomial_model(data, datetime.timestamp(predictedDate))
158208

159209
return data
160210

@@ -170,7 +220,8 @@ def predicted_long_exrate_bytrainnedmodel(self, apiConfig, strPredictedDate, bas
170220

171221
data = self.get_specific_exrate_byDateRange(apiConfig, dateLastMonth, dateLastYear, checkedDate, baseCurrency, toCurrency)
172222

173-
self.training_linear_model(data)
223+
self.training_linear_model(data, datetime.timestamp(predictedDate))
224+
self.training_polynomial_model(data, datetime.timestamp(predictedDate))
174225

175226
return data
176227

@@ -184,8 +235,10 @@ def predicted_basic_exrate(self, apiConfig, strPredictedDate, baseCurrency, toCu
184235

185236
data = self.get_specific_exrate_byDateRange(apiConfig, dateLastMonth, dateLastYear, checkedDate, baseCurrency, toCurrency)
186237

187-
predictedRate = self.calculate_exrate_forSpecificDate(data, predictedDate)
188-
print("Predicted: ", predictedRate)
238+
predictedRate = self.calculate_exrate_bypurelinearmodel(data, predictedDate)
239+
print("Predicted with Linear Regression Model: ", predictedRate)
240+
predictedRate2 = self.calculate_exrate_bypurepolynomialmodel(data, predictedDate)
241+
print("Predicted with Polynomial Regression Model: ", predictedRate2)
189242

190243
return data
191244

unit_tests/test_service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import sys, os
33
import urllib
44
import urllib.parse
5+
import datetime
56

67

78
ROOT_DIR = os.getcwd() # Get root directory
@@ -58,7 +59,7 @@ def test_exrate__get_specific_exrate_byDateRange(self):
5859
data = service.get_specific_exrate_byDateRange(ServiceTestCase.ApiCheckExcRateConfig, fromDate, toDate, checkedDate, baseCurrency, toCurrency)
5960

6061
# service.display_graph(data)
61-
service.training_linear_model(data)
62+
service.training_linear_model(data, datetime.datetime.timestamp( datetime.datetime(year=2017, month=1, day=checkedDate[0]) ))
6263

6364
self.assertIsNotNone(data, '###Error Message: No data')
6465

unit_tests/test_utility.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ def test_logic__calLinearRegressionOfListY(self):
7575

7676
self.assertIsNotNone(data, '###Error Message: No data')
7777

78+
def test_logic__calPolynomialRegressionOfY(self):
79+
80+
lstX = [-6, -4, -2, 0, 2, 4, 6]
81+
lstY = [2.28, 1.42, 0.67, 0, -0.57, -1.05, -1.42]
82+
x = -7.72
83+
84+
data = UtilityTestCase.UtilLogic.calPolynomialRegressionOfY(lstX, lstY, x)
85+
print(data)
86+
87+
self.assertIsNotNone(data, '###Error Message: No data')
88+
7889

7990

8091
###########################################################################################################

0 commit comments

Comments
 (0)