vanhai123 commited on
Commit
5c211c8
·
verified ·
1 Parent(s): cca02aa

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +87 -14
  2. app.py +218 -0
  3. requirements.txt +4 -0
README.md CHANGED
@@ -1,14 +1,87 @@
1
- ---
2
- title: Vietnamese News Topic Classifier
3
- emoji: 🐢
4
- colorFrom: red
5
- colorTo: yellow
6
- sdk: gradio
7
- sdk_version: 5.32.1
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- short_description: Vietnamese news topic classification using Logistic Regressi
12
- ---
13
-
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Vietnamese News Topic Classifier
3
+ emoji: 📰
4
+ colorFrom: indigo
5
+ colorTo: pink
6
+ sdk: gradio
7
+ app_file: app.py
8
+ license: other
9
+ tags:
10
+ - text-classification
11
+ - vietnamese
12
+ - news
13
+ - logistic-regression
14
+ - scikit-learn
15
+ - tf-idf
16
+ - gradio
17
+ model:
18
+ - vanhai123/Vietnamese-news-classifier-model
19
+ ---
20
+
21
+ # 📰 Vietnamese News Topic Classifier
22
+
23
+ 🔎 Dự đoán chủ đề của đoạn tin tức tiếng Việt bằng mô hình **Logistic Regression + TF-IDF**.
24
+ Ứng dụng này được huấn luyện trên dữ liệu tiêu đề tin tức thuộc 5 chủ đề:
25
+
26
+ - 📘 **Giáo dục**
27
+ - ⚽ **Thể thao**
28
+ - 🎬 **Giải trí**
29
+ - 💻 **Công nghệ**
30
+ - 🏛️ **Chính trị**
31
+
32
+ ---
33
+
34
+ ## 🛠 Mô hình
35
+
36
+ - ✅ Logistic Regression (scikit-learn)
37
+ - ✅ TF-IDF Vectorizer
38
+ - ✅ Train bằng Python (sklearn), lưu bằng joblib
39
+ - ✅ Mô hình được lưu trữ tại: [vanhai123/Vietnamese-news-classifier-model](https://huggingface.co/vanhai123/Vietnamese-news-classifier-model)
40
+
41
+ ---
42
+
43
+ ## 🚀 Cách hoạt động
44
+
45
+ 1. Người dùng nhập đoạn văn bản tiếng Việt (ví dụ: tiêu đề bài báo)
46
+ 2. Văn bản được tiền xử lý (`lowercase`)
47
+ 3. Vector hóa bằng TF-IDF
48
+ 4. Dự đoán nhãn bằng Logistic Regression
49
+ 5. Trả về tên chủ đề phù hợp
50
+
51
+ ---
52
+
53
+ ## 📦 Công nghệ sử dụng
54
+
55
+ - `gradio` cho giao diện demo
56
+ - `scikit-learn` cho mô hình học máy
57
+ - `huggingface_hub` để tải mô hình từ repo
58
+
59
+ ---
60
+
61
+ ## 📚 Cách huấn luyện mô hình (tham khảo)
62
+
63
+ Bạn có thể xem mã nguồn huấn luyện tại GitHub repo:
64
+ 👉 [https://github.com/vanhai123/gginhir-news-classifier](https://github.com/vanhai123/gginhir-news-classifier)
65
+
66
+ ---
67
+
68
+ ## ✨ Demo
69
+
70
+ Hãy thử nhập:
71
+ - `"Học sinh được miễn học phí từ năm học mới"`
72
+ - `"Apple ra mắt mẫu MacBook mới dùng chip AI"`
73
+ - `"Đội tuyển Việt Nam chiến thắng thuyết phục"`
74
+
75
+ ---
76
+
77
+ ## 👤 Tác giả
78
+
79
+ **vanhai123**
80
+ - Hugging Face: [https://huggingface.co/vanhai123](https://huggingface.co/vanhai123)
81
+ - GitHub: [https://github.com/vanhai1231](https://github.com/vanhai1231)
82
+
83
+ ---
84
+
85
+ ## 📄 Giấy phép
86
+
87
+ Chỉ sử dụng cho mục đích học tập và nghiên cứu.
app.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import joblib
3
+ from huggingface_hub import hf_hub_download
4
+ import time
5
+ import random
6
+
7
+ # Tải mô hình và vectorizer từ Hugging Face Hub
8
+ model_path = hf_hub_download(repo_id="vanhai123/Vietnamese-news-classifier-model", filename="saved_model.pkl")
9
+ vectorizer_path = hf_hub_download(repo_id="vanhai123/Vietnamese-news-classifier-model", filename="vectorizer.pkl")
10
+
11
+ model = joblib.load(model_path)
12
+ vectorizer = joblib.load(vectorizer_path)
13
+
14
+ # Mapping chủ đề với icon và màu sắc
15
+ TOPIC_INFO = {
16
+ "giáo dục": {"icon": "🎓", "color": "#4CAF50", "desc": "Tin tức về giáo dục, đào tạo"},
17
+ "công nghệ": {"icon": "💻", "color": "#2196F3", "desc": "Công nghệ thông tin, khoa học"},
18
+ "thể thao": {"icon": "⚽", "color": "#FF5722", "desc": "Thể thao, thể dục thể thao"},
19
+ "giải trí": {"icon": "🎬", "color": "#E91E63", "desc": "Giải trí, văn hóa, nghệ thuật"},
20
+ "chính trị": {"icon": "🏛️", "color": "#9C27B0", "desc": "Chính trị, xã hội, pháp luật"}
21
+ }
22
+
23
+ def predict_topic_enhanced(text):
24
+ if not text.strip():
25
+ return "⚠️ Vui lòng nhập nội dung tin tức để phân tích!", "", ""
26
+
27
+ # Simulate processing time for better UX
28
+ time.sleep(0.5)
29
+
30
+ text_clean = text.lower()
31
+ vec = vectorizer.transform([text_clean])
32
+ prediction = model.predict(vec)[0]
33
+ confidence = model.predict_proba(vec)[0]
34
+ max_confidence = max(confidence) * 100
35
+
36
+ # Get topic info
37
+ topic_info = TOPIC_INFO.get(prediction, {"icon": "📰", "color": "#757575", "desc": "Chủ đề khác"})
38
+
39
+ # Create result with enhanced formatting
40
+ result = f"""
41
+ <div style="text-align: center; padding: 20px; border-radius: 10px; background: linear-gradient(135deg, {topic_info['color']}20, {topic_info['color']}10);">
42
+ <h2 style="color: {topic_info['color']}; margin: 0;">
43
+ {topic_info['icon']} {prediction.upper()}
44
+ </h2>
45
+ <p style="color: #666; margin: 10px 0; font-style: italic;">{topic_info['desc']}</p>
46
+ <div style="background: white; padding: 10px; border-radius: 5px; margin: 10px 0;">
47
+ <strong>Độ tin cậy:</strong> <span style="color: {topic_info['color']};">{max_confidence:.1f}%</span>
48
+ </div>
49
+ </div>
50
+ """
51
+
52
+ # Create confidence chart data
53
+ all_topics = list(TOPIC_INFO.keys())
54
+ confidence_data = []
55
+ for i, topic in enumerate(all_topics):
56
+ conf_score = confidence[i] * 100
57
+ confidence_data.append([topic.title(), conf_score])
58
+
59
+ return result, confidence_data, f"Đã phân tích {len(text.split())} từ"
60
+
61
+ def get_example_texts():
62
+ examples = [
63
+ "Bộ Giáo dục và Đào tạo vừa công bố chương trình giáo dục phổ thông mới với nhiều thay đổi quan trọng.",
64
+ "Apple vừa ra mắt iPhone mới với công nghệ chip A17 Pro và camera cải tiến đáng kể.",
65
+ "Đội tuyển Việt Nam đã giành chiến thắng 2-1 trước đội khách trong trận đấu tối qua.",
66
+ "Bộ phim điện ảnh mới của đạo diễn nổi tiếng sẽ được công chiếu vào tháng tới.",
67
+ "Quốc hội đã thông qua dự luật mới về bảo vệ môi trường với 90% phiếu thuận."
68
+ ]
69
+ return random.choice(examples)
70
+
71
+ # Custom CSS để làm đẹp giao diện
72
+ custom_css = """
73
+ .gradio-container {
74
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
75
+ }
76
+ .main-header {
77
+ text-align: center;
78
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
79
+ color: white;
80
+ padding: 30px;
81
+ border-radius: 15px;
82
+ margin-bottom: 20px;
83
+ }
84
+ .feature-box {
85
+ background: #f8f9fa;
86
+ padding: 15px;
87
+ border-radius: 10px;
88
+ border-left: 4px solid #007bff;
89
+ margin: 10px 0;
90
+ }
91
+ .stats-container {
92
+ display: flex;
93
+ justify-content: space-around;
94
+ margin: 20px 0;
95
+ }
96
+ .stat-item {
97
+ text-align: center;
98
+ padding: 15px;
99
+ background: white;
100
+ border-radius: 10px;
101
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
102
+ }
103
+ """
104
+
105
+ with gr.Blocks(css=custom_css, title="Vietnamese News Classifier", theme=gr.themes.Soft()) as interface:
106
+
107
+ # Header
108
+ gr.HTML("""
109
+ <div class="main-header">
110
+ <h1>📰 Vietnamese News Topic Classifier</h1>
111
+ <p>Phân loại chủ đề tin tức tiếng Việt bằng AI</p>
112
+ <p><em>Hỗ trợ 5 chủ đề: Giáo dục • Công nghệ • Thể thao • Giải trí • Chính trị</em></p>
113
+ </div>
114
+ """)
115
+
116
+ with gr.Row():
117
+ with gr.Column(scale=2):
118
+ # Input section
119
+ gr.Markdown("### 📝 Nhập nội dung tin tức")
120
+ input_text = gr.Textbox(
121
+ label="Nội dung tin tức",
122
+ placeholder="Nhập đoạn tin tức tiếng Việt tại ��ây...",
123
+ lines=6,
124
+ max_lines=10
125
+ )
126
+
127
+ with gr.Row():
128
+ predict_btn = gr.Button("🔍 Phân tích chủ đề", variant="primary", size="lg")
129
+ example_btn = gr.Button("📋 Lấy ví dụ", variant="secondary")
130
+ clear_btn = gr.Button("🗑️ Xóa", variant="stop")
131
+
132
+ with gr.Column(scale=1):
133
+ # Info panel
134
+ gr.Markdown("### ℹ️ Thông tin mô hình")
135
+ gr.HTML("""
136
+ <div class="feature-box">
137
+ <strong>🤖 Thuật toán:</strong> TF-IDF + Logistic Regression<br>
138
+ <strong>📊 Độ chính xác:</strong> ~85-90%<br>
139
+ <strong>⚡ Thời gian xử lý:</strong> < 1 giây<br>
140
+ <strong>🗣️ Ngôn ngữ:</strong> Tiếng Việt
141
+ </div>
142
+ """)
143
+
144
+ # Results section
145
+ gr.Markdown("### 📊 Kết quả phân tích")
146
+
147
+ with gr.Row():
148
+ with gr.Column(scale=2):
149
+ result_output = gr.HTML(label="Kết quả dự đoán")
150
+
151
+ with gr.Column(scale=1):
152
+ stats_output = gr.Textbox(label="Thống kê", interactive=False)
153
+
154
+ # Confidence chart
155
+ confidence_plot = gr.BarPlot(
156
+ x="topic",
157
+ y="confidence",
158
+ title="Độ tin cậy theo từng chủ đề (%)",
159
+ x_title="Chủ đề",
160
+ y_title="Độ tin cậy (%)",
161
+ height=300
162
+ )
163
+
164
+ # Examples section
165
+ gr.Markdown("### 💡 Ví dụ các chủ đề")
166
+ with gr.Row():
167
+ for topic, info in TOPIC_INFO.items():
168
+ gr.HTML(f"""
169
+ <div style="text-align: center; padding: 15px; margin: 5px; border-radius: 10px;
170
+ background: {info['color']}20; border: 2px solid {info['color']}50;">
171
+ <div style="font-size: 24px;">{info['icon']}</div>
172
+ <strong style="color: {info['color']};">{topic.upper()}</strong>
173
+ <br><small>{info['desc']}</small>
174
+ </div>
175
+ """)
176
+
177
+ # Event handlers
178
+ predict_btn.click(
179
+ fn=predict_topic_enhanced,
180
+ inputs=[input_text],
181
+ outputs=[result_output, confidence_plot, stats_output]
182
+ )
183
+
184
+ example_btn.click(
185
+ fn=get_example_texts,
186
+ outputs=[input_text]
187
+ )
188
+
189
+ clear_btn.click(
190
+ fn=lambda: ("", "", "", None),
191
+ outputs=[input_text, result_output, stats_output, confidence_plot]
192
+ )
193
+
194
+ # Auto-predict on text change (with debounce)
195
+ input_text.change(
196
+ fn=predict_topic_enhanced,
197
+ inputs=[input_text],
198
+ outputs=[result_output, confidence_plot, stats_output],
199
+ trigger_mode="on_change"
200
+ )
201
+
202
+ # Footer
203
+ gr.HTML("""
204
+ <div style="text-align: center; padding: 20px; margin-top: 30px;
205
+ background: #f8f9fa; border-radius: 10px;">
206
+ <p><strong>🚀 Powered by Hugging Face & Gradio</strong></p>
207
+ <p><em>Mô hình được huấn luyện trên dữ liệu tin tức tiếng Việt</em></p>
208
+ </div>
209
+ """)
210
+
211
+ if __name__ == "__main__":
212
+ interface.launch(
213
+ share=True,
214
+ server_name="0.0.0.0",
215
+ server_port=7860,
216
+ show_api=False,
217
+ favicon_path=None
218
+ )
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio
2
+ scikit-learn
3
+ joblib
4
+ huggingface_hub