Bài học này Tui sẽ trình bày cách tái sử dụng mô hình máy học đã được train trong bài 44 để sử dụng trong phiên bản Website này.
Rõ ràng việc train mô hình máy học nó tốn thời gian và cần nhiều tài nguyên, như vậy sau khi train xong thì ta chỉ tái sử dụng thôi, chứ không phải mỗi lần chạy phần mềm lên là train lại mô hình nó sẽ không tối ưu hệ thống.
Thông qua bài này, các bạn sẽ biết cách tái sử dụng mô hình máy học ở các nền tảng khác nhau. Ví dụ bài 44, Tui đã hướng dẫn cách train mô hình máy học trên giao diện Windows viết bằng Python Tkinter, tạo ra được mô hình máy học lưu lại với file zip định dạng pickle. Bài này thì sẽ dùng Web python Flask Microservice để triệu gọi mô hình máy học được train để để sử dụng (tức không phải thực hiện các bước chọn dataset, train mô hình).
Thông qua ví dụ này, bạn có thể viết các module để đính kèm vào hệ thống thương mại điện tử có sẵn để tích hợp mô hình máy học vào chạy trên nền web. Đưới đây là màn hình Website chúng ta sẽ thiết kế và sử dụng mô hình máy học:
Như vậy rõ ràng bạn phải làm bài 44 trước nha.
Và bắt buộc phải có kiến thức cơ bản về Website, HTML, Javascript, các bạn có thể học tại đây nếu chưa có kiến thức về nó:
Bây giờ ta bắt đầu thực hiện dự án:
Bạn cần phải tạo dự án có cấu trúc các tập tin và thư mục chính xác ở trên để nó khớp với các mã lệnh. Tui giải thích sơ lược như sau:
- Thư mục “web” chứa các static files được lưu trong thư mục css và images. Đồng thời chứa thư mục “templates” để lưu trữ html
- Thư mục “css” là định dạng Cascading Style Sheets (CSS) để định dạng website cho nó đẹp theo ý mình. Các định dạng được lưu trong file “maincss.css”
- Thư mục “images” sẽ lưu các hình ảnh tĩnh để sử dụng cho thiết kế website trong các trang .html
- Thư mục “templates” là thư mục chứa các mã lệnh html để thiết kế website cũng như tương tác lệnh với Python Flask, Ajax…
- File “housingmodel_2024-07-15_13-30-34.zip” là file mô hình máy học được tạo ra từ bài 44. Bạn có thể lấy bất kỳ file mô hình máy học được train.
- File “FileUtil.py” là file mã lệnh để nạp mô hình máy học vào bộ nhớ sau đó nó được đưa vào để sử dụng trên nền Web
- File chính “app.py” là file mã lệnh Python dạng Flask MicrosoService để gọi các lệnh render website, nạp mô hình máy học, và triệu gọi mô hình máy học cũng như xuất kết quả prediction cho người sử dụng trên nền website.
Bây giờ ta đi vào chi tiết của từng mã lệnh:
File “FileUtil.py” mã lệnh này quen thuộc dùng để lưu mô hình xuống ổ cứng với định dạng pickle và tải mô hình máy học lên bộ nhớ, ta đã sử dụng ở các bài học trước:
import pickle
class FileUtil:
@staticmethod
def savemodel(model, filename):
try:
pickle.dump(model, open(filename, 'wb'))
return True
except:
print("An exception occurred")
return False
@staticmethod
def loadmodel(filename):
try:
model = pickle.load(open(filename, 'rb'))
return model
except:
print("An exception occurred")
return None
Trong dự án web này thì chúng ta chỉ sử dụng hàm loadmodel của FileUtil mà thôi.
File “maincss.css” file Cascading Style Sheets để định dạng website cho trang index.html.
h3{
color:red
}
table{
border: 1px solid;
}
#tdtitle{
text-align:center
}
#tdbutton
{
text-align:right
}
table table tr:nth-child(even)
{
background-color: #f8f5c1;
}
#tdfooter
{
background-color: #457FE5;
color:white
}
Các selector trong maincss được khai báo trong index.html rồi. Và nó cần khớp với nhau.
Tiếp theo là trang “index.html” nó gồm có 2 phần chính, phần thứ nhất là Giao diện web, phần thứ 2 đó là tương tác người dùng áp dụng AJAX:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prediction Pricing House</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script scr="https://code.jquery.com/jquery-3.6.3.js"></script>
<link rel="stylesheet" href="css/maincss.css">
</head>
<body>
<form method="post">
<table>
<tr>
<td colspan="2" id="tdtitle">
<h3>House Pricing Prediction</h3>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Avg. Area Income:</td>
<td><input type = "text" name="area_income_value" id="area_income_value" size="15" /></td>
</tr>
<tr>
<td>Avg. Area House Age:</td>
<td><input type = "text" name="area_house_age_value" id="area_house_age_value" size="15" /></td>
</tr>
<tr>
<td>Avg. Area Number of Rooms:</td>
<td><input type = "text" name="area_number_of_rooms_value" id="area_number_of_rooms_value" size="15" /></td>
</tr>
<tr>
<td>Avg. Area Number of Bedrooms:</td>
<td><input type = "text" name="area_number_of_bedrooms_value" id="area_number_of_bedrooms_value" size="15" /></td>
</tr>
<tr>
<td>Area Population:</td>
<td><input type = "text" name="area_population_value" id="area_population_value" size="15" /></td>
</tr>
<tr>
<td colspan="2" id="tdbutton">
<button id="doprediction_button" type="button">Prediction</button>
</td>
</tr>
<tr>
<td>House Pricing Prediction:</td>
<td><input type="text" name="house_price" id="house_price" size="15"></td>
</tr>
</table>
</td>
<td>
<img src="images/ic_house.png" width="200px" height="200px">
</td>
</tr>
<tr>
<td colspan="2" id="tdfooter">Designed by: Trần Duy Thanh</td>
</tr>
</table>
</form>
<script>
$(function(){
$('#doprediction_button').click(function(){
$.ajax({
url: '/doprediction',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
$('#house_price').val(response);
},
error: function(error){
console.log(error);
}
})
})
})
</script>
</body>
</html>
“index.html” sẽ sử dụng “maincss.css” để format website đẹp
Và ở phía dưới index.html có các mã lệnh về AJAX để triệu gọi các API được thiết kế trong “app.py“
Khi người sử dụng nhập liệu vào các ô text box rồi nhấn nút “Prediction” chương trình sẽ dùng phương thức HTTP POST để đẩy dữ liệu lên Server:
<script>
$(function(){
$('#doprediction_button').click(function(){
$.ajax({
url: '/doprediction',
data: $('form').serialize(),
type: 'POST',
success: function(response){
console.log(response);
$('#house_price').val(response);
},
error: function(error){
console.log(error);
}
})
})
})
</script>
“doprediction” là API dạng POST được khai báo trong app.py
Khi AJAX triệu gọi API này, nó sẽ đẩy dữ liệu trong Form (là các ô nhập liệu) lên server và nhần kết quả trả về trong success
Bạn lưu ý các mã(id,name) của các texbox phải chính xác với khai báo trong app.py để nó lấy được dữ liệu.
Bây giờ ta qua “app.py“
from flask import Flask, render_template, request
from FileUtil import FileUtil
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
@app.route("/")
def main():
return render_template("index.html")
@app.route("/doprediction", methods=['GET','POST'])
def doprediction():
area_income_value = float(request.form['area_income_value'])
area_house_age_value = float(request.form['area_house_age_value'])
area_number_of_rooms_value = float(request.form['area_number_of_rooms_value'])
area_number_of_bedrooms_value = float(request.form['area_number_of_bedrooms_value'])
area_population_value = float(request.form["area_population_value"])
trainedModel = FileUtil.loadmodel('housingmodel_2024-07-15_13-30-34.zip')
result = trainedModel.predict([[area_income_value,
area_house_age_value,
area_number_of_rooms_value,
area_number_of_bedrooms_value,
area_population_value]])
return f"{result[0]}"
if __name__ == "__main__":
app.run(host="localhost", port=9500, debug=True)
Đầu tiên ta tạo đối tượng Flask, truyền các static url, static folder và template folder:
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
Chỗ này ta cần khai báo chính xác như cấu trúc thư mục mà ta tạo trong Pycharm. Điều đó có nghĩa là gì? tức là nếu trong Pycharm ta tạo cấu trúc như thế nào thì khai báo ở đây y chang như mong muốn là được (tức là không cần phải giống như Tui tạo). Như cố gắng tạo cấu trúc như Tui hướng dẫn để tránh sai sót trong quá trình lập trình.
Hàm để mặc định kích hoạt website trang chủ:
@app.route("/")
def main():
return render_template("index.html")
Vì ta đã khai báo template_folder trong đối tượng khởi tạo Flask rồi, nên khi gọi lệnh render_template(“index.html”) chương trình sẽ tự hiểu và tự động tạo giao diện website với index.html
Để kích hoạt website khi chạy, thì ta có lệnh:
if __name__ == "__main__":
app.run(host="localhost", port=9500, debug=True)
Ở trên ta chạy port 9500, bạn có thể đổi qua Port khác. Và tui để debug để tìm lỗi nếu có. Vì đang chạy local nên host là localhost
Cuối cùng đó là API doprediction để nhận kết quả từ Client (là các ô nhập liệu từ website) sau đó tải mô hình máy học để tiến hành prediction, sau khi prediction xong thì trả kết quả lại cho Client:
@app.route("/doprediction", methods=['GET','POST'])
def doprediction():
area_income_value = float(request.form['area_income_value'])
area_house_age_value = float(request.form['area_house_age_value'])
area_number_of_rooms_value = float(request.form['area_number_of_rooms_value'])
area_number_of_bedrooms_value = float(request.form['area_number_of_bedrooms_value'])
area_population_value = float(request.form["area_population_value"])
trainedModel = FileUtil.loadmodel('housingmodel_2024-07-15_13-30-34.zip')
result = trainedModel.predict([[area_income_value,
area_house_age_value,
area_number_of_rooms_value,
area_number_of_bedrooms_value,
area_population_value]])
return f"{result[0]}"
Bạn xem Logic xử lý Tui vẽ sơ lược:
Chương trình xử lý theo 4 bước như trên khi người dùng bắt đầu nhấn nút Prediction.
Như vậy tổng hợp ta có mã lệnh “app.py” như sau:
from flask import Flask, render_template, request
from FileUtil import FileUtil
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
@app.route("/")
def main():
return render_template("index.html")
@app.route("/doprediction", methods=['GET','POST'])
def doprediction():
area_income_value = float(request.form['area_income_value'])
area_house_age_value = float(request.form['area_house_age_value'])
area_number_of_rooms_value = float(request.form['area_number_of_rooms_value'])
area_number_of_bedrooms_value = float(request.form['area_number_of_bedrooms_value'])
area_population_value = float(request.form["area_population_value"])
trainedModel = FileUtil.loadmodel('housingmodel_2024-07-15_13-30-34.zip')
result = trainedModel.predict([[area_income_value,
area_house_age_value,
area_number_of_rooms_value,
area_number_of_bedrooms_value,
area_population_value]])
return f"{result[0]}"
if __name__ == "__main__":
app.run(host="localhost", port=9500, debug=True)
Như vậy Tui đã trình bày xong cách thiết kế giao diện Website, tích hợp mô hình máy học để dự báo giá nhà. Các bạn đã biết cách tái sử dụng mô hình máy học trong dự án, có kiến thức về HTML, CSS, Javascript và Python Flask Microservice.
Coding đầy đủ của dự án ở đây:
https://www.mediafire.com/file/z4mjepwkwzfxdjt/Web_HousePricePrediction.rar/file
Bài học sau Tui sẽ hướng dẫn các bài liên quan tới hệ quản trị cơ sở dữ liệu MySQL để quản trị dữ liệu, và phục vụ cho xử lý mô hình máy học, viết các dự án liên quan tới thống kê và máy học.
Chúc các bạn thành công