pridwimnjha's picture
Upload train_all.py
a2da3c5 verified
Raw
History Blame Contribute Delete
2.49 kB
"""Reproduce training from the source Excel. Run stages in a machine with enough time/RAM.
Produces: vertical_model.joblib, subvertical_model.joblib, parent_map.json
Vertical trains on real verticals only (excludes 'others'); sub-vertical is downsampled per
class for speed. Feature vectorizers are shared across both stages."""
import re, json, gc, joblib
import numpy as np, pandas as pd
from scipy.sparse import hstack
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier
from sklearn.svm import LinearSVC
from sklearn.model_selection import train_test_split
SRC = "Raw_data_vertical_subvertical.xlsx"
clean = lambda s: " ".join(str(s).lower().split())
df = pd.read_excel(SRC, usecols=["category_name","vertical","sub_vertical"], dtype=str).fillna("")
for c in df.columns: df[c] = df[c].str.strip()
df["text"] = df["category_name"].map(clean)
# shared vectorizers, fit on real-vertical text
real = df[df.vertical.str.lower()!="others"]
wv = TfidfVectorizer(analyzer="word", ngram_range=(1,2), min_df=5, max_features=100000,
sublinear_tf=True, dtype=np.float32)
cv = TfidfVectorizer(analyzer="char_wb", ngram_range=(2,4), min_df=5, max_features=100000,
sublinear_tf=True, dtype=np.float32)
wv.fit(real.text); cv.fit(real.text)
vec = lambda s: hstack([wv.transform(s), cv.transform(s)]).tocsr()
# ---- vertical (21-class, probabilistic) ----
vclf = SGDClassifier(loss="log_loss", alpha=2e-6, max_iter=30, tol=1e-4, random_state=42)
vclf.fit(vec(real.text), real.vertical.to_numpy())
joblib.dump({"word_vec":wv,"char_vec":cv,"clf":vclf,"classes":list(vclf.classes_)},
"vertical_model.joblib", compress=3)
# ---- sub-vertical (LinearSVC, downsampled per class) ----
sub = df[(df.vertical.str.lower()!="others") & (df.sub_vertical.str.lower()!="others")]
parent = sub.groupby("sub_vertical")["vertical"].agg(lambda s: s.value_counts().index[0]).to_dict()
json.dump(parent, open("parent_map.json","w"))
CAP=2500; rng=np.random.default_rng(42); idx=[]
for c, g in sub.groupby("sub_vertical"):
ix=g.index.to_numpy()
idx.append(rng.choice(ix,CAP,replace=False) if len(ix)>CAP else ix)
idx=np.concatenate(idx)
s=sub.loc[idx]
sclf=LinearSVC(C=1.0)
sclf.fit(vec(s.text), s.sub_vertical.to_numpy())
joblib.dump({"clf":sclf,"classes":list(sclf.classes_)}, "subvertical_model.joblib", compress=3)
print("done: vertical_model.joblib, subvertical_model.joblib, parent_map.json")