Gồm 2 bước:
Huấn luyện mô hình: Lựa chọn mô hình tốt nhất. Bước này thực hiện 1 lần (chỉ thực hiện lại khi mô hình giảm khả năng dự báo)
Vận hành mô hình: Dựa trên kết quả sau khi huấn luyện, cung cấp API cho các đơn vị khác sử dụng.
german_creditcredit_risk: khách hàng good hoặc badamount: số tiền giải ngân, purpose: mục đích vay, age: tuổi của khách hàng.data = tsk("german_credit")$data()
data = data[, c("credit_risk", "amount", "purpose", "age")]
task = TaskClassif$new("boston", backend = data, target = "credit_risk")
head(data, 5)
## credit_risk amount purpose age
## 1: good 1169 furniture/equipment 67
## 2: bad 5951 furniture/equipment 22
## 3: good 2096 repairs 49
## 4: good 7882 car (used) 45
## 5: bad 4870 others 53
lightgbmg = po("imputemedian") %>>%
po("imputeoor") %>>%
po("fixfactors") %>>%
po("encodeimpact") %>>% # woe transformation
lrn("classif.lightgbm")
gl = GraphLearner$new(g) # convert to graph
g$plot(html = TRUE) %>% visNetwork::visInteraction()
Kết hợp các quy trình và số liệu để ra được mô hình tốt nhất. Để không làm phức tạp, tại bước này sẽ sử dụng các tham số mặc định.
gl$train(task)
## [LightGBM] [Info] Number of positive: 700, number of negative: 300
## [LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000053 seconds.
## You can set `force_row_wise=true` to remove the overhead.
## And if memory is not enough, you can set `force_col_wise=true`.
## [LightGBM] [Info] Total Bins 328
## [LightGBM] [Info] Number of data points in the train set: 1000, number of used features: 4
## [LightGBM] [Info] [binary:BoostFromScore]: pavg=0.700000 -> initscore=0.847298
## [LightGBM] [Info] Start training from score 0.847298
Quá trình huấn luyện mô hình chỉ thực hiện 1 lần nên kết quả từ mô hình (object) sẽ được lưu lại dưới dạng 1 file .rds để phục vụ cho việc dự báo về sau.
# function save object
fnc_save_lightgbm <- function(graph_learner = NULL, model = NULL, file = NULL){
# save lightgbm model
saveRDS.lgb.Booster(model, paste0(file,"_model.rds"))
# save graph learner
saveRDS(graph_learner, paste0(file,"_gl.rds"))
}
# Save model
fnc_save_lightgbm(gl, gl$model$classif.lightgbm$model, 'lightgbm_test')
# save features info
feature_info = list(
feature_names = task$feature_names,
feature_types = task$feature_types,
levels = task$levels()
)
saveRDS(feature_info, "feature_info.rds")
Trước khi tạo API, ta kiểm tra kết quả dự báo của mô hình bằng 1 ví dụ. Đầu ra của mô hình có thể là hạng hoặc điểm số, xác suất vỡ nợ hoặc cả 3 tùy thuộc vào mục đích sử dụng. Phần ví dụ này đầu ra sẽ là điểm số.
newdata = data.table(amount = 1169, purpose = 'repairs', age = 20)
pred = as.data.table(gl$predict_newdata(newdata))
score = 1000 - pred$prob.bad * 1000
Điểm số: 659.8626762
Trong phần này chúng ta sẽ làm 1 số việc như:
sử dụng đầu vào là kết quả mô hình đã được huấn luyện ở trên bằng cách đọc file .rds đã được lưu lại ở trên.
Định dạng dữ liệu đầu vào để phù hợp với input của mô hình
Và tạo API để giao tiếp với các máy tính khác.
Dữ liệu đầu vào bao gồm các biến dạng numeric, text, … cần phải được định dạng trước để máy có thể hiểu. Hàm fix_feature_types() dưới đây sẽ được sử dụng để định dạng dữ liệu đầu vào.
fix_feature_types <- function(feature, feature_name, feature_info) {
id = match(feature_name, feature_info$feature_names)
feature_type = feature_info$feature_types$type[id]
switch(
feature_type,
"logical" = as.logical(feature),
"integer" = as.integer(feature),
"numeric" = as.numeric(feature),
"character" = as.character(feature),
"factor" = factor(feature, levels = feature_info$levels[[feature_name]],
ordered = FALSE),
"ordered" = factor(feature, levels = feature_info$levels[[feature_name]],
ordered = TRUE),
"POSIXct" = as.POSIXct(feature)
)
}
Để có dự báo chúng ta sử dụng POST request gửi dữ liệu dưới dạng JSON đến máy chủ. Sau khi nhận dữ liệu body từ POST request, máy chủ sẽ thực hiện tính toán, kết quả trả ra là điểm số định dạng JSON.
#* @post /predict_credit_risk
function(req) {
# get the JSON string from the post body
newdata = fromJSON(req$postBody, simplifyVector = FALSE)
# expect either JSON objects in an array or nested JSON objects
newdata = rbindlist(newdata, use.names = TRUE)
# convert all features in place to their expected feature_type
newdata[, colnames(newdata) := mlr3misc::pmap(list(.SD, colnames(newdata)),
fix_feature_types,
feature_info = feature_info)]
# predict and return as a data.table
pred = as.data.table(gl$predict_newdata(newdata))
score = 1000 - pred$prob.bad * 1000
return(score)
# or only the numeric values
# gl$predict_newdata(newdata)$response
}
Sử dụng package plumber cho để cài đặt web service. Trong phần này sẽ chạy phần code để dự báo (predict_gl.R) và khai báo host, port.
library(plumber)
r = plumb(file = "R/predict_gl.R", dir ='R/model_deploy')
r$run(port = 1030, host = "0.0.0.0")
Ví dụ 1 trường hợp gửi dữ liệu đến máy chủ và kết quả nhận được.
newdata = '[{"amount":1169, "purpose":"repairs", "age":"20"}]'
resp = httr::POST(url = "http://127.0.0.1:1030/predict_credit_risk",
body = newdata, encode = "json")
httr::content(resp)