Spaces:
Sleeping
feat(phase5.1): calibrated keyword extraction — match real ATS checkers
Browse filesUser proved with screenshots that our 95% vs Jobalytics 58% / Simplify 46%
on the same resume. Root cause: scorer self-graded against a NARROW taxonomy
(28 PM terms) that excluded the generic professional vocabulary real checkers
count (development, application, software, solutions, market).
Fix:
- Added GENERIC_PROFESSIONAL_VOCAB (~120 terms real checkers count) — broadens
extraction to match Jobalytics breadth (~36 kw vs their 32) WITHOUT counting
proper-noun noise (company/location/ticker still excluded — not in any set).
- _collapse_redundant_keywords: lemma-dedup + drop single words subsumed by
phrases (product ⊂ product strategy, backlog ⊂ backlog grooming) so our
count tracks real checkers instead of inflating to 40+.
- Tightened multiword phrase matching: in-order with max 2-token gap (was
loose any-order 5-token window that over-matched and inflated our score).
Results:
- Old (9) Experian resume (narrow-set, old build): 95 -> 78 on new scorer
(it genuinely contains 27/36 kw; Jobalytics' 58 differs by keyword SET,
which is proprietary — we can't match exactly, only directionally).
- FRESH Experian resume via current pipeline: 89/100, now covers the generic
terms (development/software/solutions/application) the old build missed —
exactly the terms Jobalytics penalized. Should score far above 58 on a
real re-check.
Honest limitation documented: exact ±10 match to any one checker isn't
achievable (they're proprietary and disagree with each other by 12pts).
Real proof = run a FRESH resume through Jobalytics, not the old (9).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- src/ats_scorer.py +136 -22
- tests/fixtures/jds/experian_tpo.txt +16 -0
- tests/fixtures/resumes/experian_current.txt +45 -0
|
@@ -207,6 +207,61 @@ def _is_taxonomy_skill(token_or_phrase: str) -> bool:
|
|
| 207 |
return False
|
| 208 |
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
# ── Rules-based lemmatizer (no NLTK dependency, deterministic on HF Spaces) ──
|
| 211 |
|
| 212 |
# Order matters: longer suffixes first so we don't strip "s" before "ses".
|
|
@@ -314,11 +369,30 @@ def _phrase_in_text(phrase: str, text: str, _cached_lemmas: List[str] = None) ->
|
|
| 314 |
if len(p_lemmas) == 1:
|
| 315 |
return p_lemmas[0] in t_lemmas
|
| 316 |
|
| 317 |
-
# Multi-word:
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
return True
|
| 323 |
return False
|
| 324 |
|
|
@@ -636,42 +710,45 @@ def extract_jd_keywords(jd_text: str) -> List[str]:
|
|
| 636 |
text = jd_text.lower()
|
| 637 |
keywords: list[str] = []
|
| 638 |
|
| 639 |
-
# ──
|
| 640 |
-
#
|
| 641 |
-
#
|
| 642 |
-
#
|
| 643 |
-
#
|
| 644 |
-
#
|
| 645 |
|
| 646 |
# 1. Multi-word skill phrases first (longest-first to avoid double-count)
|
| 647 |
-
consumed_spans: list[tuple] = []
|
| 648 |
for phrase in PM_SKILL_PHRASES:
|
| 649 |
-
# Word-boundary phrase search
|
| 650 |
for m in re.finditer(r"(?<!\w)" + re.escape(phrase) + r"(?!\w)", text):
|
| 651 |
span = (m.start(), m.end())
|
| 652 |
-
# Skip if overlaps an already-consumed (longer) phrase
|
| 653 |
if any(span[0] < e and s < span[1] for (s, e) in consumed_spans):
|
| 654 |
continue
|
| 655 |
consumed_spans.append(span)
|
| 656 |
keywords.append(phrase)
|
| 657 |
-
break
|
| 658 |
|
| 659 |
-
# 2. Single-word taxonomy tokens
|
| 660 |
for token in PM_SKILL_TAXONOMY:
|
| 661 |
if " " in token or "/" in token or "→" in token or "-" in token:
|
| 662 |
-
continue
|
| 663 |
if re.search(r"(?<!\w)" + re.escape(token) + r"(?!\w)", text):
|
| 664 |
keywords.append(token)
|
| 665 |
|
| 666 |
-
# 3.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 667 |
for pat in _TAXONOMY_PATTERNS:
|
| 668 |
for m in pat.finditer(text):
|
| 669 |
-
kw = m.group().strip().lower()
|
| 670 |
-
kw = re.sub(r"\s+", " ", kw)
|
| 671 |
keywords.append(kw)
|
| 672 |
|
| 673 |
-
# Deduplicate
|
| 674 |
-
# already guarantees every entry is a real skill.
|
| 675 |
seen = set()
|
| 676 |
unique = []
|
| 677 |
for kw in keywords:
|
|
@@ -680,9 +757,46 @@ def extract_jd_keywords(jd_text: str) -> List[str]:
|
|
| 680 |
seen.add(kw)
|
| 681 |
unique.append(kw)
|
| 682 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 683 |
return unique[:40]
|
| 684 |
|
| 685 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 686 |
def _kw_in_text(keyword: str, text: str) -> bool:
|
| 687 |
"""
|
| 688 |
Lemma + phrase aware matching.
|
|
|
|
| 207 |
return False
|
| 208 |
|
| 209 |
|
| 210 |
+
# ─────────────────────────────────────────────────────────────────────────
|
| 211 |
+
# GENERIC PROFESSIONAL VOCABULARY — the terms real ATS checkers (Jobalytics,
|
| 212 |
+
# Simplify, JobScan) count that our skill taxonomy deliberately excluded.
|
| 213 |
+
#
|
| 214 |
+
# These are NOT PM-specific skills, but they ARE legitimate professional
|
| 215 |
+
# words that appear in JDs and that real checkers extract as keywords
|
| 216 |
+
# (Jobalytics counted "development", "application", "software", "solutions",
|
| 217 |
+
# "market" for the Experian JD). Including them is what makes our score
|
| 218 |
+
# track real checkers. They are safe to carry in a resume (a PM resume
|
| 219 |
+
# naturally says "product development", "software solutions", "go-to-market").
|
| 220 |
+
#
|
| 221 |
+
# Proper-noun noise (company names, locations, tickers) is STILL excluded
|
| 222 |
+
# because it's in neither this set nor the taxonomy.
|
| 223 |
+
# ─────────────────────────────────────────────────────────────────────────
|
| 224 |
+
GENERIC_PROFESSIONAL_VOCAB = {
|
| 225 |
+
# Work/output nouns
|
| 226 |
+
"development", "design", "engineering", "implementation", "delivery",
|
| 227 |
+
"execution", "deployment", "operations", "maintenance", "support",
|
| 228 |
+
"documentation", "testing", "validation", "monitoring", "reporting",
|
| 229 |
+
"planning", "management", "administration", "coordination", "facilitation",
|
| 230 |
+
# Product/tech nouns
|
| 231 |
+
"software", "application", "applications", "platform", "platforms",
|
| 232 |
+
"system", "systems", "technology", "technologies", "infrastructure",
|
| 233 |
+
"architecture", "solution", "solutions", "product", "products", "feature",
|
| 234 |
+
"features", "module", "modules", "tool", "tools", "service", "services",
|
| 235 |
+
"data", "database", "databases", "dashboard", "dashboards", "interface",
|
| 236 |
+
"integration", "integrations", "pipeline", "pipelines", "workflow",
|
| 237 |
+
"workflows", "framework", "frameworks", "environment", "release",
|
| 238 |
+
# Business nouns
|
| 239 |
+
"market", "business", "strategy", "growth", "revenue", "customer",
|
| 240 |
+
"customers", "user", "users", "stakeholder", "stakeholders", "team",
|
| 241 |
+
"teams", "process", "processes", "quality", "performance", "efficiency",
|
| 242 |
+
"impact", "outcome", "outcomes", "initiative", "initiatives", "project",
|
| 243 |
+
"projects", "program", "programs", "portfolio", "roadmap", "vision",
|
| 244 |
+
"requirements", "specification", "specifications", "scope", "priorities",
|
| 245 |
+
"prioritization", "metrics", "kpis", "analytics", "insights", "research",
|
| 246 |
+
"experimentation", "optimization", "automation", "innovation",
|
| 247 |
+
# Collaboration / methodology nouns
|
| 248 |
+
"collaboration", "communication", "leadership", "ownership", "mentoring",
|
| 249 |
+
"agile", "scrum", "sprint", "iteration", "backlog", "discovery",
|
| 250 |
+
"launch", "lifecycle", "feedback", "alignment", "governance",
|
| 251 |
+
# Domain-adjacent (kept generic)
|
| 252 |
+
"cloud", "api", "apis", "frontend", "backend", "fullstack", "mobile",
|
| 253 |
+
"web", "ml", "ai", "ux", "ui",
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def _is_professional_term(token_or_phrase: str) -> bool:
|
| 258 |
+
"""True if the term is a real skill OR generic professional vocabulary."""
|
| 259 |
+
t = token_or_phrase.strip().lower()
|
| 260 |
+
if not t:
|
| 261 |
+
return False
|
| 262 |
+
return _is_taxonomy_skill(t) or t in GENERIC_PROFESSIONAL_VOCAB
|
| 263 |
+
|
| 264 |
+
|
| 265 |
# ── Rules-based lemmatizer (no NLTK dependency, deterministic on HF Spaces) ──
|
| 266 |
|
| 267 |
# Order matters: longer suffixes first so we don't strip "s" before "ses".
|
|
|
|
| 369 |
if len(p_lemmas) == 1:
|
| 370 |
return p_lemmas[0] in t_lemmas
|
| 371 |
|
| 372 |
+
# Multi-word: require the phrase lemmas to appear IN ORDER within a tight
|
| 373 |
+
# window (matches how real ATS checkers score phrases — they want the
|
| 374 |
+
# actual phrase, not its words scattered across the resume). A loose
|
| 375 |
+
# any-order 5-token window over-matched and inflated our score vs real
|
| 376 |
+
# checkers; in-order with a small gap is stricter and calibrated.
|
| 377 |
+
n = len(p_lemmas)
|
| 378 |
+
max_gap = 2 # allow up to 2 filler tokens between phrase words
|
| 379 |
+
for i in range(len(t_lemmas)):
|
| 380 |
+
if t_lemmas[i] != p_lemmas[0]:
|
| 381 |
+
continue
|
| 382 |
+
# Try to match the rest in order, allowing small gaps
|
| 383 |
+
pos = i + 1
|
| 384 |
+
matched = 1
|
| 385 |
+
for target_lemma in p_lemmas[1:]:
|
| 386 |
+
found_at = None
|
| 387 |
+
for j in range(pos, min(pos + max_gap + 1, len(t_lemmas))):
|
| 388 |
+
if t_lemmas[j] == target_lemma:
|
| 389 |
+
found_at = j
|
| 390 |
+
break
|
| 391 |
+
if found_at is None:
|
| 392 |
+
break
|
| 393 |
+
matched += 1
|
| 394 |
+
pos = found_at + 1
|
| 395 |
+
if matched == n:
|
| 396 |
return True
|
| 397 |
return False
|
| 398 |
|
|
|
|
| 710 |
text = jd_text.lower()
|
| 711 |
keywords: list[str] = []
|
| 712 |
|
| 713 |
+
# ── CALIBRATED extraction (Phase 5) ──
|
| 714 |
+
# Matches what real ATS checkers (Jobalytics/Simplify) count: PM skills
|
| 715 |
+
# PLUS generic professional vocabulary (development/application/software/
|
| 716 |
+
# solutions/market…). Proper-noun noise (company names, locations,
|
| 717 |
+
# tickers) is still excluded because it's in NEITHER the taxonomy NOR the
|
| 718 |
+
# generic professional vocab.
|
| 719 |
|
| 720 |
# 1. Multi-word skill phrases first (longest-first to avoid double-count)
|
| 721 |
+
consumed_spans: list[tuple] = []
|
| 722 |
for phrase in PM_SKILL_PHRASES:
|
|
|
|
| 723 |
for m in re.finditer(r"(?<!\w)" + re.escape(phrase) + r"(?!\w)", text):
|
| 724 |
span = (m.start(), m.end())
|
|
|
|
| 725 |
if any(span[0] < e and s < span[1] for (s, e) in consumed_spans):
|
| 726 |
continue
|
| 727 |
consumed_spans.append(span)
|
| 728 |
keywords.append(phrase)
|
| 729 |
+
break
|
| 730 |
|
| 731 |
+
# 2. Single-word taxonomy tokens (high-signal PM skills)
|
| 732 |
for token in PM_SKILL_TAXONOMY:
|
| 733 |
if " " in token or "/" in token or "→" in token or "-" in token:
|
| 734 |
+
continue
|
| 735 |
if re.search(r"(?<!\w)" + re.escape(token) + r"(?!\w)", text):
|
| 736 |
keywords.append(token)
|
| 737 |
|
| 738 |
+
# 3. Generic professional vocabulary present in the JD — this is the
|
| 739 |
+
# Phase 5 broadening that makes our score track real checkers. These are
|
| 740 |
+
# the words Jobalytics/Simplify count that our taxonomy alone missed.
|
| 741 |
+
for token in GENERIC_PROFESSIONAL_VOCAB:
|
| 742 |
+
if re.search(r"(?<!\w)" + re.escape(token) + r"(?!\w)", text):
|
| 743 |
+
keywords.append(token)
|
| 744 |
+
|
| 745 |
+
# 4. Regex-pattern skills (a/b testing variants, "0 to 1", etc.)
|
| 746 |
for pat in _TAXONOMY_PATTERNS:
|
| 747 |
for m in pat.finditer(text):
|
| 748 |
+
kw = re.sub(r"\s+", " ", m.group().strip().lower())
|
|
|
|
| 749 |
keywords.append(kw)
|
| 750 |
|
| 751 |
+
# Deduplicate exact repeats
|
|
|
|
| 752 |
seen = set()
|
| 753 |
unique = []
|
| 754 |
for kw in keywords:
|
|
|
|
| 757 |
seen.add(kw)
|
| 758 |
unique.append(kw)
|
| 759 |
|
| 760 |
+
# Collapse redundancy so our count tracks real checkers (~32, not 40):
|
| 761 |
+
# - lemma-equal singular/plural (stakeholder/stakeholders,
|
| 762 |
+
# application/applications, solution/solutions)
|
| 763 |
+
# - single-word token subsumed by a multiword phrase already present
|
| 764 |
+
# (product ⊂ product strategy; backlog ⊂ backlog grooming;
|
| 765 |
+
# agile ⊂ agile/scrum; discovery ⊂ product discovery)
|
| 766 |
+
unique = _collapse_redundant_keywords(unique)
|
| 767 |
+
|
| 768 |
return unique[:40]
|
| 769 |
|
| 770 |
|
| 771 |
+
def _collapse_redundant_keywords(keywords: List[str]) -> List[str]:
|
| 772 |
+
"""Collapse lemma-duplicate and phrase-subsumed keywords."""
|
| 773 |
+
# 1. Lemma-dedup: group by lemma-of-each-word, keep longest surface form
|
| 774 |
+
best_by_key: dict = {}
|
| 775 |
+
order: list = []
|
| 776 |
+
for kw in keywords:
|
| 777 |
+
k = " ".join(_lemma(w) for w in re.split(r"[\s/]+", kw.lower()))
|
| 778 |
+
if k not in best_by_key:
|
| 779 |
+
best_by_key[k] = kw
|
| 780 |
+
order.append(k)
|
| 781 |
+
elif len(kw) > len(best_by_key[k]):
|
| 782 |
+
best_by_key[k] = kw
|
| 783 |
+
deduped = [best_by_key[k] for k in order]
|
| 784 |
+
|
| 785 |
+
# 2. Drop a single-word kw if it's a token inside any multiword kw
|
| 786 |
+
multiword_tokens = set()
|
| 787 |
+
for kw in deduped:
|
| 788 |
+
parts = re.split(r"[\s/]+", kw.lower())
|
| 789 |
+
if len(parts) > 1:
|
| 790 |
+
multiword_tokens.update(parts)
|
| 791 |
+
final = []
|
| 792 |
+
for kw in deduped:
|
| 793 |
+
parts = re.split(r"[\s/]+", kw.lower())
|
| 794 |
+
if len(parts) == 1 and parts[0] in multiword_tokens:
|
| 795 |
+
continue # subsumed by a phrase
|
| 796 |
+
final.append(kw)
|
| 797 |
+
return final
|
| 798 |
+
|
| 799 |
+
|
| 800 |
def _kw_in_text(keyword: str, text: str) -> bool:
|
| 801 |
"""
|
| 802 |
Lemma + phrase aware matching.
|
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Technical Product Owner — Experian
|
| 2 |
+
Location: Hyderabad / Dublin
|
| 3 |
+
|
| 4 |
+
Company Description
|
| 5 |
+
Experian is a global data and technology company, powering opportunities for people and businesses around the world. We help redefine lending practices, uncover and prevent fraud, simplify healthcare, create marketing solutions, and gain deeper insights into the automotive market, all using our unique combination of data, analytics and software.
|
| 6 |
+
|
| 7 |
+
Role
|
| 8 |
+
We seek a Technical Product Owner to drive product development on the Ascend cloud platform. Define product strategy, write user stories and epics, manage the product backlog, run agile ceremonies, and partner with engineering, design, and stakeholders across sprints. Build software solutions and applications. Conduct analytics and product discovery. Use Jira, Confluence, and Aha for backlog management.
|
| 9 |
+
|
| 10 |
+
Requirements
|
| 11 |
+
- 5+ years product management or product owner experience
|
| 12 |
+
- Agile/scrum, sprint planning, backlog grooming
|
| 13 |
+
- Jira, Confluence, Aha
|
| 14 |
+
- Stakeholder management, analytics, product lifecycle, acceptance criteria
|
| 15 |
+
- Cloud, microservices, software development
|
| 16 |
+
- Credit, lending, insurance, fraud domain a plus
|
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SAITEJA TIRUNAGARI
|
| 2 |
+
+91 9988996588 · saitejatirunagari@gmail.com · linkedin.com/in/saitejatirunagari
|
| 3 |
+
PROFESSIONAL SUMMARY
|
| 4 |
+
Strong-fit candidate for Technical Product Owner at Experian: 5+ years of PM experience directly applicable to this role. AI-first Product Manager with 5+ years driving 0→1 product development in fast-paced EdTech startups. Proven record building digital acquisition funnels, automation pipelines, and AI-powered tools that have processed 140,000+ users and contributed to 2× revenue growth. Deep expertise in conversational AI, OCR automation, funnel optimization, A/B experimentation, and cross- functional delivery. Combines data-driven decision-making with user-centric design to ship measurable outcomes—from +35 pp payment conversion lifts to 3.8× report engagement jumps. Toolchain and domain coverage includes Microservices, Lending, Aha, Cloud, Epics, Epic, Insurance, Ceremonies, Credit, Fraud, and Marketing.
|
| 5 |
+
PROFESSIONAL EXPERIENCE
|
| 6 |
+
Internal Product Manager
|
| 7 |
+
NxtWave Disruptive Technologies Pvt. Ltd. · Hyderabad, India · Jan 2023 – Present
|
| 8 |
+
Led end-to-end revamp of NIAT Application Portal—a unified digital funnel covering landing pages → OTP login → personal details → payment → slot booking → exam → report → sales flow—integrated with CRM, WebEngage, and payment systems; aligned with Sprint Planning workflows.
|
| 9 |
+
Scaled to 141,269 OTP-verified leads; achieved 97% personal-details completion and 95% exam-attendance rate across 23,983 attendees, with 210 final enrollments — including Sprint integration.
|
| 10 |
+
Maintained ₹1,120+ Cr annual pipeline value across 8,000+ processed applications
|
| 11 |
+
Introduced contextual loaders and UX refinements, eliminating idle wait perception and reducing early-stage drop-offs, partnering on Backlog.
|
| 12 |
+
Implemented coupon-based urgency logic in the payment flow, lifting 0–60 min payment completion from 27.37% → 63.24% (+35.87 pp) for coupon users
|
| 13 |
+
Improved overall funnel payment conversion by +6.98 pp, accelerating time-to-revenue with near-zero acquisition cost increase
|
| 14 |
+
Redesigned the NIAT landing-page AI chatbot into a structured conversion engine with stage-wise decision trees and CRM- integrated nudges aligned to every funnel milestone (lead → application → payment → exam → enrollment)
|
| 15 |
+
Generated 6,776 leads and 113 enrollments via chatbot-driven funnel; chatbot independently sourced 1,744 leads and 440 applications
|
| 16 |
+
Asst. Product Success Manager – User Experience
|
| 17 |
+
Think & Learn Pvt. Ltd. (BYJU'S) · Bengaluru, India · Oct 2021 – Dec 2022
|
| 18 |
+
Managed 20 customer-success specialists covering 40,000 customers; maintained refund rate below 5% and customer satisfaction above 95%
|
| 19 |
+
Played 0→1 role in Xplore Experiment and Social Emotional Learning pilot projects alongside product and engineering teams — leveraging Product Lifecycle.
|
| 20 |
+
Sustained 95%+ Monthly Recurring Revenue from existing EMI customers through proactive retention strategies
|
| 21 |
+
Designed robust processes and drove adherence across teams to ensure consistent execution and sustainable growth; aligned with Acceptance Criteria workflows.
|
| 22 |
+
Created comprehensive customer documentation and educated users on new product capabilities and technical feasibility; aligned with Stakeholder Management workflows.
|
| 23 |
+
Product Specialist – User Experience
|
| 24 |
+
Think & Learn Pvt. Ltd. (BYJU'S) · Bengaluru, India · Aug 2019 – Sep 2021
|
| 25 |
+
Increased user retention by 8% by redesigning the onboarding process using UX research and user-centric principles, partnering on Confluence.
|
| 26 |
+
Conducted extensive UX research and A/B testing to identify pain points and refine features, improving learning-platform engagement
|
| 27 |
+
Mentored students throughout their academic journey using multi-channel communication; monitored performance dashboards and shared progress reports with stakeholders — including User Stories integration.
|
| 28 |
+
Founder & CEO
|
| 29 |
+
ML Edutech · Hyderabad, India · Aug 2015 – Jul 2019
|
| 30 |
+
Launched EdTech app portfolio of 275 apps with 3 million+ cumulative downloads; aligned with Agile workflows.
|
| 31 |
+
Drove user acquisition through Google Ads, LinkedIn, and paid social; established strategic partnerships and managed end-to- end P&L — leveraging Jira.
|
| 32 |
+
Built a performance-driven culture focused on conversion optimization, data-driven decision-making, and sustainable growth, partnering on Analytics.
|
| 33 |
+
KEY ACHIEVEMENTS
|
| 34 |
+
141,269 OTP-verified leads processed through rebuilt NIAT Application Portal (2026 cycle)
|
| 35 |
+
2× business revenue growth in <9 months via automation and AI-powered funnel optimization
|
| 36 |
+
Payment conversion: 27.37% → 63.24% (+35.87 pp) for coupon users · Overall lift +6.98 pp
|
| 37 |
+
₹1,120+ Cr annual pipeline managed across 8,000+ applications
|
| 38 |
+
8,000+ admissions applications processed; ₹45,600 offline exam revenue from 1,503 paid users
|
| 39 |
+
EDUCATION
|
| 40 |
+
Diploma – Product & Brand Management
|
| 41 |
+
IIM Rohtak · Mar 2023 – Sep 2023
|
| 42 |
+
Diploma in Business Management
|
| 43 |
+
Osmania University, Hyderabad · Aug 2015 – Jul 2019
|
| 44 |
+
Bachelor of Engineering – Civil Engineering
|
| 45 |
+
JNTU Hyderabad · Aug 2011 – Sep 2016
|