FinSight / backend /sector.py
Sanjam19's picture
Deploy FinSight demo (single-container Docker Space)
d4f8959 verified
Raw
History Blame Contribute Delete
5.36 kB
# backend/sector.py
"""
Sector classification by keyword scoring. A document is classified into
the sector with the most keyword hits in its first ~50k characters,
provided that sector clears a minimum match threshold β€” otherwise it
falls back to GENERAL rather than guessing off a single weak signal.
NOTE: this is a reconstruction written after the original file was lost
to a local backup/restore mishap. Keyword lists below are reasonable,
broad coverage for each sector but have NOT been tuned against as many
real filings as a hand-refined version would be β€” if you still have your
original tuned keyword lists anywhere (old terminal output, a teammate's
copy, git history), send them over and they can be merged in.
One deliberate improvement vs. likely-original: ENERGY's keyword list is
broadened to cover diversified conglomerates (oil-to-chemicals, refining,
petrochemicals, E&P language) plus major company-name anchors β€” this
directly targets a real issue found this session, where a large Indian
energy/conglomerate filing (Reliance Industries) was falling through to
GENERAL because its actual business-description language didn't match a
narrower oil/gas-only keyword set.
"""
SECTOR_KEYWORDS = {
"BANK": [
"bank", "npa", "casa", "deposits", "advances", "net interest margin",
"net interest income", "capital adequacy", "scheduled commercial bank",
"rbi", "gross npa", "net npa", "provision coverage ratio",
"hdfc", "icici", "axis bank", "kotak", "state bank of india", "sbi",
"idfc", "yes bank", "punjab national bank", "bank of baroda",
],
"IT": [
"software", "it services", "information technology", "software exports",
"attrition", "offshore", "onsite", "billing rate", "digital transformation",
"cloud services", "outsourcing", "software development",
"tcs", "tata consultancy", "infosys", "wipro", "hcl tech", "hcltech",
"tech mahindra", "ltimindtree", "mindtree", "cognizant",
],
"PHARMA": [
"pharma", "pharmaceutical", "drug", "formulation", "api",
"active pharmaceutical ingredient", "clinical trial", "fda", "usfda",
"generic drugs", "drug approval", "anda", "molecule",
"sun pharma", "cipla", "dr reddy", "dr. reddy", "lupin", "divis labs",
"aurobindo", "biocon", "torrent pharma",
],
"ENERGY": [
"oil", "gas", "refinery", "refining", "petrochemical", "petrochemicals",
"exploration", "e&p", "upstream", "downstream", "crude oil", "lng",
"natural gas", "oil to chemicals", "fuel retail", "energy transition",
"barrels", "feedstock", "cracker", "polymer", "polyester",
"reliance industries", "reliance", "ongc", "bpcl", "hpcl", "iocl",
"indian oil", "ntpc", "adani green", "adani power", "gail",
],
"MANUFACTURING": [
"manufacturing", "plant capacity", "factory", "production volume",
"capacity utilization", "automobile", "automotive", "steel",
"cement", "assembly line", "vehicles sold", "production facility",
"tata motors", "maruti suzuki", "jsw steel", "tata steel",
"ultratech cement", "bajaj auto", "hero motocorp", "mahindra",
],
}
# minimum keyword hits required before trusting a sector classification
# over the GENERAL fallback
MIN_MATCH_THRESHOLD = 3
# how much of the document (chars) to scan for sector signal β€” business
# description / MD&A language is almost always in the early pages, no
# need to scan the full document for this
SCAN_LIMIT = 50_000
def detect_sector(text: str) -> str:
"""Returns the best-matching sector name, or 'GENERAL' if no sector
clears the minimum keyword-match threshold."""
sample = text[:SCAN_LIMIT].lower()
scores = {}
for sector, keywords in SECTOR_KEYWORDS.items():
scores[sector] = sum(1 for kw in keywords if kw in sample)
best_sector = max(scores, key=scores.get)
if scores[best_sector] >= MIN_MATCH_THRESHOLD:
return best_sector
return "GENERAL"
if __name__ == "__main__":
bank_text = """
HDFC Bank reported total income of Rs 250,000 crore for FY2024.
Gross NPA ratio was 1.24%. CASA ratio stood at 38.2%.
Capital adequacy ratio was 19.3% as per RBI guidelines.
"""
print("Bank test ->", detect_sector(bank_text))
it_text = """
TCS reported revenue from operations of Rs 240,893 crore for FY2024.
Attrition rate stood at 12.5%. The company continues to grow its
offshore and onsite delivery model across IT services.
"""
print("IT test ->", detect_sector(it_text))
ril_text = """
Reliance Industries Limited is India's largest private sector
company, with businesses spanning oil to chemicals, oil and gas
exploration, petrochemicals, refining, and digital services.
The O2C (oil to chemicals) segment includes refining and
petrochemical operations at the Jamnagar refinery complex.
"""
print("RIL/Energy test ->", detect_sector(ril_text))
generic_text = """
This document discusses general corporate matters without any
sector-specific language at all, just generic business updates.
"""
print("Generic test ->", detect_sector(generic_text))