# Xây dựng ứng dụng web sử dụng mô hình ML Trong bài học này, bạn sẽ huấn luyện một mô hình ML trên một tập dữ liệu đặc biệt: _Các lần nhìn thấy UFO trong thế kỷ qua_, được lấy từ cơ sở dữ liệu của NUFORC. Bạn sẽ học: - Cách 'pickle' một mô hình đã được huấn luyện - Cách sử dụng mô hình đó trong một ứng dụng Flask Chúng ta sẽ tiếp tục sử dụng notebook để làm sạch dữ liệu và huấn luyện mô hình, nhưng bạn có thể tiến thêm một bước bằng cách khám phá cách sử dụng mô hình trong thực tế, cụ thể là trong một ứng dụng web. Để làm điều này, bạn cần xây dựng một ứng dụng web sử dụng Flask. ## [Quiz trước bài học](https://ff-quizzes.netlify.app/en/ml/) ## Xây dựng ứng dụng Có nhiều cách để xây dựng ứng dụng web sử dụng mô hình học máy. Kiến trúc web của bạn có thể ảnh hưởng đến cách mô hình được huấn luyện. Hãy tưởng tượng bạn đang làm việc trong một doanh nghiệp nơi nhóm khoa học dữ liệu đã huấn luyện một mô hình mà họ muốn bạn sử dụng trong ứng dụng. ### Những điều cần cân nhắc Có nhiều câu hỏi bạn cần đặt ra: - **Đó là ứng dụng web hay ứng dụng di động?** Nếu bạn đang xây dựng một ứng dụng di động hoặc cần sử dụng mô hình trong ngữ cảnh IoT, bạn có thể sử dụng [TensorFlow Lite](https://www.tensorflow.org/lite/) và tích hợp mô hình vào ứng dụng Android hoặc iOS. - **Mô hình sẽ được lưu trữ ở đâu?** Trên đám mây hay cục bộ? - **Hỗ trợ ngoại tuyến.** Ứng dụng có cần hoạt động ngoại tuyến không? - **Công nghệ nào được sử dụng để huấn luyện mô hình?** Công nghệ được chọn có thể ảnh hưởng đến công cụ bạn cần sử dụng. - **Sử dụng TensorFlow.** Nếu bạn huấn luyện mô hình bằng TensorFlow, ví dụ, hệ sinh thái này cung cấp khả năng chuyển đổi mô hình TensorFlow để sử dụng trong ứng dụng web bằng cách sử dụng [TensorFlow.js](https://www.tensorflow.org/js/). - **Sử dụng PyTorch.** Nếu bạn xây dựng mô hình bằng thư viện như [PyTorch](https://pytorch.org/), bạn có tùy chọn xuất mô hình ở định dạng [ONNX](https://onnx.ai/) (Open Neural Network Exchange) để sử dụng trong các ứng dụng web JavaScript có thể sử dụng [Onnx Runtime](https://www.onnxruntime.ai/). Tùy chọn này sẽ được khám phá trong bài học tương lai với mô hình được huấn luyện bằng Scikit-learn. - **Sử dụng Lobe.ai hoặc Azure Custom Vision.** Nếu bạn sử dụng hệ thống ML SaaS (Phần mềm như một dịch vụ) như [Lobe.ai](https://lobe.ai/) hoặc [Azure Custom Vision](https://azure.microsoft.com/services/cognitive-services/custom-vision-service/?WT.mc_id=academic-77952-leestott) để huấn luyện mô hình, loại phần mềm này cung cấp cách xuất mô hình cho nhiều nền tảng, bao gồm xây dựng API tùy chỉnh để truy vấn trên đám mây bởi ứng dụng trực tuyến của bạn. Bạn cũng có cơ hội xây dựng toàn bộ ứng dụng web Flask có thể tự huấn luyện mô hình ngay trong trình duyệt web. Điều này cũng có thể được thực hiện bằng cách sử dụng TensorFlow.js trong ngữ cảnh JavaScript. Đối với mục đích của chúng ta, vì chúng ta đã làm việc với notebook dựa trên Python, hãy khám phá các bước bạn cần thực hiện để xuất một mô hình đã huấn luyện từ notebook sang định dạng có thể đọc được bởi ứng dụng web xây dựng bằng Python. ## Công cụ Để thực hiện nhiệm vụ này, bạn cần hai công cụ: Flask và Pickle, cả hai đều chạy trên Python. ✅ [Flask](https://palletsprojects.com/p/flask/) là gì? Được định nghĩa là 'micro-framework' bởi các nhà sáng tạo, Flask cung cấp các tính năng cơ bản của framework web sử dụng Python và một công cụ tạo mẫu để xây dựng trang web. Hãy xem [module học này](https://docs.microsoft.com/learn/modules/python-flask-build-ai-web-app?WT.mc_id=academic-77952-leestott) để thực hành xây dựng với Flask. ✅ [Pickle](https://docs.python.org/3/library/pickle.html) là gì? Pickle 🥒 là một module Python dùng để tuần tự hóa và giải tuần tự hóa cấu trúc đối tượng Python. Khi bạn 'pickle' một mô hình, bạn tuần tự hóa hoặc làm phẳng cấu trúc của nó để sử dụng trên web. Hãy cẩn thận: pickle không an toàn về bản chất, vì vậy hãy cẩn thận nếu được yêu cầu 'un-pickle' một tệp. Một tệp pickled có hậu tố `.pkl`. ## Bài tập - làm sạch dữ liệu Trong bài học này, bạn sẽ sử dụng dữ liệu từ 80,000 lần nhìn thấy UFO, được thu thập bởi [NUFORC](https://nuforc.org) (Trung tâm Báo cáo UFO Quốc gia). Dữ liệu này có một số mô tả thú vị về các lần nhìn thấy UFO, ví dụ: - **Mô tả dài.** "Một người đàn ông xuất hiện từ một tia sáng chiếu xuống một cánh đồng cỏ vào ban đêm và chạy về phía bãi đậu xe của Texas Instruments". - **Mô tả ngắn.** "những ánh sáng đuổi theo chúng tôi". Bảng tính [ufos.csv](../../../../3-Web-App/1-Web-App/data/ufos.csv) bao gồm các cột về `city`, `state` và `country` nơi xảy ra lần nhìn thấy, hình dạng của vật thể (`shape`) và `latitude` và `longitude`. Trong [notebook](../../../../3-Web-App/1-Web-App/notebook.ipynb) trống được bao gồm trong bài học này: 1. import `pandas`, `matplotlib`, và `numpy` như bạn đã làm trong các bài học trước và import bảng tính ufos. Bạn có thể xem một mẫu tập dữ liệu: ```python import pandas as pd import numpy as np ufos = pd.read_csv('./data/ufos.csv') ufos.head() ``` 1. Chuyển đổi dữ liệu ufos thành một dataframe nhỏ với tiêu đề mới. Kiểm tra các giá trị duy nhất trong trường `Country`. ```python ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']}) ufos.Country.unique() ``` 1. Bây giờ, bạn có thể giảm lượng dữ liệu cần xử lý bằng cách loại bỏ các giá trị null và chỉ import các lần nhìn thấy trong khoảng từ 1-60 giây: ```python ufos.dropna(inplace=True) ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)] ufos.info() ``` 1. Import thư viện `LabelEncoder` của Scikit-learn để chuyển đổi các giá trị văn bản của quốc gia thành số: ✅ LabelEncoder mã hóa dữ liệu theo thứ tự bảng chữ cái ```python from sklearn.preprocessing import LabelEncoder ufos['Country'] = LabelEncoder().fit_transform(ufos['Country']) ufos.head() ``` Dữ liệu của bạn sẽ trông như thế này: ```output Seconds Country Latitude Longitude 2 20.0 3 53.200000 -2.916667 3 20.0 4 28.978333 -96.645833 14 30.0 4 35.823889 -80.253611 23 60.0 4 45.582778 -122.352222 24 3.0 3 51.783333 -0.783333 ``` ## Bài tập - xây dựng mô hình Bây giờ bạn có thể chuẩn bị huấn luyện mô hình bằng cách chia dữ liệu thành nhóm huấn luyện và kiểm tra. 1. Chọn ba đặc trưng bạn muốn huấn luyện làm vector X, và vector y sẽ là `Country`. Bạn muốn có thể nhập `Seconds`, `Latitude` và `Longitude` và nhận được mã quốc gia để trả về. ```python from sklearn.model_selection import train_test_split Selected_features = ['Seconds','Latitude','Longitude'] X = ufos[Selected_features] y = ufos['Country'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) ``` 1. Huấn luyện mô hình của bạn bằng logistic regression: ```python from sklearn.metrics import accuracy_score, classification_report from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X_train, y_train) predictions = model.predict(X_test) print(classification_report(y_test, predictions)) print('Predicted labels: ', predictions) print('Accuracy: ', accuracy_score(y_test, predictions)) ``` Độ chính xác không tệ **(khoảng 95%)**, không có gì ngạc nhiên, vì `Country` và `Latitude/Longitude` có mối tương quan. Mô hình bạn tạo ra không quá đột phá vì bạn có thể suy luận một `Country` từ `Latitude` và `Longitude`, nhưng đây là một bài tập tốt để thử huấn luyện từ dữ liệu thô mà bạn đã làm sạch, xuất ra, và sau đó sử dụng mô hình này trong một ứng dụng web. ## Bài tập - 'pickle' mô hình của bạn Bây giờ, đã đến lúc _pickle_ mô hình của bạn! Bạn có thể làm điều đó chỉ trong vài dòng mã. Sau khi _pickled_, tải mô hình đã pickled và kiểm tra nó với một mảng dữ liệu mẫu chứa các giá trị cho seconds, latitude và longitude, ```python import pickle model_filename = 'ufo-model.pkl' pickle.dump(model, open(model_filename,'wb')) model = pickle.load(open('ufo-model.pkl','rb')) print(model.predict([[50,44,-12]])) ``` Mô hình trả về **'3'**, là mã quốc gia của Vương quốc Anh. Thật thú vị! 👽 ## Bài tập - xây dựng ứng dụng Flask Bây giờ bạn có thể xây dựng một ứng dụng Flask để gọi mô hình của bạn và trả về kết quả tương tự, nhưng theo cách trực quan hơn. 1. Bắt đầu bằng cách tạo một thư mục tên **web-app** bên cạnh tệp _notebook.ipynb_ nơi tệp _ufo-model.pkl_ của bạn nằm. 1. Trong thư mục đó, tạo thêm ba thư mục: **static**, với một thư mục **css** bên trong, và **templates**. Bạn sẽ có các tệp và thư mục sau: ```output web-app/ static/ css/ templates/ notebook.ipynb ufo-model.pkl ``` ✅ Tham khảo thư mục giải pháp để xem ứng dụng hoàn chỉnh 1. Tệp đầu tiên cần tạo trong thư mục _web-app_ là tệp **requirements.txt**. Giống như _package.json_ trong ứng dụng JavaScript, tệp này liệt kê các phụ thuộc cần thiết cho ứng dụng. Trong **requirements.txt** thêm các dòng: ```text scikit-learn pandas numpy flask ``` 1. Bây giờ, chạy tệp này bằng cách điều hướng đến _web-app_: ```bash cd web-app ``` 1. Trong terminal của bạn, gõ `pip install`, để cài đặt các thư viện được liệt kê trong _requirements.txt_: ```bash pip install -r requirements.txt ``` 1. Bây giờ, bạn đã sẵn sàng tạo thêm ba tệp để hoàn thành ứng dụng: 1. Tạo **app.py** trong thư mục gốc. 2. Tạo **index.html** trong thư mục _templates_. 3. Tạo **styles.css** trong thư mục _static/css_. 1. Xây dựng tệp _styles.css_ với một vài kiểu: ```css body { width: 100%; height: 100%; font-family: 'Helvetica'; background: black; color: #fff; text-align: center; letter-spacing: 1.4px; font-size: 30px; } input { min-width: 150px; } .grid { width: 300px; border: 1px solid #2d2d2d; display: grid; justify-content: center; margin: 20px auto; } .box { color: #fff; background: #2d2d2d; padding: 12px; display: inline-block; } ``` 1. Tiếp theo, xây dựng tệp _index.html_: ```html
According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?
{{ prediction_text }}