Nolist commited on
Commit
0ad16a6
·
verified ·
1 Parent(s): dfee9a8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -39
app.py CHANGED
@@ -3,38 +3,14 @@ import joblib
3
  import pandas as pd
4
  import re
5
  import nltk
 
 
6
  import os
7
- from sklearn.base import BaseEstimator, TransformerMixin # Cần import này cho TextCleaner
8
 
9
  # --- CẤU HÌNH TRANG STREAMLIT (PHẢI LÀ LỆNH STREAMLIT ĐẦU TIÊN) ---
10
  st.set_page_config(page_title="Phân biệt Tin tức Thật/Giả", layout="centered")
11
 
12
- # --- Định nghĩa lớp Custom Transformer cho việc làm sạch văn bản ---
13
- # Lớp này PHẢI CHÍNH XÁC giống hệt như lớp bạn đã dùng khi huấn luyện mô hình
14
- # và lưu file fake_news_model.pkl.
15
- class TextCleaner(BaseEstimator, TransformerMixin):
16
- def fit(self, X, y=None):
17
- return self
18
-
19
- def transform(self, X: pd.Series, y=None):
20
- # Đảm bảo đầu vào là Series để sử dụng các phương thức .str
21
- if not isinstance(X, pd.Series):
22
- X = pd.Series(X)
23
-
24
- return (
25
- X
26
- .str.replace(r'<[^>]+>', ' ', regex=True)
27
- .str.replace(r'http\S+|\S+@\S+', ' ', regex=True)
28
- .str.replace(r'[^A-Za-z0-9\s]', ' ', regex=True)
29
- .str.lower()
30
- .str.strip()
31
- )
32
-
33
  # --- Cài đặt và tải tài nguyên NLTK (quan trọng cho môi trường Docker) ---
34
- # Đoạn code này đảm bảo NLTK data được tải và có sẵn trong môi trường của Space.
35
- # Nếu bạn đã cấu hình Dockerfile để tải NLTK stopwords trong quá trình build,
36
- # phần này có thể được lược bỏ để giảm thời gian khởi tạo ứng dụng,
37
- # nhưng giữ lại nếu bạn không chắc chắn Dockerfile đã lo việc tải.
38
  nltk_data_path = os.path.join(os.path.dirname(__file__), 'nltk_data')
39
  os.makedirs(os.path.join(nltk_data_path, 'corpora'), exist_ok=True)
40
  nltk.data.path.append(nltk_data_path)
@@ -43,25 +19,40 @@ try:
43
  if not os.path.exists(os.path.join(nltk_data_path, 'corpora', 'stopwords')):
44
  nltk.download('stopwords', download_dir=nltk_data_path)
45
  except Exception as e:
46
- st.error(f"Lỗi khi tải NLTK stopwords: {e}. Vui lòng kiểm tra kết nối hoặc cấu hình Dockerfile.")
47
  st.stop()
48
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  # --- Tải mô hình ---
51
- # Phần này cố gắng tải mô hình. Nếu có lỗi, ứng dụng sẽ dừng và hiển thị thông báo.
52
  model = None
53
  try:
54
  model_path = os.path.join(os.path.dirname(__file__), 'fake_news_model.pkl')
55
- # joblib.load() sẽ cần tìm thấy định nghĩa của lớp TextCleaner TRƯỚC khi tải model
56
  model = joblib.load(model_path)
57
- st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
 
58
  except Exception as e:
59
- st.error(f"Lỗi khi tải mô hình: {e}. Vui lòng đảm bảo lớp TextCleaner đã được định nghĩa chính xác và file mô hình nằm đúng vị trí.")
 
60
  st.stop() # Dừng ứng dụng nếu mô hình không tải được
61
 
 
 
 
 
62
 
63
  # --- Giao diện Streamlit ---
64
- # Các lệnh Streamlit khác sẽ bắt đầu từ đây trở đi để tránh lỗi set_page_config()
65
  st.title("📰 Phân biệt Tin tức Thật/Giả")
66
  st.markdown("Sử dụng mô hình AI để phân tích và xác định liệu một tin tức là thật hay giả.")
67
 
@@ -79,27 +70,24 @@ if st.button("Phân tích"):
79
  st.error("Mô hình chưa sẵn sàng để phân tích. Vui lòng kiểm tra lại lỗi tải mô hình.")
80
  else:
81
  with st.spinner("Đang phân tích tin tức..."):
82
- # Chuẩn bị dữ liệu đầu vào dưới dạng DataFrame, giống như X_train khi huấn luyện
83
  input_df = pd.DataFrame({
84
  'Feature_1': [title_input],
85
  'Feature_2': [content_input]
86
  })
87
 
88
  try:
89
- # Thực hiện dự đoán xác suất và nhãn
90
  prediction = model.predict(input_df)[0]
91
  prediction_proba = model.predict_proba(input_df)[0]
92
 
93
- # Lấy xác suất cao nhất mà mô hình gán cho một trong các lớp
94
  confidence = round(max(prediction_proba) * 100, 2)
95
 
96
  # --- ĐIỀU CHỈNH LOGIC DỰ ĐOÁN DỰA TRÊN NGƯỠNG ĐỘ TIN CẬY ---
97
- # Nhãn đã train: 0 là THẬT, 1 là GIẢ
98
  result_label = ""
99
  color = ""
100
  confidence_text = f"Độ tin cậy: **{confidence}%**"
101
 
102
-
103
  if prediction == 1: # Nếu mô hình ban đầu dự đoán là GIẢ (nhãn 1)
104
  if confidence < 90.0: # Và độ tin cậy của dự đoán GIẢ dưới 90%
105
  result_label = "Tin tức CÓ THỂ LÀ THẬT" # Chuyển thành THẬT do tin cậy thấp
@@ -114,11 +102,11 @@ if st.button("Phân tích"):
114
 
115
  st.subheader("Kết quả phân tích:")
116
  st.markdown(f"<h3 style='color:{color};'>{result_label}</h3>", unsafe_allow_html=True)
117
- st.info(confidence_text) # Hiển thị độ tin cậy và ghi chú bổ sung
118
 
119
  except Exception as e:
120
  st.error(f"Đã xảy ra lỗi trong quá trình dự đoán: {e}")
121
- st.exception(e) # Hiển thị chi tiết lỗi để gỡ lỗi
122
 
123
  st.markdown("---")
124
  st.markdown("Ứng dụng này được phát triển để mục đích minh họa và học tập.")
 
3
  import pandas as pd
4
  import re
5
  import nltk
6
+ from nltk.corpus import stopwords # Giữ lại import này theo code của bạn
7
+ from nltk.stem.porter import PorterStemmer # Giữ lại import này theo code của bạn
8
  import os
 
9
 
10
  # --- CẤU HÌNH TRANG STREAMLIT (PHẢI LÀ LỆNH STREAMLIT ĐẦU TIÊN) ---
11
  st.set_page_config(page_title="Phân biệt Tin tức Thật/Giả", layout="centered")
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # --- Cài đặt và tải tài nguyên NLTK (quan trọng cho môi trường Docker) ---
 
 
 
 
14
  nltk_data_path = os.path.join(os.path.dirname(__file__), 'nltk_data')
15
  os.makedirs(os.path.join(nltk_data_path, 'corpora'), exist_ok=True)
16
  nltk.data.path.append(nltk_data_path)
 
19
  if not os.path.exists(os.path.join(nltk_data_path, 'corpora', 'stopwords')):
20
  nltk.download('stopwords', download_dir=nltk_data_path)
21
  except Exception as e:
22
+ st.error(f"Lỗi khi tải NLTK stopwords: {e}")
23
  st.stop()
24
 
25
+ # --- Định nghĩa hàm clean_text CHÍNH XÁC NHƯ TRONG CODE HUẤN LUYỆN ---
26
+ # (Giữ nguyên hàm này theo code bạn cung cấp, mặc dù với mô hình mới nên là TextCleaner class)
27
+ def clean_text(series: pd.Series) -> pd.Series:
28
+ return (
29
+ series
30
+ .str.replace(r'<[^>]+>', ' ', regex=True)
31
+ .str.replace(r'http\S+|\S+@\S+', ' ', regex=True)
32
+ .str.replace(r'[^A-Za-z0-9\s]', ' ', regex=True)
33
+ .str.lower()
34
+ .str.strip()
35
+ )
36
 
37
  # --- Tải mô hình ---
 
38
  model = None
39
  try:
40
  model_path = os.path.join(os.path.dirname(__file__), 'fake_news_model.pkl')
 
41
  model = joblib.load(model_path)
42
+ # Không dùng st.success/st.error ở đây nữa, vì chúng phải được gọi sau set_page_config
43
+ # st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
44
  except Exception as e:
45
+ # Nếu lỗi clean_text vẫn xảy ra, hãy kiểm tra lại file .pkl và việc sử dụng TextCleaner class.
46
+ st.error(f"Lỗi khi tải mô hình: {e}. Vui lòng đảm bảo hàm clean_text đã được định nghĩa chính xác và file mô hình nằm đúng vị trí.")
47
  st.stop() # Dừng ứng dụng nếu mô hình không tải được
48
 
49
+ # Chỉ hiển thị thông báo tải thành công nếu không có lỗi nào trước đó
50
+ if model is not None:
51
+ st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
52
+
53
 
54
  # --- Giao diện Streamlit ---
55
+ # Các lệnh Streamlit khác sẽ bắt đầu từ đây trở đi
56
  st.title("📰 Phân biệt Tin tức Thật/Giả")
57
  st.markdown("Sử dụng mô hình AI để phân tích và xác định liệu một tin tức là thật hay giả.")
58
 
 
70
  st.error("Mô hình chưa sẵn sàng để phân tích. Vui lòng kiểm tra lại lỗi tải mô hình.")
71
  else:
72
  with st.spinner("Đang phân tích tin tức..."):
 
73
  input_df = pd.DataFrame({
74
  'Feature_1': [title_input],
75
  'Feature_2': [content_input]
76
  })
77
 
78
  try:
 
79
  prediction = model.predict(input_df)[0]
80
  prediction_proba = model.predict_proba(input_df)[0]
81
 
82
+ # Lấy xác suất cao nhất (độ tin cậy)
83
  confidence = round(max(prediction_proba) * 100, 2)
84
 
85
  # --- ĐIỀU CHỈNH LOGIC DỰ ĐOÁN DỰA TRÊN NGƯỠNG ĐỘ TIN CẬY ---
86
+ # Nhãn đã train của bạn: 0 là THẬT, 1 là GIẢ
87
  result_label = ""
88
  color = ""
89
  confidence_text = f"Độ tin cậy: **{confidence}%**"
90
 
 
91
  if prediction == 1: # Nếu mô hình ban đầu dự đoán là GIẢ (nhãn 1)
92
  if confidence < 90.0: # Và độ tin cậy của dự đoán GIẢ dưới 90%
93
  result_label = "Tin tức CÓ THỂ LÀ THẬT" # Chuyển thành THẬT do tin cậy thấp
 
102
 
103
  st.subheader("Kết quả phân tích:")
104
  st.markdown(f"<h3 style='color:{color};'>{result_label}</h3>", unsafe_allow_html=True)
105
+ st.info(confidence_text)
106
 
107
  except Exception as e:
108
  st.error(f"Đã xảy ra lỗi trong quá trình dự đoán: {e}")
109
+ st.exception(e)
110
 
111
  st.markdown("---")
112
  st.markdown("Ứng dụng này được phát triển để mục đích minh họa và học tập.")