File size: 5,360 Bytes
d4f8959
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# 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))