Merge pull request #665 from mvanhorn/tmchow/competitor-roadmap-prediction
fix: hiring-signal company size inference
This commit is contained in:
@@ -44,6 +44,7 @@ htmlcov/
|
|||||||
|
|
||||||
# Internal planning docs (ce:plan output) — keep local, don't publish
|
# Internal planning docs (ce:plan output) — keep local, don't publish
|
||||||
docs/plans/
|
docs/plans/
|
||||||
|
docs/brainstorms/
|
||||||
.context/
|
.context/
|
||||||
|
|
||||||
/work
|
/work
|
||||||
|
|||||||
@@ -96,6 +96,14 @@ def analyze(
|
|||||||
|
|
||||||
def infer_company_size(items: list[schema.SourceItem], *, topic: str = "") -> str:
|
def infer_company_size(items: list[schema.SourceItem], *, topic: str = "") -> str:
|
||||||
"""Infer a coarse company-size tier from jobs evidence."""
|
"""Infer a coarse company-size tier from jobs evidence."""
|
||||||
|
topic_lower = topic.lower()
|
||||||
|
firmographic_text = " ".join(
|
||||||
|
" ".join([
|
||||||
|
str(item.metadata.get("company_size") or ""),
|
||||||
|
topic,
|
||||||
|
])
|
||||||
|
for item in items
|
||||||
|
).lower()
|
||||||
text = " ".join(
|
text = " ".join(
|
||||||
" ".join([
|
" ".join([
|
||||||
item.title,
|
item.title,
|
||||||
@@ -111,9 +119,9 @@ def infer_company_size(items: list[schema.SourceItem], *, topic: str = "") -> st
|
|||||||
# never the job-description body - JDs list enterprise customers (e.g.
|
# never the job-description body - JDs list enterprise customers (e.g.
|
||||||
# "trusted by Microsoft, Google"), which would misclassify a startup as
|
# "trusted by Microsoft, Google"), which would misclassify a startup as
|
||||||
# mega-cap and suppress its real signals.
|
# mega-cap and suppress its real signals.
|
||||||
if re.search(r"\b(apple|uber|google|microsoft|amazon|meta|netflix)\b", topic.lower()):
|
if re.search(r"\b(apple|uber|google|microsoft|amazon|meta|netflix)\b", topic_lower):
|
||||||
return "mega-cap"
|
return "mega-cap"
|
||||||
if count >= 200 or re.search(r"\b(fortune 500|thousands of employees)\b", text):
|
if count >= 200 or re.search(r"\b(fortune 500|thousands of employees)\b", firmographic_text):
|
||||||
return "large-enterprise"
|
return "large-enterprise"
|
||||||
if count >= 35 or re.search(r"\b(series [cd]|public company)\b", text):
|
if count >= 35 or re.search(r"\b(series [cd]|public company)\b", text):
|
||||||
return "growth"
|
return "growth"
|
||||||
|
|||||||
@@ -39,6 +39,23 @@ class HiringSignalsTests(unittest.TestCase):
|
|||||||
self.assertEqual("mega-cap", summary["company_size_tier"])
|
self.assertEqual("mega-cap", summary["company_size_tier"])
|
||||||
self.assertIn("too diffuse", summary["omitted_reason"])
|
self.assertIn("too diffuse", summary["omitted_reason"])
|
||||||
|
|
||||||
|
def test_fortune_500_customer_boilerplate_does_not_make_startup_large_enterprise(self):
|
||||||
|
items = [
|
||||||
|
job(
|
||||||
|
"Founding Enterprise Solutions Engineer",
|
||||||
|
"Help Fortune 500 customers adopt SSO, SOC 2, and procurement workflows.",
|
||||||
|
"Sales",
|
||||||
|
),
|
||||||
|
job(
|
||||||
|
"Security Platform Engineer",
|
||||||
|
"Build enterprise security, audit, and admin workflows for Fortune 500 customers.",
|
||||||
|
"Engineering",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
summary = hiring_signals.analyze(items, explicit=False, topic="Listen Labs")
|
||||||
|
self.assertEqual("startup", summary["company_size_tier"])
|
||||||
|
self.assertTrue(summary["include"])
|
||||||
|
|
||||||
def test_explicit_mode_keeps_low_confidence_signal(self):
|
def test_explicit_mode_keeps_low_confidence_signal(self):
|
||||||
items = [job("Customer Success Manager", "support enterprise customers", "Success")]
|
items = [job("Customer Success Manager", "support enterprise customers", "Success")]
|
||||||
summary = hiring_signals.analyze(items, explicit=True, topic="Acme")
|
summary = hiring_signals.analyze(items, explicit=True, topic="Acme")
|
||||||
|
|||||||
Reference in New Issue
Block a user