import streamlit as st import pandas as pd import numpy as np import neattext.functions as nfx from tensorflow.keras.models import load_model import pickle from textblob import TextBlob import os import nltk import plotly.graph_objects as go # --- NLTK PAKETLERİ --- try: nltk.data.find('corpora/wordnet') except LookupError: nltk.download('wordnet') nltk.download('punkt') nltk.download('omw-1.4') # --- PICKLE İÇİN GEREKLİ FONKSİYON --- # Model eğitilirken kullanılan 'ekkok' fonksiyonu burada tanımlı olmalı def ekkok(title): return [word.lemmatize() for word in TextBlob(title).words] # --- SAYFA AYARLARI --- st.set_page_config(page_title="News Classifier", layout="wide") # --- MODEL VE DOSYALARI YÜKLEME --- @st.cache_resource def load_assets(): model_path = "news_classification_model.h5" vect_path = "tfidf_vectorizer.pkl" le_path = "label_encoder.pkl" # Dosyaların varlığını kontrol et if not all(os.path.exists(p) for p in [model_path, vect_path, le_path]): st.error("⚠️ Model dosyaları bulunamadı! Lütfen .h5 ve .pkl dosyalarını app.py ile aynı klasöre koyun.") st.stop() # Modeli yükle model = load_model(model_path) # Pickle dosyalarını yükle with open(vect_path, "rb") as f: vect = pickle.load(f) with open(le_path, "rb") as f: le = pickle.load(f) return model, vect, le # Dosyaları belleğe alalım model, vect, le = load_assets() # --- TAHMİN FONKSİYONU --- def predict_news(text): # Metin temizleme clean_text = nfx.clean_text(text.lower()) # TF-IDF Dönüşümü matrix = vect.transform([clean_text]).toarray() # Model Tahmini prediction = model.predict(matrix, verbose=0) class_index = np.argmax(prediction) prob = np.max(prediction) # Kategori ismini bulma category = le.inverse_transform([class_index])[0] # Sınıf olasılıkları probabilities = prediction[0] return category, prob, probabilities # --- SIDEBAR (SOL PANEL) - ÇOKLU ÖRNEKLER --- st.sidebar.title("📌 Samples / Örnekler") # Her kategori için 3'er adet örnek cümle (Science/Uzay ağırlıklı) all_examples = { "Science / Bilim": [ "NASA's Perseverance rover successfully collects high-priority rock samples from the Martian surface.", "The James Webb Space Telescope captures stunning new images of a distant star-forming nebula.", "Astronomers discover a new solar system with three potentially habitable planets." ], "Tech / Teknoloji": [ "Apple announces new AI-powered features for the upcoming iPhone 18 Pro series.", "OpenAI releases a new language model that can reason like a human expert.", "Scientists develop a new quantum computer that performs calculations in seconds." ], "Sports / Spor": [ "Manchester City secures a narrow victory against Arsenal in a thrilling Premier League match.", "The Olympic Committee announces the final list of cities bidding for the 2032 Games.", "Formula 1 introduces new sustainable fuel regulations to be implemented by 2026." ], "Business / Ekonomi": [ "Global stock markets rally as central banks signal potential interest rate cuts.", "The tech industry faces new regulations regarding data privacy and user security.", "Gold prices hit an all-time high amidst global economic uncertainty and inflation." ], "Health / Sağlık": [ "New clinical trials show a 90% success rate in a breakthrough cancer treatment.", "Doctors recommend daily exercise and a balanced diet to prevent heart disease.", "A new study reveals the long-term impact of sleep deprivation on mental health." ] } # Kategori seçimi selected_cat = st.sidebar.selectbox("Select Category / Kategori Seçin:", [""] + list(all_examples.keys())) if selected_cat != "": st.sidebar.markdown(f"### {selected_cat} Örnekleri:") st.sidebar.write("Kopyalamak için üzerine tıklayın:") # Seçilen kategorideki 3 örneği de kopyalanabilir code bloğu içinde gösteriyoruz for i, ex in enumerate(all_examples[selected_cat], 1): st.sidebar.info(f"Örnek {i}:") st.sidebar.code(ex, language=None) # --- ANA SAYFA TASARIMI --- st.title("📰 News Topic Categorizer / Haber Sınıflandırıcı") st.markdown("---") # Metin Giriş Alanı (Her zaman boş başlar) user_input = st.text_area("News Headline / Haber Başlığı:", height=150, placeholder="Sol taraftan bir örnek kopyalayıp buraya yapıştırın...") # Tahmin Butonu ve İşlemi if st.button("Predict / Tahmin Et"): if user_input.strip() != "": with st.spinner('Analyzing... / Analiz ediliyor...'): # 1. Tahmin Yap category, confidence, all_probs = predict_news(user_input) # 2. Çeviri Yap (TextBlob kullanarak hatasız çeviri, cgi hatası vermez) try: # TextBlob bazen internet bağlantısına göre yavaşlayabilir translated = str(TextBlob(user_input).translate(from_lang='en', to='tr')) except: translated = "Çeviri şu an yapılamıyor. / Translation failed." # 3. Efektler st.balloons() # 4. Haber ve Alt Satırda Çeviri (Şık Bilgi Kutusu) st.info(f"**English:** {user_input}\n\n**Türkçe Çeviri:** *{translated}*") st.markdown("---") # 5. Sonuç Kartları (Metric formatında) res_col1, res_col2 = st.columns(2) with res_col1: st.success(f"**Predicted Category / Tahmin Edilen Kategori:**\n\n## {category}") with res_col2: st.warning(f"**Confidence Score / Güven Oranı:**\n\n## %{confidence*100:.2f}") # 6. Grafik Ekleme (Plotly ile Şık ve Renkli Görünüm) st.markdown("#### Probability Distribution / Olasılık Dağılımı") # Etiketler ve olasılıklar labels = le.classes_ # --- GRAFİK RENGİ MAVİ OLSUN --- fig = go.Figure(go.Bar( x=all_probs, y=labels, orientation='h', marker_color='#1F77B4', # Mazarine Blue / Mavi Renk Kodu text=[f"%{p*100:.1f}" for p in all_probs], textposition='auto' )) fig.update_layout( title="Category Probabilities / Kategori Olasılıkları", xaxis_title="Confidence / Güven", yaxis_title="Categories / Kategoriler", height=400, margin=dict(l=20, r=20, t=40, b=20) ) st.plotly_chart(fig, use_container_width=True) else: st.warning("⚠️ Lütfen bir haber başlığı girin! / Please enter a headline!") # Footer / Alt Bilgi st.markdown("---") st.caption("Deep Learning News Classification Project - Powered by Mergen")