File size: 5,789 Bytes
ba48a36
9d454eb
 
 
 
58e2d3b
9d454eb
 
58e2d3b
9d454eb
ba48a36
9d454eb
 
 
 
 
 
 
58e2d3b
 
9d454eb
 
 
 
 
 
58e2d3b
9d454eb
ba48a36
9d454eb
 
 
 
 
 
 
 
58e2d3b
9d454eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ba48a36
9d454eb
58e2d3b
9d454eb
 
58e2d3b
 
9d454eb
58e2d3b
 
9d454eb
 
 
 
 
 
58e2d3b
9d454eb
58e2d3b
 
 
 
 
 
 
9d454eb
 
58e2d3b
9d454eb
 
 
 
 
58e2d3b
9d454eb
 
58e2d3b
 
9d454eb
 
58e2d3b
 
 
 
 
 
 
 
 
 
 
9d454eb
 
 
58e2d3b
ba48a36
9d454eb
 
 
 
 
 
 
 
 
ba48a36
9d454eb
 
 
 
 
 
 
 
 
 
ba48a36
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import gradio as gr
from llm_classification import get_answer
from inference_demo import (
    predict_randomforest_2f, predict_xgboost_2f, predict_lightgbm_2f,
    predict_svm_2f, predict_decisiontree_2f, predict_naivebayes_2f,
    predict_logisticregression_2f,
    predict_randomforest_6f, predict_xgboost_6f, predict_lightgbm_6f,
    predict_svm_6f, predict_decisiontree_6f, predict_naivebayes_6f,
    predict_logisticregression_6f,
)

PREDICT_FUNCS = {
    ("Random Forest", "2-feature"): predict_randomforest_2f,
    ("XGBoost", "2-feature"): predict_xgboost_2f,
    ("LightGBM", "2-feature"): predict_lightgbm_2f,
    ("SVM", "2-feature"): predict_svm_2f,
    ("Decision Tree", "2-feature"): predict_decisiontree_2f,
    ("Naive Bayes", "2-feature"): predict_naivebayes_2f,
    ("Logistic Regression", "2-feature"): predict_logisticregression_2f,

    ("Random Forest", "6-feature"): predict_randomforest_6f,
    ("XGBoost", "6-feature"): predict_xgboost_6f,
    ("LightGBM", "6-feature"): predict_lightgbm_6f,
    ("SVM", "6-feature"): predict_svm_6f,
    ("Decision Tree", "6-feature"): predict_decisiontree_6f,
    ("Naive Bayes", "6-feature"): predict_naivebayes_6f,
    ("Logistic Regression", "6-feature"): predict_logisticregression_6f,
}

CLASSIFIERS = [
    "๐Ÿ”ฎ Gemini",
    "๐ŸŒณ Random Forest",
    "โšก XGBoost",
    "๐Ÿ’ก LightGBM",
    "๐Ÿ“ˆ SVM",
    "๐ŸŒฒ Decision Tree",
    "๐Ÿ“Š Naive Bayes",
    "๐Ÿงฎ Logistic Regression",
    "๐Ÿค Ensemble"
]
FEATURE_VERSIONS = ["2-feature", "6-feature"]

FEATURE_EXPLANATIONS = {
    "2-feature": (
        "### Supported Language\n"
        "Only **English** sentences are supported.\n\n"
        "### 2-feature version\n"
        "This version uses only 2 frequency-based features:\n"
        "  * x1 = Total frequency of words in the Positive class\n"
        "  * x2 = Total frequency of words in the Negative class"
    ),
    "6-feature": (
        "### Supported Language\n"
        "Only **English** sentences are supported.\n\n"
        "### 6-feature version\n"
        "This version uses 6 features:\n"
        "  * x1 = Total frequency of words in the Positive class\n"
        "  * x2 = Total frequency of words in the Negative class\n"
        "  * x3 = 1 if the word 'no' appears, else 0\n"
        "  * x4 = Count of 1st and 2nd person pronouns\n"
        "  * x5 = 1 if the tweet contains '!' else 0\n"
        "  * x6 = log(word count)"
    ),
}

def explain_features(version: str) -> str:
    return FEATURE_EXPLANATIONS[version]

def infer(clf: str, version: str, text: str):
    if not text.strip():
        return {"โš ๏ธ Please enter a sentence": 1.0}, ""

    if clf == "๐Ÿ”ฎ Gemini":
        y = get_answer(text)
        return ({"Positive ๐Ÿ˜€": 1.0} if y == 1 else {"Negative ๐Ÿ˜ž": 1.0}), ""

    if clf == "๐Ÿค Ensemble":
        model_names = ["Random Forest", "XGBoost", "LightGBM", "SVM", "Decision Tree", "Naive Bayes", "Logistic Regression"]
        votes_detail, votes = [], []
        for m in model_names:
            func = PREDICT_FUNCS.get((m, version))
            if func:
                y = func(text)
                votes.append(y)
                votes_detail.append(f"- **{m}**: {'Positive ๐Ÿ˜€' if y == 1 else 'Negative ๐Ÿ˜ž'}")
        if not votes:
            return {"No models available": 1.0}, ""

        pos, total = sum(votes), len(votes)
        neg = total - pos
        pos_pct = 100 * pos / total
        neg_pct = 100 * neg / total

        if pos > neg:
            label = {"Positive ๐Ÿ˜€": 1.0}
            final = "### Final Ensemble Result: **Positive ๐Ÿ˜€**"
        elif neg > pos:
            label = {"Negative ๐Ÿ˜ž": 1.0}
            final = "### Final Ensemble Result: **Negative ๐Ÿ˜ž**"
        else:
            label = {"Tie ๐Ÿค”": 1.0}
            final = "### Final Ensemble Result: **Tie ๐Ÿค”**"

        detail_md = (
            f"{final}\n\n"
            f"**Votes:** {pos} positive ({pos_pct:.1f}%) | {neg} negative ({neg_pct:.1f}%) out of {total} models.\n\n"
            f"**Individual model decisions:**\n" + "\n".join(votes_detail)
        )
        return label, detail_md

    base_name = (
        clf.replace("๐ŸŒณ ","")
           .replace("โšก ","")
           .replace("๐Ÿ’ก ","")
           .replace("๐Ÿ“ˆ ","")
           .replace("๐ŸŒฒ ","")
           .replace("๐Ÿ“Š ","")
           .replace("๐Ÿงฎ ","")
    )
    func = PREDICT_FUNCS.get((base_name, version))
    if func is None:
        return {"Model not found": 1.0}, ""
    y = func(text)
    return ({"Positive ๐Ÿ˜€": 1.0} if y == 1 else {"Negative ๐Ÿ˜ž": 1.0}), ""

with gr.Blocks(
    title="Sentiment Classifier Demo",
    css=".big-markdown {font-size: 1.2rem; min-height: 300px; overflow:auto;}"
) as demo:
    gr.Markdown("## Sentiment Classifier Demo")
    with gr.Row():
        clf = gr.Dropdown(choices=CLASSIFIERS, value="๐Ÿ”ฎ Gemini", label="Classifier (or Ensemble)")
        version = gr.Dropdown(choices=FEATURE_VERSIONS, value="2-feature", label="Feature Version (not used for gemini)")
    txt = gr.Textbox(label="Input sentence (English only)", placeholder="Type a sentenceโ€ฆ")
    btn = gr.Button("Classify")
    out_label = gr.Label(label="Main Result")
    out_detail = gr.Markdown(elem_classes="big-markdown")
    explanation_box = gr.Markdown(FEATURE_EXPLANATIONS["2-feature"])
    version.change(fn=explain_features, inputs=version, outputs=explanation_box)
    btn.click(fn=infer, inputs=[clf, version, txt], outputs=[out_label, out_detail])
    gr.Markdown(
        "**Note:** This demo supports **English** sentences only. "
        "Choose '๐Ÿค Ensemble' to see the combined decision from all classifiers, "
        "or choose '๐Ÿ”ฎ Gemini' to use the Gemini LLM-based classifier."
    )
if __name__ == "__main__":
    demo.launch()