Skripsi/app.py

118 lines
3.8 KiB
Python

from flask import Flask, render_template, request, jsonify
import joblib
import sys
import traceback
import pandas as pd
import re
app = Flask(__name__)
# -----------------------------
# Load kamus CSV (delimiter ;)
# -----------------------------
kamus_df = pd.read_csv('kamus_normalize.csv', sep=';')
kamus_df.columns = kamus_df.columns.str.strip() # hilangkan spasi di nama kolom
kamus = dict(zip(kamus_df['BEFORE'], kamus_df['AFTER']))
# -----------------------------
# Preprocessing function
# -----------------------------
def preprocess(text):
text = text.lower()
for k, v in kamus.items():
text = text.replace(k, v)
text = re.sub(r'[^a-z\s]', '', text)
text = re.sub(r'\s+', ' ', text).strip()
return text
# -----------------------------
# Load model, vectorizer, LabelEncoder
# -----------------------------
try:
print("Python version:", sys.version)
print("Loading TF-IDF vectorizer...")
# Jika vectorizer pernah pakai custom analyzer, definisikan identity dulu:
# def identity(x): return x
vectorizer = joblib.load('tfidf_vectorizer.pkl')
print("Vectorizer loaded:", type(vectorizer))
print("Loading Naive Bayes model...")
model = joblib.load('nb_classifier.pkl')
print("Model loaded:", type(model))
print("Loading LabelEncoder...")
le = joblib.load('label_encoder.pkl')
print("LabelEncoder loaded:", type(le))
except FileNotFoundError as e:
print(f"Error: {e}")
raise
except Exception as e:
print(f"Error loading models: {str(e)}")
traceback.print_exc()
raise
# -----------------------------
# Routes
# -----------------------------
@app.route('/')
def home():
return render_template('index.html')
@app.route('/analyze', methods=['POST'])
def analyze():
if request.method == 'POST':
try:
text = request.form['text']
print(f"Received text: {text}")
# Preprocess input
text_clean = preprocess(text)
print(f"Preprocessed text: {text_clean}")
# Transform and predict
X = vectorizer.transform([text_clean])
pred_encoded = model.predict(X)[0]
pred_label = le.inverse_transform([pred_encoded])[0] # output string
print(f"Predicted label: {pred_label}")
# Get prediction probabilities
probs = model.predict_proba(X)[0]
# Ambil index probabilitas positif/negatif
labels = le.inverse_transform(range(len(probs))) # misal ['negatif', 'positif']
neg_idx = list(labels).index('negatif')
pos_idx = list(labels).index('positif')
# Map ke key JS yang sesuai
prob_percentages = {
'Positive': f"{probs[pos_idx]*100:.2f}%",
'Negative': f"{probs[neg_idx]*100:.2f}%"}
# Pastikan sentimen dikirim bahasa Inggris untuk JS
pred_label_lower = pred_label.lower().strip()
if pred_label_lower == 'positif':
sentiment_str = 'Positive'
else:
sentiment_str = 'Negative'
# Map probabilities to correct labels (hanya negatif/positif)
# label_order = le.inverse_transform(range(len(probs))) # ['negatif', 'positif']
# prob_percentages = {label.capitalize(): f"{prob*100:.2f}%" for label, prob in zip(label_order, probs)}
return jsonify({
'sentiment': pred_label.capitalize(),
'probabilities': prob_percentages
})
except Exception as e:
print(f"Error during analysis: {str(e)}")
traceback.print_exc()
return jsonify({'error': str(e)}), 500
# -----------------------------
# Run Flask
# -----------------------------
if __name__ == '__main__':
app.run(debug=True)