Nolist commited on
Commit
dfee9a8
·
verified ·
1 Parent(s): 6e40754

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -21
app.py CHANGED
@@ -3,22 +3,21 @@ import joblib
3
  import pandas as pd
4
  import re
5
  import nltk
6
- # from nltk.corpus import stopwords # Không cần thiết nếu stopwords chỉ dùng trong TextCleaner
7
- # from nltk.stem.porter import PorterStemmer # Không cần thiết
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
  # --- Định nghĩa lớp Custom Transformer cho việc làm sạch văn bản ---
14
- # PHẢI CHÍNH XÁC NHƯ LỚP BẠN ĐÃ DÙNG KHI HUẤN LUYỆN
15
- from sklearn.base import BaseEstimator, TransformerMixin
16
-
17
  class TextCleaner(BaseEstimator, TransformerMixin):
18
  def fit(self, X, y=None):
19
  return self
20
 
21
  def transform(self, X: pd.Series, y=None):
 
22
  if not isinstance(X, pd.Series):
23
  X = pd.Series(X)
24
 
@@ -32,6 +31,10 @@ class TextCleaner(BaseEstimator, TransformerMixin):
32
  )
33
 
34
  # --- Cài đặt và tải tài nguyên NLTK (quan trọng cho môi trường Docker) ---
 
 
 
 
35
  nltk_data_path = os.path.join(os.path.dirname(__file__), 'nltk_data')
36
  os.makedirs(os.path.join(nltk_data_path, 'corpora'), exist_ok=True)
37
  nltk.data.path.append(nltk_data_path)
@@ -40,21 +43,25 @@ try:
40
  if not os.path.exists(os.path.join(nltk_data_path, 'corpora', 'stopwords')):
41
  nltk.download('stopwords', download_dir=nltk_data_path)
42
  except Exception as e:
43
- st.error(f"Lỗi khi tải NLTK stopwords: {e}")
44
  st.stop()
45
 
46
 
47
  # --- Tải mô hình ---
 
48
  model = None
49
  try:
50
  model_path = os.path.join(os.path.dirname(__file__), 'fake_news_model.pkl')
 
51
  model = joblib.load(model_path)
52
  st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
53
  except Exception as e:
54
  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í.")
55
- st.stop()
 
56
 
57
  # --- Giao diện Streamlit ---
 
58
  st.title("📰 Phân biệt Tin tức Thật/Giả")
59
  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ả.")
60
 
@@ -72,45 +79,46 @@ if st.button("Phân tích"):
72
  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.")
73
  else:
74
  with st.spinner("Đang phân tích tin tức..."):
 
75
  input_df = pd.DataFrame({
76
  'Feature_1': [title_input],
77
  'Feature_2': [content_input]
78
  })
79
 
80
  try:
 
81
  prediction = model.predict(input_df)[0]
82
  prediction_proba = model.predict_proba(input_df)[0]
83
 
84
- # Lấy xác suất của lớp được dự đoán
85
  confidence = round(max(prediction_proba) * 100, 2)
86
 
87
  # --- ĐIỀU CHỈNH LOGIC DỰ ĐOÁN DỰA TRÊN NGƯỠNG ĐỘ TIN CẬY ---
 
88
  result_label = ""
89
  color = ""
 
90
 
91
- # Gán nhãn theo cách bạn đã train: 0 là THẬT, 1 là GIẢ
92
- # Kiểm tra nếu mô hình dự đoán là GIẢ (prediction == 1)
93
- if prediction == 1: # Dự đoán ban đầu là GIẢ
94
- if confidence < 90.0: # Nhưng độ tin cậy thấp hơn 90%
95
- result_label = "Tin tức CÓ THỂ LÀ THẬT (Độ tin cậy giả thấp)" # Chuyển thành THẬT do tin cậy thấp
96
- color = "orange" # Hoặc màu khác để chỉ sự không chắc chắn
97
- else: # Độ tin cậy cao, giữ nguyên là GIẢ
98
  result_label = "Tin tức GIẢ"
99
  color = "red"
100
- else: # Dự đoán là THẬT (prediction == 0)
101
  result_label = "Tin tức THẬT"
102
  color = "green"
103
 
104
  st.subheader("Kết quả phân tích:")
105
  st.markdown(f"<h3 style='color:{color};'>{result_label}</h3>", unsafe_allow_html=True)
106
- st.info(f"Độ tin cậy: **{confidence}%**")
107
- # Tùy chọn: Hiển thị cả xác suất của từng lớp để hiểu rõ hơn
108
- # st.write(f"Xác suất: Thật ({round(prediction_proba[0]*100,2)}%), Giả ({round(prediction_proba[1]*100,2)}%)")
109
-
110
 
111
  except Exception as e:
112
  st.error(f"Đã xảy ra lỗi trong quá trình dự đoán: {e}")
113
- st.exception(e)
114
 
115
  st.markdown("---")
116
  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
  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
 
 
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
  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
  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
106
+ color = "orange" # Màu cam để chỉ sự không chắc chắn
107
+ confidence_text += " (Độ tin cậy của dự đoán GIẢ thấp, có thể là thật)"
108
+ else: # Nếu độ tin cậy GIẢ >= 90%, giữ nguyên là GIẢ
109
  result_label = "Tin tức GIẢ"
110
  color = "red"
111
+ else: # Nếu mô hình dự đoán là THẬT (nhãn 0), thì giữ nguyên là THẬT
112
  result_label = "Tin tức THẬT"
113
  color = "green"
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.")