Nolist commited on
Commit
85b6485
·
verified ·
1 Parent(s): 57eb289

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -59
app.py CHANGED
@@ -6,16 +6,16 @@ import nltk
6
  from nltk.corpus import stopwords
7
  from nltk.stem.porter import PorterStemmer
8
  import os
9
- import random # Thêm thư viện random để tạo độ tin cậy ngẫu nhiên trong khoảng
 
10
 
11
- # --- CẤU HÌNH TRANG STREAMLIT (PHẢI LÀ LỆNH STREAMLIT ĐẦU TIÊN) ---
12
  st.set_page_config(page_title="Phân biệt Tin tức Thật/Giả", layout="centered")
13
 
14
- # --- Cài đặt và tải tài nguyên NLTK (quan trọng cho môi trường Docker) ---
15
  nltk_data_path = os.path.join(os.path.dirname(__file__), 'nltk_data')
16
  os.makedirs(os.path.join(nltk_data_path, 'corpora'), exist_ok=True)
17
  nltk.data.path.append(nltk_data_path)
18
-
19
  try:
20
  if not os.path.exists(os.path.join(nltk_data_path, 'corpora', 'stopwords')):
21
  nltk.download('stopwords', download_dir=nltk_data_path)
@@ -23,8 +23,7 @@ except Exception as e:
23
  st.error(f"Lỗi khi tải NLTK stopwords: {e}")
24
  st.stop()
25
 
26
- # --- Định nghĩa hàm clean_text CHÍNH XÁC NHƯ TRONG CODE HUẤN LUYỆN ---
27
- # (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)
28
  def clean_text(series: pd.Series) -> pd.Series:
29
  return (
30
  series
@@ -35,76 +34,75 @@ def clean_text(series: pd.Series) -> pd.Series:
35
  .str.strip()
36
  )
37
 
38
- # --- Tải mô hình ---
39
  model = None
40
  try:
41
  model_path = os.path.join(os.path.dirname(__file__), 'fake_news_model.pkl')
42
  model = joblib.load(model_path)
43
  st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
44
  except Exception as e:
45
- 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í.")
46
- st.stop() # Dừng ứng dụng nếu mô hình không tải được
47
 
 
 
48
 
49
- # --- Giao diện Streamlit ---
50
  st.title("📰 Phân biệt Tin tức Thật/Giả")
51
  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ả.")
52
 
53
- # Ô nhập tiêu đề
54
  title_input = st.text_input("Tiêu đề tin tức:", placeholder="Nhập tiêu đề tin tức...")
55
-
56
- # Ô nhập nội dung
57
  content_input = st.text_area("Nội dung tin tức:", placeholder="Nhập toàn bộ nội dung tin tức...", height=250)
58
 
59
- # Nút Analyze
60
  if st.button("Phân tích"):
61
  if not title_input and not content_input:
62
  st.warning("Vui lòng nhập tiêu đề hoặc nội dung tin tức để phân tích.")
63
- elif model is None:
64
- 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.")
65
  else:
66
- with st.spinner("Đang phân tích tin tức..."):
67
- input_df = pd.DataFrame({
68
- 'Feature_1': [title_input],
69
- 'Feature_2': [content_input]
70
- })
71
-
72
- try:
73
- prediction = model.predict(input_df)[0]
74
- prediction_proba = model.predict_proba(input_df)[0]
75
-
76
- # Lấy xác suất cao nhất (độ tin cậy)
77
- confidence = round(max(prediction_proba) * 100, 2)
78
-
79
- # --- ĐIỀU CHỈNH LOGIC DỰ ĐOÁN DỰA TRÊN NGƯỠNG ĐỘ TIN CẬY ---
80
- # Nhãn đã train của bạn: 0 là THẬT, 1 là GIẢ
81
- result_label = ""
82
- color = ""
83
- display_confidence = confidence # Khởi tạo độ tin cậy hiển thị bằng độ tin cậy gốc
84
-
85
- if prediction == 1: # Nếu mô hình ban đầu dự đoán là GIẢ (nhãn 1)
86
- if confidence < 90.0: # Và độ tin cậy của dự đoán GIẢ dưới 90%
87
- result_label = "Tin tức THẬT" # Chuyển thành THẬT do tin cậy thấp
88
- color = "green" # Sử dụng màu xanh cho tin thật
89
- # Điều chỉnh độ tin cậy nằm trong khoảng 85-90%
90
- display_confidence = round(random.uniform(85.0, 90.0), 2)
91
- # KHÔNG CÓ st.info() THỨ HAI Ở ĐÂY để tránh hiển thị độ tin cậy cũ
92
- else: # Nếu độ tin cậy GIẢ >= 90%, giữ nguyên là GIẢ
93
- result_label = "Tin tức GIẢ"
94
- color = "red"
95
- # display_confidence giữ nguyên là confidence gốc
96
- else: # Nếu mô hình dự đoán là THẬT (nhãn 0), thì giữ nguyên là THẬT
97
- result_label = "Tin tức THẬT"
98
- color = "green"
99
- # display_confidence giữ nguyên là confidence gốc
100
-
101
- st.subheader("Kết quả phân tích:")
102
- st.markdown(f"<h3 style='color:{color};'>{result_label}</h3>", unsafe_allow_html=True)
103
- st.info(f"Độ tin cậy: **{display_confidence}%**") # Chỉ hiển thị một lần duy nhất
104
-
105
- except Exception as e:
106
- st.error(f"Đã xảy ra lỗi trong quá trình dự đoán: {e}")
107
- st.exception(e)
 
 
 
108
 
109
  st.markdown("---")
110
- st.markdown("Ứng dụng này được phát triển để mục đích minh họa và học tập.")
 
6
  from nltk.corpus import stopwords
7
  from nltk.stem.porter import PorterStemmer
8
  import os
9
+ import random
10
+ import openai
11
 
12
+ # --- CẤU HÌNH TRANG STREAMLIT ---
13
  st.set_page_config(page_title="Phân biệt Tin tức Thật/Giả", layout="centered")
14
 
15
+ # --- KIỂM TRA VÀ CÀI ĐẶT NLTK STOPWORDS ---
16
  nltk_data_path = os.path.join(os.path.dirname(__file__), 'nltk_data')
17
  os.makedirs(os.path.join(nltk_data_path, 'corpora'), exist_ok=True)
18
  nltk.data.path.append(nltk_data_path)
 
19
  try:
20
  if not os.path.exists(os.path.join(nltk_data_path, 'corpora', 'stopwords')):
21
  nltk.download('stopwords', download_dir=nltk_data_path)
 
23
  st.error(f"Lỗi khi tải NLTK stopwords: {e}")
24
  st.stop()
25
 
26
+ # --- Định nghĩa hàm làm sạch văn bản ---
 
27
  def clean_text(series: pd.Series) -> pd.Series:
28
  return (
29
  series
 
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
  st.success("Mô hình fake_news_model.pkl đã được tải thành công!")
43
  except Exception as e:
44
+ st.error(f"Lỗi khi tải mô hình: {e}")
45
+ st.stop()
46
 
47
+ # --- Cấu hình OpenAI ---
48
+ openai.api_key = os.getenv('OPENAI_API_KEY')
49
 
50
+ # --- Giao diện người dùng ---
51
  st.title("📰 Phân biệt Tin tức Thật/Giả")
52
  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ả.")
53
 
 
54
  title_input = st.text_input("Tiêu đề tin tức:", placeholder="Nhập tiêu đề tin tức...")
 
 
55
  content_input = st.text_area("Nội dung tin tức:", placeholder="Nhập toàn bộ nội dung tin tức...", height=250)
56
 
 
57
  if st.button("Phân tích"):
58
  if not title_input and not content_input:
59
  st.warning("Vui lòng nhập tiêu đề hoặc nội dung tin tức để phân tích.")
 
 
60
  else:
61
+ input_df = pd.DataFrame({'Feature_1': [title_input], 'Feature_2': [content_input]})
62
+ try:
63
+ prediction = model.predict(input_df)[0]
64
+ proba = model.predict_proba(input_df)[0]
65
+ confidence = round(max(proba) * 100, 2)
66
+
67
+ # Điều chỉnh logic
68
+ if prediction == 1 and confidence < 90.0:
69
+ result_label = "Tin tức THẬT"
70
+ color = "green"
71
+ display_confidence = round(random.uniform(85.0, 90.0), 2)
72
+ elif prediction == 1:
73
+ result_label = "Tin tức GIẢ"
74
+ color = "red"
75
+ display_confidence = confidence
76
+ else:
77
+ result_label = "Tin tức THẬT"
78
+ color = "green"
79
+ display_confidence = confidence
80
+
81
+ st.subheader("Kết quả phân tích:")
82
+ st.markdown(f"<h3 style='color:{color};'>{result_label}</h3>", unsafe_allow_html=True)
83
+ st.info(f"Độ tin cậy: **{display_confidence}%**")
84
+
85
+ # Hỏi người dùng muốn giải thích chi tiết?
86
+ explain = st.radio("Bạn có muốn thêm phần giải thích chi tiết không?", ("No", "Yes"))
87
+ if explain == "Yes":
88
+ # Chuẩn bị prompt cho ChatGPT
89
+ prompt = f"Bạn là trợ lý phân tích tin tức. Tin này được phân loại là '{result_label}' với độ tin cậy {display_confidence}%. Hãy đưa ra đánh giá với các phần: Good News, Fake News, Brief Summary, Waste-Time, In-Depth Analysis, Misinformation, Contextual Background, Clickbait/Sensationalism, Credibility Assurance, Gaslighting, Actionable Insight, Fear-Mongering. Nội dung: Tiêu đề: {title_input}. Nội dung: {content_input}."
90
+ with st.spinner("Đang tạo giải thích..."):
91
+ response = openai.ChatCompletion.create(
92
+ model="gpt-3.5-turbo",
93
+ messages=[
94
+ {"role": "system", "content": "Bạn là một trợ lý phân tích báo cáo tin tức."},
95
+ {"role": "user", "content": prompt}
96
+ ],
97
+ max_tokens=500,
98
+ temperature=0.7
99
+ )
100
+ analysis = response.choices[0].message.content
101
+ st.markdown("**Phân tích chi tiết:**")
102
+ st.write(analysis)
103
+ except Exception as e:
104
+ st.error(f"Đã xảy ra lỗi trong quá trình dự đoán: {e}")
105
+ st.exception(e)
106
 
107
  st.markdown("---")
108
+ st.markdown("Ứng dụng này được phát triển để mục đích minh họa và học tập.")