CoolFace
Apppublic

HITESHCODER/Toxic_Comment_Detection_System

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
app.py574 linesDownload Raw Back to root
1# ==========================================================2# Imports3# ==========================================================4 5import gradio as gr6import pandas as pd7import numpy as np8import matplotlib.pyplot as plt9 10import joblib11 12import re13import string14import contractions15import emoji16 17import nltk18from nltk.tokenize import word_tokenize19from nltk.corpus import stopwords20from nltk.stem import WordNetLemmatizer21 22 23# ==========================================================24# Download NLTK Resources (Only First Time)25# ==========================================================26 27nltk.download("punkt")28nltk.download("punkt_tab")29nltk.download("stopwords")30nltk.download("wordnet")31nltk.download("omw-1.4")32 33 34# ==========================================================35# Load Saved Model36# ==========================================================37 38pipeline = joblib.load("pipeline.pkl")39 40# Load Thresholds41thresholds = joblib.load("thresholds.pkl")42 43 44# ==========================================================45# Labels46# ==========================================================47 48LABELS = [49    "Toxic",50    "Severe Toxic",51    "Obscene",52    "Threat",53    "Insult",54    "Identity Hate"55]56 57 58# ==========================================================59# NLP Objects60# ==========================================================61 62lemmatizer = WordNetLemmatizer()63 64stop_words = set(stopwords.words("english"))65 66for word in ["not", "no", "nor", "never"]:67    stop_words.discard(word)68 69 70# ==========================================================71# Text Preprocessing Function72# ==========================================================73 74def preprocess(text):75 76    # Convert to lowercase77    text = text.lower()78 79    # Expand contractions80    text = contractions.fix(text)81 82    # Remove HTML83    text = re.sub(r"<.*?>", "", text)84 85    # Remove URLs86    text = re.sub(r"http\S+|www\S+", "", text)87 88    # Remove Emails89    text = re.sub(r"\S+@\S+", "", text)90 91    # Remove @mentions92    text = re.sub(r"@\w+", "", text)93 94    # Remove hashtag symbol95    text = text.replace("#", "")96 97    # Remove emojis98    text = emoji.replace_emoji(text, replace="")99 100    # Remove numbers101    text = re.sub(r"\d+", "", text)102 103    # Remove punctuation104    text = text.translate(105        str.maketrans("", "", string.punctuation)106    )107 108    # Remove extra spaces109    text = re.sub(r"\s+", " ", text).strip()110 111    # Tokenize112    words = word_tokenize(text)113 114    # Remove stopwords + Lemmatization115    words = [116 117        lemmatizer.lemmatize(word, pos="v")118 119        for word in words120 121        if word not in stop_words122 123    ]124 125    return " ".join(words)126 127 128# ==========================================================129# Prediction Function130# ==========================================================131 132def predict_comment(user_comment):133 134    # Keep original comment135    original_comment = user_comment136 137    # Clean comment138    cleaned_comment = preprocess(user_comment)139 140    # Create dataframe (same format used during training)141    input_df = pd.DataFrame(142        {143            "clean_comment": [cleaned_comment]144        }145    )146 147    # Predict probabilities148    probabilities = pipeline.predict_proba(input_df)[0]149 150    # Apply thresholds151    predictions = (152        probabilities >= thresholds153    ).astype(int)154 155    # Overall confidence156    confidence = np.max(probabilities) * 100157 158    return (159        original_comment,160        cleaned_comment,161        probabilities,162        predictions,163        confidence164    )165 166def get_overall_status(predictions):167 168    if np.sum(predictions) == 0:169 170        return "🟢 NON TOXIC COMMENT"171 172    else:173 174        return "🔴 TOXIC COMMENT DETECTED"175 176 177def create_probability_table(probabilities, predictions):178 179    probability_df = pd.DataFrame({180 181        "Category": LABELS,182 183        "Probability (%)":184        np.round(probabilities * 100, 2),185 186        "Prediction":187        [188            "Positive" if pred == 1189            else "Negative"190 191            for pred in predictions192        ]193 194    })195 196    return probability_df197 198def create_probability_chart(probabilities):199 200    probabilities = probabilities * 100201 202    fig, ax = plt.subplots(figsize=(8,5))203 204    bars = ax.barh(205 206        LABELS,207 208        probabilities209 210    )211 212    ax.set_xlim(0,100)213 214    ax.set_xlabel("Probability (%)")215 216    ax.set_title("Toxicity Probability Distribution")217 218    for bar in bars:219 220        width = bar.get_width()221 222        ax.text(223 224            width + 1,225 226            bar.get_y() + bar.get_height()/2,227 228            f"{width:.1f}%",229 230            va="center"231 232        )233 234    plt.tight_layout()235 236    return fig237 238def generate_summary(probabilities, predictions):239 240    summary = []241 242    for label, prob, pred in zip(243 244        LABELS,245 246        probabilities,247 248        predictions249 250    ):251 252        if pred == 1:253 254            if prob >= 0.80:255 256                summary.append(257 258                    f"• High confidence {label.lower()} detected ({prob*100:.1f}%)."259 260                )261 262            elif prob >= 0.50:263 264                summary.append(265 266                    f"• Moderate confidence {label.lower()} detected ({prob*100:.1f}%)."267 268                )269 270            else:271 272                summary.append(273 274                    f"• Low confidence {label.lower()} detected ({prob*100:.1f}%)."275 276                )277 278    if len(summary) == 0:279 280        summary.append(281 282            "• No toxic categories detected."283 284        )285 286    summary.append("")287 288    if np.sum(predictions) > 0:289 290        summary.append(291 292            "Recommendation: This comment should be reviewed before posting."293 294        )295 296    else:297 298        summary.append(299 300            "Recommendation: This comment appears safe."301 302        )303 304    return "\n".join(summary)305 306def analyze_comment(user_comment):307 308    (309        original_comment,310 311        cleaned_comment,312 313        probabilities,314 315        predictions,316 317        confidence318 319    ) = predict_comment(user_comment)320 321    status = get_overall_status(predictions)322 323    probability_table = create_probability_table(324 325        probabilities,326 327        predictions328 329    )330 331    chart = create_probability_chart(332 333        probabilities334 335    )336 337    summary = generate_summary(338 339        probabilities,340 341        predictions342 343    )344 345    confidence = f"{confidence:.2f}%"346 347    return (348 349        original_comment,350 351        cleaned_comment,352 353        status,354 355        confidence,356 357        probability_table,358 359        chart,360 361        summary362 363    )364 365 366css = """367footer {368    visibility: hidden;369}370 371.gradio-container {372    max-width: 1300px !important;373    margin: auto;374}375 376h1{377    text-align:center;378}379 380"""381 382# ==========================================================383# Gradio User Interface384# ==========================================================385 386with gr.Blocks(387    css=css,388    theme=gr.themes.Soft(389        primary_hue="blue",390        secondary_hue="slate"391    ),392    title="AI Toxic Comment Detection System"393) as demo:394 395    gr.Markdown(396        """397        # 🛡️ AI Toxic Comment Detection System398        399        Analyze comments using a Multi-Label Machine Learning Model.400        401        The model predicts the following six toxicity categories:402        403        - Toxic404        - Severe Toxic405        - Obscene406        - Threat407        - Insult408        - Identity Hate409        """410    )411 412    # =====================================================413    # User Input414    # =====================================================415 416    with gr.Row():417 418        comment_input = gr.Textbox(419 420            label="Enter Comment",421 422            placeholder="Type or paste a comment here...",423 424            lines=5425 426        )427 428    analyze_button = gr.Button(429 430        "Analyze Comment",431 432        variant="primary"433 434    )435 436    gr.Markdown("---")437 438    # =====================================================439    # Original & Cleaned Comment440    # =====================================================441 442    with gr.Row():443 444        original_output = gr.Textbox(445 446            label="Original Comment",447 448            interactive=False,449 450            lines=4451 452        )453 454        cleaned_output = gr.Textbox(455 456            label="Preprocessed Comment",457 458            interactive=False,459 460            lines=4461 462        )463 464    # =====================================================465    # Overall Prediction466    # =====================================================467 468    with gr.Row():469 470        status_output = gr.Textbox(471 472            label="Overall Prediction",473 474            interactive=False475 476        )477 478        confidence_output = gr.Textbox(479 480            label="Overall Confidence",481 482            interactive=False483 484        )485 486    gr.Markdown("---")487 488    # =====================================================489    # Prediction Table490    # =====================================================491 492    probability_table = gr.Dataframe(493 494        headers=[495 496            "Category",497 498            "Probability (%)",499 500            "Prediction"501 502        ],503 504        interactive=False,505 506        label="Prediction Details"507 508    )509 510    gr.Markdown("---")511 512    # =====================================================513    # Probability Graph514    # =====================================================515 516    probability_plot = gr.Plot(517 518        label="Category Probability Distribution"519 520    )521 522    gr.Markdown("---")523 524    # =====================================================525    # AI Summary526    # =====================================================527 528    summary_output = gr.Textbox(529 530        label="AI Analysis Summary",531 532        interactive=False,533 534        lines=10535 536    )537 538    # =====================================================539    # Button Click Event540    # =====================================================541 542    analyze_button.click(543 544        fn=analyze_comment,545 546        inputs=comment_input,547 548        outputs=[549 550            original_output,551 552            cleaned_output,553 554            status_output,555 556            confidence_output,557 558            probability_table,559 560            probability_plot,561 562            summary_output563 564        ]565 566    )567 568# ==========================================================569# Launch App570# ==========================================================571 572if __name__ == "__main__":573    demo.launch(debug=True)574