|
|
"""
|
|
|
Interaktywny skrypt do testowania klasyfikatora jakości tekstu.
|
|
|
|
|
|
Ten moduł dostarcza prosty interfejs wiersza poleceń (CLI) do analizy
|
|
|
pojedynczych tekstów. Po uruchomieniu, skrypt wczytuje te same modele
|
|
|
i komponenty, które są używane w procesie przetwarzania wsadowego
|
|
|
(TextAnalyzer, Scaler, Classifier).
|
|
|
|
|
|
Jest to narzędzie przeznaczone do szybkich testów, debugowania i demonstracji
|
|
|
działania modelu, zapewniając spójność wyników z przetwarzaniem masowym.
|
|
|
|
|
|
Użycie:
|
|
|
python interactive_classifier.py
|
|
|
"""
|
|
|
|
|
|
import pickle
|
|
|
import joblib
|
|
|
import pandas as pd
|
|
|
from text_analyzer.analyzer import TextAnalyzer
|
|
|
from text_analyzer import constants
|
|
|
|
|
|
MODELS_DIR = 'models'
|
|
|
|
|
|
|
|
|
|
|
|
print("Ładowanie modeli i analizatora...")
|
|
|
|
|
|
with open('models/scaler.pkl', 'rb') as f:
|
|
|
scaler = pickle.load(f)
|
|
|
classifier = joblib.load("models/model.joblib")
|
|
|
text_analyzer = TextAnalyzer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def classify_single_text(text_to_classify: str) -> tuple[str | None, float | None]:
|
|
|
"""
|
|
|
Analizuje pojedynczy tekst i dokonuje predykcji jego jakości,
|
|
|
używając tego samego potoku co w przetwarzaniu wsadowym.
|
|
|
|
|
|
Potok inferencyjny:
|
|
|
1. Ekstrakcja cech za pomocą TextAnalyzer.
|
|
|
2. Uporządkowanie cech zgodnie z `constants.COLUMN_ORDER`.
|
|
|
3. Skalowanie cech za pomocą wczytanego skalera.
|
|
|
4. Predykcja prawdopodobieństw klas za pomocą modelu.
|
|
|
5. Wybór najbardziej prawdopodobnej klasy i formatowanie wyniku.
|
|
|
|
|
|
Args:
|
|
|
text_to_classify (str): Ciąg znaków do analizy.
|
|
|
|
|
|
Returns:
|
|
|
tuple[str | None, float | None]: zawiera:
|
|
|
- Przewidywaną kategorię ('LOW', 'MEDIUM', 'HIGH') lub None w przypadku błędu.
|
|
|
- Pewność predykcji (w procentach) lub None w przypadku błędu.
|
|
|
"""
|
|
|
|
|
|
if not isinstance(text_to_classify, str) or not text_to_classify.strip():
|
|
|
print("Błąd: Wprowadzony tekst jest pusty lub nie jest typu string.")
|
|
|
return None, None
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
|
features_dict = next(text_analyzer.analyze_batch([text_to_classify]))
|
|
|
|
|
|
|
|
|
ordered_features = [features_dict.get(fname, 0.0) for fname in constants.COLUMN_ORDER]
|
|
|
|
|
|
|
|
|
features_df = pd.DataFrame([ordered_features], columns=constants.COLUMN_ORDER)
|
|
|
input_features_scaled = scaler.transform(features_df)
|
|
|
|
|
|
|
|
|
y_pred_proba = classifier.predict_proba(input_features_scaled)
|
|
|
|
|
|
|
|
|
labels = ["LOW", "MEDIUM", "HIGH"]
|
|
|
category_probabilities = {
|
|
|
label: prob
|
|
|
for label, prob in zip(labels, y_pred_proba[0])
|
|
|
}
|
|
|
|
|
|
most_probable_category = max(category_probabilities, key=category_probabilities.get)
|
|
|
confidence = round(category_probabilities[most_probable_category] * 100, 2)
|
|
|
|
|
|
return most_probable_category, confidence
|
|
|
|
|
|
except Exception as e:
|
|
|
print(f"\nWystąpił nieoczekiwany błąd podczas przetwarzania tekstu.")
|
|
|
print(f"Szczegóły błędu: {e}")
|
|
|
return None, None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
print("\n--- Interaktywny Klasyfikator Jakości Tekstu ---")
|
|
|
print("Wpisz tekst i naciśnij Enter, aby uzyskać klasyfikację.")
|
|
|
print("Wpisz 'quit' lub 'exit', aby zakończyć.")
|
|
|
|
|
|
|
|
|
while True:
|
|
|
try:
|
|
|
|
|
|
user_input = input("\n> ")
|
|
|
|
|
|
if user_input.lower() in ['quit', 'exit']:
|
|
|
print("Zamykanie programu...")
|
|
|
break
|
|
|
|
|
|
|
|
|
category, confidence = classify_single_text(user_input)
|
|
|
|
|
|
|
|
|
if category is not None:
|
|
|
print(f" └── Predykcja: {category} (Pewność: {confidence}%)")
|
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
print("\nPrzerwano przez użytkownika. Zamykanie programu...")
|
|
|
break |