vanhai123 commited on
Commit
e2e9623
·
verified ·
1 Parent(s): 7976372

Upload 7 files

Browse files
Files changed (7) hide show
  1. README.md +110 -13
  2. app.py +35 -0
  3. model_spam_v1.pkl +3 -0
  4. model_spam_v2.pkl +3 -0
  5. model_spam_v3.pkl +3 -0
  6. requirements.txt +3 -0
  7. train_spam_model.py +31 -0
README.md CHANGED
@@ -1,13 +1,110 @@
1
- ---
2
- title: Spam Mlflow Registry Demo
3
- emoji: 👀
4
- colorFrom: pink
5
- colorTo: red
6
- sdk: gradio
7
- sdk_version: 5.31.0
8
- app_file: app.py
9
- pinned: false
10
- license: openrail
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📩 SMS Spam Classifier with MLflow Model Versioning
2
+
3
+ Đây là một demo triển khai mô hình phân loại tin nhắn rác (spam) sử dụng **Gradio** và **MLflow Model Registry**, với khả năng chọn phiên bản mô hình để phục vụ.
4
+
5
+ ---
6
+
7
+ ## 🚀 Mục tiêu
8
+
9
+ * Áp dụng kiến thức về **MLflow Model Versioning**
10
+ * So sánh các mô hình huấn luyện khác nhau (nhiều version)
11
+ * Triển khai online miễn phí bằng Hugging Face Spaces
12
+
13
+ ---
14
+
15
+ ## 📦 Dataset
16
+
17
+ Dữ liệu được sử dụng là **SMS Spam Collection Dataset**, bao gồm hơn 5.000 tin nhắn đã được phân loại sẵn là `ham` (hợp lệ) hoặc `spam`.
18
+
19
+ ---
20
+
21
+ ## 🧐 Mô hình
22
+
23
+ Các phiên bản được huấn luyện với pipeline gồm:
24
+
25
+ * `TfidfVectorizer`: để chuyển văn bản thành vector đặc trưng
26
+ * `Multinomial Naive Bayes`: mô hình phân loại đơn giản nhưng hiệu quả
27
+
28
+ Các version chỉ khác nhau về giá trị `alpha` (tham số làm trơn trong Naive Bayes):
29
+
30
+ * `model_spam_v1.pkl`: alpha = 1.0
31
+ * `model_spam_v2.pkl`: alpha = 0.5
32
+ * `model_spam_v3.pkl`: alpha = 0.3
33
+
34
+ ---
35
+
36
+ ## 🧪 Hướng dẫn sử dụng
37
+
38
+ 1. Nhập nội dung tin nhắn cần phân loại
39
+ 2. Chọn phiên bản mô hình (v1, v2, hoặc v3)
40
+ 3. Nhấn **Dự đoán**
41
+ 4. Ứng dụng sẽ trả về kết quả: `Spam ❌` hoặc `Ham ✅` và độ tin cậy
42
+
43
+ ---
44
+
45
+ ## 📌 Công nghệ sử dụng
46
+
47
+ * 🦍 Python
48
+ * 📊 Scikit-learn
49
+ * 📦 MLflow (log model & versioning)
50
+ * 🎨 Gradio (UI)
51
+ * ☁️ Hugging Face Spaces (hosting)
52
+
53
+ ---
54
+
55
+ ## 💻 Chạy offline trên máy local
56
+
57
+ Nếu bạn muốn chạy ứng dụng trên máy cá nhân, làm theo các bước sau:
58
+
59
+ ### 🔧 1. Tạo môi trường ảo (virtual environment)
60
+
61
+ **Windows:**
62
+
63
+ ```bash
64
+ python -m venv .venv
65
+ .venv\Scripts\activate
66
+ ```
67
+
68
+ **macOS/Linux:**
69
+
70
+ ```bash
71
+ python3 -m venv .venv
72
+ source .venv/bin/activate
73
+ ```
74
+
75
+ ---
76
+
77
+ ### 📦 2. Cài đặt thư viện
78
+
79
+ ```bash
80
+ pip install -r requirements.txt
81
+ ```
82
+
83
+ ---
84
+
85
+ ### ▶️ 3. Chạy ứng dụng Gradio
86
+
87
+ ```bash
88
+ python app.py
89
+ ```
90
+
91
+ Ứng dụng sẽ chạy tại địa chỉ: [http://localhost:7860](http://localhost:7860)
92
+
93
+ ---
94
+
95
+ ### 📁 Cấu trúc thư mục mẫu
96
+
97
+ ```
98
+ mlflow-spam-classifier/
99
+ ├── app.py
100
+ ├── requirements.txt
101
+ ├── model_spam_v1.pkl
102
+ ├── model_spam_v2.pkl
103
+ ├── model_spam_v3.pkl
104
+ ├── README.md
105
+ └── train_spam_model.py (tuỳ chọn)
106
+ ```
107
+
108
+ ---
109
+
110
+ ✅ Sau khi chạy xong, bạn có thể nhập nội dung tin nhắn và chọn phiên bản mô hình để dự đoán trực tiếp mà không cần kết nối Internet.
app.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import joblib
3
+
4
+ # Load các mô hình đã export từ MLflow
5
+ models = {
6
+ "1": joblib.load("model_spam_v1.pkl"),
7
+ "2": joblib.load("model_spam_v2.pkl"),
8
+ "3": joblib.load("model_spam_v3.pkl"),
9
+ }
10
+
11
+ # Hàm dự đoán
12
+ def predict_spam(text, version):
13
+ model = models[version]
14
+ pred = model.predict([text])[0]
15
+ prob = model.predict_proba([text])[0][pred]
16
+ result = "Spam ❌" if pred == 1 else "Ham ✅"
17
+ return f"{result} (Độ tin cậy: {prob:.2%})"
18
+
19
+ # Giao diện Gradio
20
+ with gr.Blocks(title="SMS Spam Classifier - MLflow Versioning Demo") as demo:
21
+ gr.Markdown("## 📩 SMS Spam Classifier")
22
+ gr.Markdown("🔢 **Chọn phiên bản mô hình (MLflow Registry)** để phân loại tin nhắn.")
23
+
24
+ with gr.Row():
25
+ with gr.Column():
26
+ message_input = gr.Textbox(label="✉️ Nội dung tin nhắn", placeholder="Nhập tin nhắn cần kiểm tra...")
27
+ version_input = gr.Radio(choices=["1", "2", "3"], label="📦 Chọn version mô hình", value="1")
28
+ submit_btn = gr.Button("📤 Dự đoán")
29
+
30
+ with gr.Column():
31
+ result_output = gr.Textbox(label="📌 Kết quả", interactive=False)
32
+
33
+ submit_btn.click(fn=predict_spam, inputs=[message_input, version_input], outputs=result_output)
34
+
35
+ demo.launch()
model_spam_v1.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b021280edfe769c9ca4b3dfc9ee9bab226feb1a2d61e125dcb8720e50e1960d3
3
+ size 466574
model_spam_v2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ed5feee17e3179500cb928abb1d185338eed53607c1c794afc954d1671b9ba28
3
+ size 466574
model_spam_v3.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c98f998afd9f3b4f6b4c8ec7f668b16f074752b700fe379dbd036b185bf3d3b
3
+ size 466574
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ scikit-learn
3
+ joblib
train_spam_model.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import mlflow
3
+ import mlflow.sklearn
4
+ from sklearn.feature_extraction.text import TfidfVectorizer
5
+ from sklearn.naive_bayes import MultinomialNB
6
+ from sklearn.pipeline import Pipeline
7
+ from sklearn.model_selection import train_test_split
8
+ from sklearn.metrics import accuracy_score
9
+
10
+ # Load dữ liệu
11
+ df = pd.read_csv("https://www.kaggle.com/datasets/uciml/sms-spam-collection-dataset/spam.csv", encoding='latin-1')[['v1', 'v2']]
12
+ df.columns = ['label', 'text']
13
+ df['label'] = df['label'].map({'ham': 0, 'spam': 1})
14
+
15
+ X_train, X_test, y_train, y_test = train_test_split(df['text'], df['label'], test_size=0.2, random_state=42)
16
+
17
+ # Pipeline gồm TF-IDF + Naive Bayes
18
+ pipeline = Pipeline([
19
+ ('tfidf', TfidfVectorizer()),
20
+ ('clf', MultinomialNB(alpha=1.0)) # bạn có thể thay đổi alpha để tạo version mới
21
+ ])
22
+
23
+ pipeline.fit(X_train, y_train)
24
+ y_pred = pipeline.predict(X_test)
25
+ acc = accuracy_score(y_test, y_pred)
26
+
27
+ with mlflow.start_run():
28
+ mlflow.log_param("alpha", 1.0)
29
+ mlflow.log_metric("accuracy", acc)
30
+ mlflow.sklearn.log_model(pipeline, "model", registered_model_name="SpamClassifier")
31
+ print(f"Logged model with acc={acc}")