746 lines
30 KiB
Python
746 lines
30 KiB
Python
import mysql.connector as connection
|
|
import pandas as pd
|
|
import numpy as np
|
|
from app import app
|
|
from flask import jsonify
|
|
from flask import flash, request, json
|
|
from sklearn.linear_model import LinearRegression
|
|
from sklearn.preprocessing import PolynomialFeatures
|
|
from sklearn.ensemble import RandomForestRegressor
|
|
from sklearn.svm import SVR
|
|
from sklearn.pipeline import make_pipeline
|
|
from sklearn.preprocessing import StandardScaler
|
|
from sklearn.model_selection import train_test_split
|
|
from sklearn.metrics import mean_squared_error
|
|
from sklearn.model_selection import GridSearchCV
|
|
from sklearn.pipeline import Pipeline
|
|
from werkzeug.exceptions import HTTPException
|
|
from joblib import Parallel, delayed
|
|
import joblib
|
|
|
|
def connectDB():
|
|
try:
|
|
mydb = connection.connect(host="localhost", database = 'mitra_panen_skripsi',user="root", passwd="",use_pure=True)
|
|
return mydb
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
# Define the function to return the MAPE values
|
|
def calculate_mape(actual, predicted) -> float:
|
|
# Convert actual and predicted
|
|
# to numpy array data type if not already
|
|
if not all([isinstance(actual, np.ndarray),
|
|
isinstance(predicted, np.ndarray)]):
|
|
actual, predicted = np.array(actual),
|
|
np.array(predicted)
|
|
|
|
# Calculate the MAPE value and return
|
|
return round(np.mean(np.abs((
|
|
actual - predicted) / actual)) * 100, 3)
|
|
|
|
@app.route('/training/full')
|
|
def training_full():
|
|
try:
|
|
# get data from database
|
|
mydb = connectDB()
|
|
query = "SELECT fish_type_id, seed_amount, seed_weight, survival_rate, average_weight, pond_volume, total_feed_spent, harvest_amount FROM harvest_fish"
|
|
df = pd.read_sql(query,mydb)
|
|
# print(df)
|
|
|
|
# set data train
|
|
x_train = df.iloc[:, :7].values
|
|
y_train = df.iloc[:, 7].values
|
|
|
|
# Training Model
|
|
method = request.args.get('method')
|
|
if(method == 'linear'):
|
|
print("Linear Regression")
|
|
# Linear Regression Model
|
|
model = LinearRegression()
|
|
model.fit(x_train, y_train)
|
|
elif(method == 'poly'):
|
|
print("Polynomial Regression")
|
|
# Polynomial Regression Model full data
|
|
model_poly = PolynomialFeatures(degree = 3)
|
|
x_poly = model_poly.fit_transform(x_train)
|
|
model_poly.fit(x_poly, y_train)
|
|
model = LinearRegression()
|
|
model.fit(x_poly, y_train)
|
|
elif(method == 'rf'):
|
|
print("Random Forest Regression")
|
|
# Random Forest Regression Model
|
|
model = RandomForestRegressor(min_samples_leaf=1, n_estimators=100, random_state=0)
|
|
model.fit(x_train, y_train)
|
|
elif(method == 'svr'):
|
|
print("SVR")
|
|
model = make_pipeline(StandardScaler(), SVR(kernel="poly", C=100, gamma="scale", degree=3, coef0=2))
|
|
model.fit(x_train, y_train)
|
|
else:
|
|
print("tidak ada request")
|
|
model = LinearRegression()
|
|
model.fit(x_train, y_train)
|
|
|
|
# save regression model to file
|
|
joblib.dump(model, 'regression_model.pkl')
|
|
joblib.dump(method, 'method.pkl')
|
|
if(method == 'poly'):
|
|
joblib.dump(model_poly, 'regression_model_poly.pkl')
|
|
|
|
# respon API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil menyimpan training model",
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
def get_total_feed_spent(fish_id, seed_amount, sr) -> float:
|
|
# check seed amount
|
|
if(seed_amount == 1000 or seed_amount == 1500 or seed_amount == 2000):
|
|
temp_amount = seed_amount
|
|
check = 0
|
|
else:
|
|
temp_amount = 1000
|
|
check = 1
|
|
|
|
# get data from database
|
|
mydb = connectDB()
|
|
query = "SELECT total_feed_spent FROM harvest_fish WHERE fish_type_id=" + fish_id + " AND seed_amount=" + str(temp_amount)
|
|
df = pd.read_sql(query,mydb)
|
|
df_values = df.values.flatten()
|
|
|
|
# calculate total feed spent
|
|
if(check == 1):
|
|
for i in range(len(df_values)):
|
|
df_values[i] = seed_amount / 1000 * df_values[i]
|
|
total_feed_spent = sum(df_values) / len(df_values)
|
|
total_feed_spent = sr / 100 * total_feed_spent
|
|
return round(total_feed_spent, 1)
|
|
|
|
@app.route('/implements')
|
|
def implements_model():
|
|
try:
|
|
# get data
|
|
fish_id = request.args.get('fish_id')
|
|
seed_amount = request.args.get('seed_amount')
|
|
seed_weight = request.args.get('seed_weight')
|
|
pond_volume = request.args.get('pond_volume')
|
|
total_fish_count = request.args.get('total_fish_count')
|
|
|
|
# processing data
|
|
average_weight = 1000 / int(total_fish_count)
|
|
average_weight = round(average_weight, 2)
|
|
if(fish_id == '1'):
|
|
sr_arr = [85,87,89,91,93]
|
|
elif(fish_id == '2'):
|
|
sr_arr = [84,86,88,90,92]
|
|
else:
|
|
sr_arr = [65,70,75,80,85]
|
|
|
|
# load model
|
|
method = joblib.load('method.pkl')
|
|
model = joblib.load('regression_model.pkl')
|
|
|
|
# predict data with regression model by survival rate
|
|
result_predict = []
|
|
table_result = []
|
|
graph_result = []
|
|
tfs = []
|
|
for i in range(len(sr_arr)):
|
|
sr = sr_arr[i]
|
|
total_feed_spent = get_total_feed_spent(fish_id, int(seed_amount), sr)
|
|
tfs.append(total_feed_spent)
|
|
data = np.array([[fish_id, seed_amount, seed_weight, sr, average_weight, pond_volume, total_feed_spent]])
|
|
data = np.array(data, dtype=float)
|
|
if(method == 'poly'):
|
|
model_poly = joblib.load('regression_model_poly.pkl')
|
|
predict = model.predict(model_poly.fit_transform(data))
|
|
else:
|
|
predict = model.predict(data)
|
|
|
|
# control value of prediction
|
|
max_harvest = average_weight * int(seed_amount) / 1000
|
|
if(predict[0] > max_harvest):
|
|
predict[0] = max_harvest
|
|
elif(predict[0] < 0):
|
|
predict[0] = 0
|
|
|
|
result_predict.append(round(predict[0],3))
|
|
table_result.append({"sr":sr, "predict":round(predict[0],3)})
|
|
graph_result.append({"x":sr, "y":round(predict[0],3)})
|
|
|
|
# save implements result to file
|
|
implements_result = {
|
|
"fish_id":fish_id, "seed_amount":seed_amount, "seed_weight":seed_weight,
|
|
"average_weight":average_weight, "total_feed_spent":tfs, "sr_arr":sr_arr,
|
|
"result_predict":result_predict, "table_result":table_result, "graph_result":graph_result
|
|
}
|
|
joblib.dump(implements_result, "implements_result.pkl")
|
|
|
|
# response API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil implements model",
|
|
"method": method,
|
|
"predict": result_predict,
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.route('/implements/prediction')
|
|
def implements_prediction():
|
|
try:
|
|
# get data
|
|
fish_id = request.args.get('fish_id')
|
|
seed_amount = request.args.get('seed_amount')
|
|
seed_weight = request.args.get('seed_weight')
|
|
pond_volume = request.args.get('pond_volume')
|
|
total_fish_count = request.args.get('total_fish_count')
|
|
sr = request.args.get('survival_rate')
|
|
sr = float(sr)
|
|
|
|
# processing data
|
|
average_weight = 1000 / int(total_fish_count)
|
|
average_weight = round(average_weight, 2)
|
|
|
|
# load model
|
|
method = joblib.load('method.pkl')
|
|
model = joblib.load('regression_model.pkl')
|
|
|
|
# predict data with regression model
|
|
total_feed_spent = get_total_feed_spent(fish_id, int(seed_amount), sr)
|
|
data = np.array([[fish_id, seed_amount, seed_weight, sr, average_weight, pond_volume, total_feed_spent]])
|
|
data = np.array(data, dtype=float)
|
|
if(method == 'poly'):
|
|
model_poly = joblib.load('regression_model_poly.pkl')
|
|
predict = model.predict(model_poly.fit_transform(data))
|
|
else:
|
|
predict = model.predict(data)
|
|
|
|
# control value of prediction
|
|
max_harvest = average_weight * int(seed_amount) / 1000
|
|
if(predict[0] > max_harvest):
|
|
predict[0] = max_harvest
|
|
elif(predict[0] < 0):
|
|
predict[0] = 0
|
|
|
|
# duration fish
|
|
if(fish_id == '1'):
|
|
day = list(range(1, 91))
|
|
else:
|
|
day = list(range(1,181))
|
|
|
|
# cultivation data
|
|
total_fish = predict[0] * 1000 / average_weight
|
|
growth = (average_weight - float(seed_weight)) / (len(day)-1)
|
|
weight = []
|
|
feed_spent = []
|
|
simulation_table = []
|
|
current_feed = 0.0
|
|
current_total_feed = 0.0
|
|
current_weight = 0.0
|
|
temp_total_feed = 0.0
|
|
rule_feed = [0.0] * 4
|
|
for j in range(len(day)):
|
|
# simulation weight
|
|
if(day[j] == 1):
|
|
current_weight += float(seed_weight)
|
|
else:
|
|
current_weight = float(current_weight) + float(growth)
|
|
weight.append({"x":day[j], "y":round(current_weight,3)})
|
|
|
|
# make rule feed using percentage above day 30
|
|
if(day[j] == 31):
|
|
temp_total_feed = total_feed_spent - current_total_feed
|
|
if(fish_id == '1'):
|
|
rule_feed[0] = (temp_total_feed * 0.4) / 30 # day 31-60 feed spent 40%
|
|
rule_feed[1] = (temp_total_feed * 0.6) / 30 # day 61-90 feed spent 60%
|
|
else:
|
|
rule_feed[0] = (temp_total_feed * 0.1) / 30 # day 31-60 feed spent 10%
|
|
rule_feed[1] = (temp_total_feed * 0.15) / 30 # day 61-90 feed spent 15%
|
|
rule_feed[2] = (temp_total_feed * 0.45) / 60 # day 91-150 feed spent 45%
|
|
rule_feed[3] = (temp_total_feed * 0.3) / 30 # day 151-180 feed spent 30%
|
|
|
|
# simulation feed spent
|
|
if(day[j] == 1 or day[j] == 2): # day 1-2 feed spent 0
|
|
current_feed = 0.0
|
|
elif(day[j] >= 3 and day[j] <= 5): # day 3-5 feed spent 0.15kg
|
|
current_feed = 0.15 * float(seed_amount) / 1000
|
|
elif(day[j] == 6 or day[j] == 7): # day 6-7 feed spent 0.3kg
|
|
current_feed = 0.3 * float(seed_amount) / 1000
|
|
elif(day[j] == 8 or day[j] == 9): # day 8-9 feed spent 0.4kg
|
|
current_feed = 0.4 * float(seed_amount) / 1000
|
|
elif(day[j] >= 10 and day[j] <= 30): # day 10-30 feed spent 0.6kg
|
|
current_feed = 0.6 * float(seed_amount) / 1000
|
|
elif(day[j] >= 31 and day[j] <= 60): # day 31-60 feed spent rule[0]
|
|
current_feed = rule_feed[0]
|
|
elif(day[j] >= 61 and day[j] <= 90): # day 61-90 feed spent rule[1]
|
|
current_feed = rule_feed[1]
|
|
elif(day[j] >= 91 and day[j] <= 150): # day 91-150 feed spent rule[2]
|
|
current_feed = rule_feed[2]
|
|
elif(day[j] >= 151 and day[j] <= 180): # day 151-180 feed spetn rule[3]
|
|
current_feed = rule_feed[3]
|
|
else:
|
|
current_feed = 1
|
|
|
|
current_total_feed += float(current_feed)
|
|
feed_spent.append({"x":day[j], "y":round(current_feed,1)})
|
|
total_weight = total_fish * current_weight / 1000
|
|
simulation_table.append({"day":day[j], "weight":round(current_weight,1), "feed_spent":round(current_feed,1), "total_feed_spent":round(current_total_feed,1), "total_weight":round(total_weight,1)})
|
|
|
|
# response API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil implements prediction model",
|
|
"method": method,
|
|
"predict": round(predict[0],1),
|
|
"total_feed_spent": round(total_feed_spent,1),
|
|
"simulation_table": simulation_table
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.route('/implements/result')
|
|
def get_implements_result():
|
|
try:
|
|
# get implements result data
|
|
implements_result = joblib.load("implements_result.pkl")
|
|
fish_id = implements_result["fish_id"]
|
|
seed_amount = implements_result["seed_amount"]
|
|
seed_weight = implements_result["seed_weight"]
|
|
average_weight = implements_result["average_weight"]
|
|
total_feed_spent = implements_result["total_feed_spent"]
|
|
sr_arr = implements_result["sr_arr"]
|
|
result_predict = implements_result["result_predict"]
|
|
table_result = implements_result["table_result"]
|
|
graph_result = implements_result["graph_result"]
|
|
|
|
# duration fish
|
|
if(fish_id == '1'):
|
|
day = list(range(1, 91))
|
|
day_range = ['1-2', '3-5', '6-7', '8-9', '10-30', '31-60', '61-90']
|
|
else:
|
|
day = list(range(1,181))
|
|
day_range = ['1-2', '3-5', '6-7', '8-9', '10-30', '31-60', '61-90', '91-150', '151-180']
|
|
|
|
# processing simulation weight and feed spent
|
|
graph_weight = []
|
|
graph_feed_spent = []
|
|
feed_spent_arr = []
|
|
total_weight_arr = []
|
|
simulation_table_arr = []
|
|
simple_feed_arr = []
|
|
for i in range(len(sr_arr)):
|
|
total_fish = result_predict[i] * 1000 / average_weight
|
|
growth = (average_weight - float(seed_weight)) / (len(day)-1)
|
|
weight = []
|
|
feed_spent = []
|
|
simulation_table = []
|
|
simple_feed = []
|
|
current_feed = 0.0
|
|
current_total_feed = 0.0
|
|
current_weight = 0.0
|
|
temp_total_feed = 0.0
|
|
rule_feed = [0.0] * 4
|
|
for j in range(len(day)):
|
|
# simulation weight
|
|
if(day[j] == 1):
|
|
current_weight += float(seed_weight)
|
|
else:
|
|
current_weight = float(current_weight) + float(growth)
|
|
weight.append({"x":day[j], "y":round(current_weight,3)})
|
|
|
|
# make rule feed using percentage above day 30
|
|
if(day[j] == 31):
|
|
temp_total_feed = total_feed_spent[i] - current_total_feed
|
|
if(fish_id == '1'):
|
|
rule_feed[0] = (temp_total_feed * 0.4) / 30 # day 31-60 feed spent 40%
|
|
rule_feed[1] = (temp_total_feed * 0.6) / 30 # day 61-90 feed spent 60%
|
|
else:
|
|
rule_feed[0] = (temp_total_feed * 0.1) / 30 # day 31-60 feed spent 10%
|
|
rule_feed[1] = (temp_total_feed * 0.15) / 30 # day 61-90 feed spent 15%
|
|
rule_feed[2] = (temp_total_feed * 0.45) / 60 # day 91-150 feed spent 45%
|
|
rule_feed[3] = (temp_total_feed * 0.3) / 30 # day 151-180 feed spent 30%
|
|
|
|
# simulation feed spent
|
|
if(day[j] == 1 or day[j] == 2): # day 1-2 feed spent 0
|
|
current_feed = 0.0
|
|
elif(day[j] >= 3 and day[j] <= 5): # day 3-5 feed spent 0.15kg
|
|
current_feed = 0.15 * float(seed_amount) / 1000
|
|
elif(day[j] == 6 or day[j] == 7): # day 6-7 feed spent 0.3kg
|
|
current_feed = 0.3 * float(seed_amount) / 1000
|
|
elif(day[j] == 8 or day[j] == 9): # day 8-9 feed spent 0.4kg
|
|
current_feed = 0.4 * float(seed_amount) / 1000
|
|
elif(day[j] >= 10 and day[j] <= 30): # day 10-30 feed spent 0.6kg
|
|
current_feed = 0.6 * float(seed_amount) / 1000
|
|
elif(day[j] >= 31 and day[j] <= 60): # day 31-60 feed spent rule[0]
|
|
current_feed = rule_feed[0]
|
|
elif(day[j] >= 61 and day[j] <= 90): # day 61-90 feed spent rule[1]
|
|
current_feed = rule_feed[1]
|
|
elif(day[j] >= 91 and day[j] <= 150): # day 91-150 feed spent rule[2]
|
|
current_feed = rule_feed[2]
|
|
elif(day[j] >= 151 and day[j] <= 180): # day 151-180 feed spetn rule[3]
|
|
current_feed = rule_feed[3]
|
|
else:
|
|
current_feed = 1
|
|
|
|
current_total_feed += float(current_feed)
|
|
feed_spent.append({"x":day[j], "y":round(current_feed,1)})
|
|
total_weight = total_fish * current_weight / 1000
|
|
simulation_table.append({"day":day[j], "weight":round(current_weight,3), "feed_spent":round(current_feed,1), "total_weight":round(total_weight,3)})
|
|
simple_feed.append(round(current_feed,1))
|
|
total_weight_arr.append(round(total_weight,3))
|
|
feed_spent_arr.append(round(current_total_feed,1))
|
|
simulation_table_arr.append(simulation_table)
|
|
graph_weight.append(weight)
|
|
graph_feed_spent.append(feed_spent)
|
|
simple_feed = list(set(simple_feed))
|
|
simple_feed_arr.append(simple_feed)
|
|
|
|
# mapping simple simulation feed
|
|
simple_table_arr = []
|
|
for i in range(len(simple_feed_arr)):
|
|
simple_table = []
|
|
for j in range(len(day_range)):
|
|
simple_table.append({'day_range':day_range[j], 'feed_spent':simple_feed_arr[i][j]})
|
|
simple_table_arr.append(simple_table)
|
|
|
|
# response API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil mendapatkan data hasil implementasi",
|
|
"sr": sr_arr,
|
|
"total_feed_spent": total_feed_spent,
|
|
"predict": result_predict,
|
|
"table_result": table_result,
|
|
"graph_result": graph_result,
|
|
"table_simulation_1": simulation_table_arr[0],
|
|
"table_simulation_2": simulation_table_arr[1],
|
|
"table_simulation_3": simulation_table_arr[2],
|
|
"table_simulation_4": simulation_table_arr[3],
|
|
"table_simulation_5": simulation_table_arr[4],
|
|
"graph_weight": graph_weight,
|
|
"graph_feed": graph_feed_spent,
|
|
"table_simple_1": simple_table_arr[0],
|
|
"table_simple_2": simple_table_arr[1],
|
|
"table_simple_3": simple_table_arr[2],
|
|
"table_simple_4": simple_table_arr[3],
|
|
"table_simple_5": simple_table_arr[4],
|
|
"total_feed_spent_arr": feed_spent_arr,
|
|
"total_weight": total_weight_arr
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.route('/best/params')
|
|
def get_best_param():
|
|
try:
|
|
# get data from database
|
|
mydb = connectDB()
|
|
query = "SELECT fish_type_id, seed_amount, seed_weight, survival_rate, average_weight, pond_volume, total_feed_spent, harvest_amount FROM harvest_fish"
|
|
df = pd.read_sql(query,mydb)
|
|
x = df.iloc[:, :7].values
|
|
y = df.iloc[:, 7].values
|
|
|
|
# make pipeline for polynomial regression
|
|
pipeline_poly = Pipeline([
|
|
('poly', PolynomialFeatures()),
|
|
('regression', LinearRegression())
|
|
])
|
|
|
|
# make pipeline for SVR
|
|
pipeline_svr = Pipeline([
|
|
('scaler', StandardScaler()),
|
|
('svr', SVR())
|
|
])
|
|
|
|
model_params = {
|
|
'linear_regression': {
|
|
'model': LinearRegression(),
|
|
'params' : {
|
|
# No Parameter
|
|
}
|
|
},
|
|
'polynomial_regression': {
|
|
'model': pipeline_poly,
|
|
'params' : {
|
|
'poly__degree' : [2,3,4]
|
|
}
|
|
},
|
|
'random_forest': {
|
|
'model': RandomForestRegressor(),
|
|
'params' : {
|
|
'n_estimators': [1,10,100],
|
|
'min_samples_leaf' : [1,2,3],
|
|
'random_state': [0]
|
|
}
|
|
},
|
|
'svr': {
|
|
'model': pipeline_svr,
|
|
'params': {
|
|
'svr__kernel': ["linear", "poly", "rbf", "sigmoid", "precomputed"],
|
|
'svr__degree': [2,3,4],
|
|
'svr__gamma': ['scale', 'auto'],
|
|
'svr__coef0': [0,1,2],
|
|
'svr__C': [1,10,100],
|
|
}
|
|
}
|
|
}
|
|
|
|
# get best parameter model
|
|
scores = []
|
|
for model_name, mp in model_params.items():
|
|
clf = GridSearchCV(mp['model'], mp['params'], scoring='neg_root_mean_squared_error', cv=19)
|
|
clf.fit(x, y)
|
|
scores.append({
|
|
'model': model_name,
|
|
'best_score': clf.best_score_,
|
|
'best_params': clf.best_params_
|
|
})
|
|
score_df = pd.DataFrame(scores,columns=['model','best_score','best_params'])
|
|
table_scores = score_df.to_html(index=False)
|
|
|
|
# response API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil mendapatkan parameter terbaik setiap model",
|
|
"scores": scores,
|
|
"table_scores": table_scores
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.route('/split/data')
|
|
def split_data():
|
|
try:
|
|
# get data from database
|
|
mydb = connectDB()
|
|
test_size = request.args.get('test_size')
|
|
test_size = float(test_size)
|
|
query = "SELECT fish_type_id, seed_amount, seed_weight, survival_rate, average_weight, pond_volume, total_feed_spent, harvest_amount FROM harvest_fish"
|
|
df = pd.read_sql(query,mydb)
|
|
|
|
# split data to train and test
|
|
x = df.iloc[:, :7].values
|
|
y = df.iloc[:, 7].values
|
|
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=test_size,random_state=0)
|
|
|
|
# save split data
|
|
split_data = {"x_train":x_train, "x_test":x_test, "y_train":y_train, "y_test":y_test}
|
|
joblib.dump(split_data, "split_data.pkl")
|
|
|
|
# setting tuning hyperparameter
|
|
setting_param = request.args.get('setting')
|
|
if(setting_param == "default"):
|
|
# Linear Regression Model
|
|
lin = LinearRegression()
|
|
lin.fit(x_train, y_train)
|
|
|
|
# Polynomial Regression Model
|
|
poly = PolynomialFeatures()
|
|
x_poly = poly.fit_transform(x_train)
|
|
poly.fit(x_poly, y_train)
|
|
lin2 = LinearRegression()
|
|
lin2.fit(x_poly, y_train)
|
|
|
|
# Random Forest Regression Model
|
|
regressor = RandomForestRegressor(random_state=0)
|
|
regressor.fit(x_train, y_train)
|
|
|
|
# SVR Model
|
|
# model dengan akurasi terbaik : SVR(kernel="poly", C=100, gamma="auto", degree=2, coef0=1)
|
|
regr = make_pipeline(StandardScaler(), SVR())
|
|
regr.fit(x_train, y_train)
|
|
else :
|
|
# Linear Regression Model
|
|
lin = LinearRegression()
|
|
lin.fit(x_train, y_train)
|
|
|
|
# Polynomial Regression Model
|
|
poly = PolynomialFeatures(degree = 3)
|
|
x_poly = poly.fit_transform(x_train)
|
|
poly.fit(x_poly, y_train)
|
|
lin2 = LinearRegression()
|
|
lin2.fit(x_poly, y_train)
|
|
|
|
# Random Forest Regression Model
|
|
regressor = RandomForestRegressor(min_samples_leaf=1, n_estimators=100, random_state=0)
|
|
regressor.fit(x_train, y_train)
|
|
|
|
# SVR Model
|
|
regr = make_pipeline(StandardScaler(), SVR(kernel="poly", C=100, gamma="scale", degree=3, coef0=2))
|
|
regr.fit(x_train, y_train)
|
|
|
|
# save all model
|
|
all_model = {"linear":lin, "poly":poly, "lin2":lin2, "rf":regressor, "svr":regr}
|
|
joblib.dump(all_model, "all_model.pkl")
|
|
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil simpan split data",
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.route('/testing/model')
|
|
def testing_model():
|
|
try:
|
|
# get split data
|
|
split_data = joblib.load("split_data.pkl")
|
|
x_train = split_data["x_train"]
|
|
y_train = split_data["y_train"]
|
|
x_test = split_data["x_test"]
|
|
y_test = split_data["y_test"]
|
|
|
|
# set data train
|
|
data_train = []
|
|
for i in range(len(y_train)):
|
|
data_train.append({"fish_type_id":x_train[i][0], "seed_amount":x_train[i][1], "seed_weight":x_train[i][2], "survival_rate":x_train[i][3], "average_weight":x_train[i][4], "pond_volume":x_train[i][5], "total_feed_spent":x_train[i][6], "harvest_amount":y_train[i]})
|
|
|
|
# set data test
|
|
data_test = []
|
|
for i in range(len(y_test)):
|
|
data_test.append({"fish_type_id":x_test[i][0], "seed_amount":x_test[i][1], "seed_weight":x_test[i][2], "survival_rate":x_test[i][3], "average_weight":x_test[i][4], "pond_volume":x_test[i][5], "total_feed_spent":x_test[i][6], "harvest_amount":y_test[i]})
|
|
|
|
# load all regression model
|
|
all_model = joblib.load("all_model.pkl")
|
|
lin = all_model["linear"]
|
|
poly = all_model["poly"]
|
|
lin2 = all_model["lin2"]
|
|
regressor = all_model["rf"]
|
|
regr = all_model["svr"]
|
|
|
|
# predict with data test
|
|
y_linear = lin.predict(x_test)
|
|
y_poly = lin2.predict(poly.fit_transform(x_test))
|
|
y_rf = regressor.predict(x_test)
|
|
y_svr = regr.predict(x_test)
|
|
|
|
# set data comparison between harvest_amount actual (data test) with predict
|
|
data_compare = []
|
|
for i in range(len(y_test)):
|
|
data_compare.append({"actual":y_test[i], "y_linear":round(y_linear[i],3), "y_poly":round(y_poly[i],3), "y_rf":round(y_rf[i],3), "y_svr":round(y_svr[i],3)})
|
|
|
|
#setup data graph
|
|
actual_graph = []
|
|
linear_graph = []
|
|
poly_graph = []
|
|
rf_graph = []
|
|
svr_graph = []
|
|
data_compare = sorted(data_compare, key=lambda data:data["actual"])
|
|
for i in range(len(y_test)):
|
|
actual_graph.append({"x":i+1, "y":data_compare[i]["actual"]})
|
|
linear_graph.append({"x":i+1, "y":data_compare[i]["y_linear"]})
|
|
poly_graph.append({"x":i+1, "y":data_compare[i]["y_poly"]})
|
|
rf_graph.append({"x":i+1, "y":data_compare[i]["y_rf"]})
|
|
svr_graph.append({"x":i+1, "y":data_compare[i]["y_svr"]})
|
|
|
|
# test accuracy model with RMSE and MAPE
|
|
rmse = [0] * 4
|
|
rmse[0] = round(mean_squared_error(y_test, y_linear, squared=False),3)
|
|
rmse[1] = round(mean_squared_error(y_test, y_poly, squared=False),3)
|
|
rmse[2] = round(mean_squared_error(y_test, y_rf, squared=False),3)
|
|
rmse[3] = round(mean_squared_error(y_test, y_svr, squared=False),3)
|
|
mape = [0] * 4
|
|
mape[0] = str(calculate_mape(y_test, y_linear)) + ' %'
|
|
mape[1] = str(calculate_mape(y_test, y_poly)) + ' %'
|
|
mape[2] = str(calculate_mape(y_test, y_rf)) + ' %'
|
|
mape[3] = str(calculate_mape(y_test, y_svr)) + ' %'
|
|
mape_num = [0] * 4
|
|
mape_num[0] = calculate_mape(y_test, y_linear)
|
|
mape_num[1] = calculate_mape(y_test, y_poly)
|
|
mape_num[2] = calculate_mape(y_test, y_rf)
|
|
mape_num[3] = calculate_mape(y_test, y_svr)
|
|
metode = ['Linear Regression', 'Polynomial Regression', 'Random Forest Regression', 'SVR']
|
|
_method = ['linear', 'poly', 'rf', 'svr']
|
|
test_result = []
|
|
result = []
|
|
for i in range(len(metode)):
|
|
test_result.append({"metode":metode[i], "rmse":rmse[i], "mape":mape[i]})
|
|
result.append({"method":_method[i], "rmse":rmse[i], "mape":mape_num[i]})
|
|
|
|
# check if minimal rmse not same with minimal mape so use minimal rmse for best method
|
|
minimal_rmse = min(result, key=lambda x: x["rmse"])
|
|
minimal_mape = min(result, key=lambda x: x["mape"])
|
|
if(minimal_rmse["method"] != minimal_mape["method"]):
|
|
best_method = minimal_rmse["method"]
|
|
else:
|
|
best_method = minimal_mape["method"]
|
|
|
|
# Save model with high accuracy
|
|
joblib.dump(best_method, 'method.pkl')
|
|
if(best_method == "linear"):
|
|
joblib.dump(lin, 'regression_model.pkl')
|
|
elif(best_method == "poly"):
|
|
joblib.dump(lin2, 'regression_model.pkl')
|
|
joblib.dump(poly, 'regression_model_poly.pkl')
|
|
elif(best_method == "rf"):
|
|
joblib.dump(regressor, 'regression_model.pkl')
|
|
else:
|
|
joblib.dump(regr, 'regression_model.pkl')
|
|
|
|
# response API
|
|
respon = jsonify()
|
|
respon.data = json.dumps({
|
|
"code": 200,
|
|
"status": 'Success',
|
|
"message": "Berhasil testing model",
|
|
"data_train": data_train,
|
|
"data_test": data_test,
|
|
"data_compare": data_compare,
|
|
"test_result": test_result,
|
|
"minimal_rmse": minimal_rmse,
|
|
"minimal_mape": minimal_mape,
|
|
"best_method": best_method,
|
|
"actual_graph": actual_graph,
|
|
"linear_graph": linear_graph,
|
|
"poly_graph": poly_graph,
|
|
"rf_graph": rf_graph,
|
|
"svr_graph": svr_graph
|
|
})
|
|
respon.status_code = 200
|
|
return respon
|
|
|
|
except Exception as e:
|
|
print(str(e))
|
|
|
|
@app.errorhandler(HTTPException)
|
|
def handle_exception(e):
|
|
"""Return JSON instead of HTML for HTTP errors."""
|
|
# start with the correct headers and status code from the error
|
|
response = e.get_response()
|
|
# replace the body with JSON
|
|
response.data = json.dumps({
|
|
"code": e.code,
|
|
"name": e.name,
|
|
"description": e.description,
|
|
})
|
|
response.content_type = "application/json"
|
|
return response
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="0.0.0.0",port=4000) |