shubham680 commited on
Commit
2b1f512
·
verified ·
1 Parent(s): 94f7e42

Upload 9 files

Browse files
fasttext_domain.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b6fa43d70ea51575d93ce96c5ec1bba03100c72dfdf42fb6f2b08289aeeb41b2
3
+ size 10264425
fasttext_domain.model.wv.vectors_ngrams.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b5bdd748f437a21795f12887e0ad1e8252c6b344e1d17951409be23bdb9d2be7
3
+ size 800000128
hierarchy_meta.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8d1a32d2179b1c66893c590965381670e1fd3dd3c20e938104dcda8373e620c
3
+ size 201257
le_queue.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:33ff94621a99ad9d7efbf82d17c5ade73e2de7c34e85475eb34fcaba95c31e51
3
+ size 451
le_type.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5fabb50e2a8d002d772570d4344ef077ab5cbf69aef6cd6899bf89023c543c7a
3
+ size 282
mlb.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9809424782574009a156d26fee95e1198229f7238afd3eeaf88d1bdafa36752e
3
+ size 20183
multi_task_bilstm_attention.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:18969fb045ae33fb7570ea20f3cb02ae7fb45bd03cce42724bb2c086ca9e5be9
3
+ size 14278880
shubham (2).py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import base64
3
+ import traceback
4
+ import streamlit as st
5
+ import numpy as np
6
+ import pickle
7
+ import tensorflow as tf
8
+ from tensorflow.keras.preprocessing.sequence import pad_sequences
9
+ from tensorflow.keras import layers
10
+ from tensorflow.keras.models import load_model
11
+ from gensim.models import FastText
12
+ import nltk
13
+ import re
14
+ from nltk.corpus import stopwords
15
+ from nltk.tokenize import TreebankWordTokenizer
16
+
17
+ # ------------------- Config -------------------
18
+ MODEL_PATH = "multi_task_bilstm_attention.h5"
19
+ FASTTEXT_PATH = "fasttext_domain.model"
20
+ TOKENIZER_PKL = "tokenizer.pkl"
21
+ LE_TYPE_PKL = "le_type.pkl"
22
+ LE_QUEUE_PKL = "le_queue.pkl"
23
+ MLB_PKL = "mlb.pkl"
24
+ META_PKL = "hierarchy_meta.pkl"
25
+ MAX_LEN = 120
26
+
27
+ # ------------------- NLTK -------------------
28
+ try: _ = stopwords.words("english")
29
+ except: nltk.download("stopwords")
30
+ try: _ = nltk.word_tokenize("test")
31
+ except: nltk.download("punkt")
32
+
33
+ stop_words = set(stopwords.words("english"))
34
+ tokenizer_nltk = TreebankWordTokenizer()
35
+
36
+ def clean_text(text):
37
+ text = str(text)
38
+ text = re.sub(r"<.*?>", " ", text)
39
+ text = re.sub(r"[^A-Za-z0-9 ]", " ", text)
40
+ text = re.sub(r"\s+", " ", text).strip()
41
+ return text.lower()
42
+
43
+ def preprocess_text(text):
44
+ toks = tokenizer_nltk.tokenize(clean_text(text))
45
+ toks = [t for t in toks if t not in stop_words and len(t) > 1]
46
+ return " ".join(toks)
47
+
48
+ # ------------------- Custom Attention -------------------
49
+ class AttentionLayer(layers.Layer):
50
+ def build(self, input_shape):
51
+ self.W = self.add_weight(shape=(input_shape[-1], input_shape[-1]), initializer="glorot_uniform", trainable=True)
52
+ self.v = self.add_weight(shape=(input_shape[-1],), initializer="glorot_uniform", trainable=True)
53
+ super().build(input_shape)
54
+ def call(self, x):
55
+ u = tf.tanh(tf.tensordot(x, self.W, axes=1))
56
+ a = tf.nn.softmax(tf.tensordot(u, self.v, axes=1), axis=1)
57
+ return tf.reduce_sum(x * tf.expand_dims(a, -1), axis=1)
58
+
59
+ # ------------------- Safe Loaders -------------------
60
+ def safe_pickle(p):
61
+ return pickle.load(open(p, "rb")) if os.path.exists(p) else None
62
+
63
+ def safe_model(p):
64
+ if not os.path.exists(p): return None
65
+ with tf.keras.utils.custom_object_scope({"AttentionLayer": AttentionLayer}):
66
+ return load_model(p, compile=False)
67
+
68
+ def safe_fasttext(p):
69
+ return FastText.load(p) if os.path.exists(p) else None
70
+
71
+ tokenizer = safe_pickle(TOKENIZER_PKL)
72
+ le_type = safe_pickle(LE_TYPE_PKL)
73
+ le_queue = safe_pickle(LE_QUEUE_PKL)
74
+ mlb = safe_pickle(MLB_PKL)
75
+ meta = safe_pickle(META_PKL)
76
+
77
+ model = safe_model(MODEL_PATH)
78
+ fasttext = safe_fasttext(FASTTEXT_PATH)
79
+
80
+ if meta is None:
81
+ type_queue_mask = None; type_queue_tag_mask = None; best_thr = 0.5
82
+ else:
83
+ type_queue_mask = meta.get("type_queue_mask", None)
84
+ type_queue_tag_mask = meta.get("type_queue_tag_mask", None)
85
+ best_thr = float(meta.get("best_thr", 0.5))
86
+
87
+ # Fallbacks
88
+ class DummyLE:
89
+ def inverse_transform(self, X): return [str(int(x)) for x in X]
90
+ class DummyMLB:
91
+ def inverse_transform(self, X): return [tuple()]
92
+
93
+ if tokenizer is None:
94
+ from tensorflow.keras.preprocessing.text import Tokenizer
95
+ tokenizer = Tokenizer(num_words=20000, oov_token="<OOV>")
96
+ if le_type is None: le_type = DummyLE()
97
+ if le_queue is None: le_queue = DummyLE()
98
+ if mlb is None: mlb = DummyMLB()
99
+
100
+ # ------------------- Inference -------------------
101
+ def infer(text):
102
+ if model is None: raise RuntimeError("Model not loaded")
103
+ seq = tokenizer.texts_to_sequences([preprocess_text(text)])
104
+ seq = pad_sequences(seq, maxlen=MAX_LEN)
105
+
106
+ extra = np.zeros((1,2), dtype=np.int32)
107
+ preds = model.predict([seq, extra], verbose=0) if len(model.inputs) > 1 else model.predict(seq, verbose=0)
108
+ if isinstance(preds, (list,tuple)):
109
+ p_type, p_queue, p_tags = preds[0][0], preds[1][0], preds[2][0]
110
+ else:
111
+ arr = preds[0]; n=len(arr); t=max(1,n//3)
112
+ p_type, p_queue, p_tags = arr[:t], arr[t:2*t], arr[2*t:]
113
+
114
+ t_idx = np.argmax(p_type)
115
+ type_lbl = le_type.inverse_transform([t_idx])[0]
116
+
117
+ q_idx = np.argmax(p_queue)
118
+ queue_lbl = le_queue.inverse_transform([q_idx])[0]
119
+
120
+ if type_queue_tag_mask is not None:
121
+ mask = type_queue_tag_mask[t_idx, q_idx]
122
+ mod = p_tags * mask if mask.sum() != 0 else p_tags
123
+ else:
124
+ mod = p_tags
125
+
126
+ pred_bin = (mod >= best_thr).astype(int).reshape(1,-1)
127
+ try: tags = mlb.inverse_transform(pred_bin)[0]
128
+ except: tags = ()
129
+
130
+ return type_lbl, queue_lbl, list(tags)
131
+
132
+ # ------------------- UI -------------------
133
+ st.set_page_config(page_title="Multilingual Ticket Classification")
134
+
135
+ # Background + UI styling + BLACK fonts
136
+ if os.path.exists("bg.jpg"):
137
+ b64 = base64.b64encode(open("bg.jpg","rb").read()).decode()
138
+ st.markdown(f"""
139
+ <style>
140
+ .stApp {{
141
+ background-image: url("data:image/jpg;base64,{b64}");
142
+ background-size: cover;
143
+ }}
144
+ * {{ color: black !important; }}
145
+ .card {{
146
+ background: rgba(255,255,255,0.92);
147
+ border-radius: 12px;
148
+ padding: 22px;
149
+ }}
150
+ </style>
151
+ """, unsafe_allow_html=True)
152
+
153
+ st.markdown("<h1 style='text-align:center;'>Multilingual Ticket Classification</h1>", unsafe_allow_html=True)
154
+ st.markdown("<div class='card'>", unsafe_allow_html=True)
155
+
156
+ message = st.text_area("Enter ticket message:", height=200)
157
+
158
+ if st.button("Predict"):
159
+ if not message.strip():
160
+ st.warning("Please enter a ticket message.")
161
+ else:
162
+ try:
163
+ t, q, tg = infer(message)
164
+ st.subheader("TYPE")
165
+ st.success(t)
166
+
167
+ st.subheader("QUEUE")
168
+ st.success(q)
169
+
170
+ st.subheader("TAGS")
171
+ st.success(", ".join(tg) if tg else "No tags predicted.")
172
+ except Exception:
173
+ st.error("Prediction failed — model or artifacts missing.")
174
+ st.text(traceback.format_exc())
175
+
176
+ st.markdown("</div>", unsafe_allow_html=True)
177
+
178
+ # Invisible debug — exists internally but 100% hidden
179
+ st.markdown("""
180
+ <style>
181
+ div[data-testid="stExpander"] {visibility: hidden; height: 0px;}
182
+ </style>s
183
+ """, unsafe_allow_html=True)
184
+ with st.expander("debug_info_hidden"):
185
+ st.write("hidden diagnostics active")
tokenizer.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2692631d5f5722f104a8042a51a0048d1570c5c2075f57f2ed22f2f54dc2694a
3
+ size 912026