Indonesian Skill Extractor v1.0
A production-ready, rule-based NER system for extracting and categorizing technical and soft skills from Indonesian job postings.
🎯 Model Description
This model specializes in identifying and categorizing skills from Indonesian job market texts. It uses a comprehensive skill taxonomy with 200+ predefined skills across 7 categories, combined with intelligent pattern matching and normalization.
Key Features
- ✅ Zero Dependencies: Pure Python, no ML frameworks required
- ✅ 200+ Skills: Comprehensive taxonomy across 7 categories
- ✅ Bilingual: Handles English and Indonesian (including code-switching)
- ✅ Skill Normalization: Maps aliases to canonical forms (js→javascript, etc.)
- ✅ Proficiency Detection: Identifies beginner/intermediate/expert levels
- ✅ Fast & Deterministic: 1000+ docs/sec, reproducible results
- ✅ Production Ready: Lightweight (~20 KB), easy integration
Skill Categories
| Category | Count | Examples |
|---|
| programming | 30+ | Python, Java, JavaScript, TypeScript, PHP, C++, Go, Rust |
| frontend | 40+ | React, Vue, Angular, Next.js, HTML, CSS, Tailwind, Webpack |
| backend | 30+ | Node.js, Django, Laravel, Spring Boot, Express, FastAPI |
| database | 25+ | MySQL, PostgreSQL, MongoDB, Redis, Elasticsearch, Oracle |
| cloud | 35+ | AWS, Azure, GCP, Docker, Kubernetes, Jenkins, Terraform |
| data_science | 30+ | Pandas, TensorFlow, PyTorch, Tableau, Power BI, Spark |
| soft_skills | 20+ | Communication, Leadership, Teamwork, Problem Solving |
Total: 200+ skills with 40+ aliases and variations
🚀 Quick Start
Installation
No installation required! Just download the single Python file:
1# Download skill_extractor.py from this repository
2# Place it in your project directory
3from skill_extractor import IndonesianSkillExtractor
4
5# Or use convenience function
6from skill_extractor import extract_skills
Basic Usage
1from skill_extractor import IndonesianSkillExtractor
2
3# Initialize
4extractor = IndonesianSkillExtractor()
5
6# Extract skills from text
7text = "Menguasai Python, React, MySQL, dan komunikasi yang baik"
8result = extractor.extract(text)
9
10print(result)
11# Output:
12# {
13# 'skills': [
14# {'original': 'Python', 'normalized': 'python', 'category': 'programming', 'proficiency': None},
15# {'original': 'React', 'normalized': 'react', 'category': 'frontend', 'proficiency': None},
16# {'original': 'MySQL', 'normalized': 'mysql', 'category': 'database', 'proficiency': None},
17# {'original': 'komunikasi', 'normalized': 'komunikasi', 'category': 'soft_skills', 'proficiency': None}
18# ],
19# 'total_count': 4,
20# 'unique_count': 4,
21# 'by_category': {
22# 'programming': [...],
23# 'frontend': [...],
24# 'database': [...],
25# 'soft_skills': [...]
26# }
27# }
Simple Extraction
1from skill_extractor import extract_skills
2
3# Quick extraction (returns list of skill names)
4skills = extract_skills("Python, React, MySQL, AWS")
5print(skills)
6# Output: ['python', 'react', 'mysql', 'aws']
Batch Processing
1extractor = IndonesianSkillExtractor()
2
3texts = [
4 "Python, Django, PostgreSQL",
5 "React, TypeScript, Node.js",
6 "AWS, Docker, Kubernetes"
7]
8
9results = extractor.batch_extract(texts)
10
11for i, result in enumerate(results):
12 print(f"Text {i+1}: {result['total_count']} skills, {len(result['by_category'])} categories")
Get Top Skills
1extractor = IndonesianSkillExtractor()
2
3job_descriptions = [
4 "Python, Django, React...",
5 "Java, Spring, MySQL...",
6 "Python, FastAPI, PostgreSQL..."
7]
8
9top_skills = extractor.get_top_skills(job_descriptions, top_n=5)
10print(top_skills)
11# Output: [('python', 2), ('react', 1), ('django', 1), ...]
📊 Features
1. Skill Normalization
Handles variations and aliases:
1extractor = IndonesianSkillExtractor()
2
3# These all normalize to the same skill
4texts = ["JS", "js", "JavaScript", "javascript"]
5for text in texts:
6 skills = extract_skills(text)
7 print(skills) # All output: ['javascript']
40+ Aliases Supported:
- js → javascript
- ts → typescript
- py → python
- reactjs, react.js → react
- nodejs → node.js
- pg, postgres → postgresql
- mongo → mongodb
- k8s → kubernetes
2. Proficiency Detection
Extracts skill levels from text:
1text = "Expert in Python, Advanced React, Basic MySQL"
2result = extractor.extract(text)
3
4for skill in result['skills']:
5 print(f"{skill['normalized']}: {skill['proficiency']}")
6
7# Output:
8# python: expert
9# react: expert (advanced maps to expert)
10# mysql: beginner (basic maps to beginner)
Proficiency Keywords:
- Expert: expert, advanced, mahir, ahli, mastery
- Intermediate: intermediate, menengah, competent
- Beginner: beginner, basic, pemula, dasar
3. Indonesian Language Support
Handles Indonesian skill names and code-switching:
1text = "Komunikasi yang baik, kerja sama tim, kepemimpinan, Python"
2result = extractor.extract(text)
3
4for skill in result['skills']:
5 print(f"{skill['original']} → {skill['category']}")
6
7# Output:
8# Komunikasi → soft_skills
9# kerja sama tim → soft_skills
10# kepemimpinan → soft_skills (leadership)
11# Python → programming
4. Comprehensive Parsing
Handles multiple formats:
1# Comma-separated
2extract_skills("Python, React, MySQL")
3
4# Semicolon-separated
5extract_skills("Python; React; MySQL")
6
7# Bullet points
8extract_skills("• Python • React • MySQL")
9
10# Newline-separated
11extract_skills("Python\nReact\nMySQL")
12
13# Mixed with proficiency
14extract_skills("Python (Expert), React (2 years), MySQL")
📈 Performance
| Metric | Value |
|---|
| Speed | 1000+ docs/second |
| Model Size | ~20 KB (pure Python) |
| Dependencies | None (stdlib only) |
| Skills Covered | 200+ |
| Categories | 7 |
| Aliases | 40+ |
| Languages | Indonesian + English |
Comparison with ML Models
| Feature | Skill Extractor | BERT-based NER |
|---|
| Training Data | Not required | Required (1000+ samples) |
| Model Size | 20 KB | 300+ MB |
| Speed | 1000+ docs/sec | 50 docs/sec |
| Deterministic | ✅ Yes | ❌ No |
| Explainable | ✅ Yes | ❌ No |
| Easy to Update | ✅ Just edit dict | ❌ Requires retraining |
🎯 Use Cases
1. Job-Candidate Matching
1# Extract skills from job posting
2job_skills = extract_skills(job_description)
3
4# Extract skills from resume
5candidate_skills = extract_skills(resume_text)
6
7# Calculate match percentage
8matching_skills = set(job_skills) & set(candidate_skills)
9match_score = len(matching_skills) / len(job_skills) * 100
2. Skills Gap Analysis
1# Get market demand
2market_skills = extractor.get_top_skills(job_postings, top_n=20)
3
4# Get candidate pool skills
5candidate_skills = extractor.get_top_skills(resumes, top_n=20)
6
7# Find gaps
8in_demand = set(s[0] for s in market_skills)
9available = set(s[0] for s in candidate_skills)
10skill_gaps = in_demand - available
3. Trend Analysis
1from collections import Counter
2
3# Group by time period
4skills_by_month = {}
5for job in jobs:
6 month = job['month']
7 skills = extract_skills(job['requirements'])
8
9 if month not in skills_by_month:
10 skills_by_month[month] = []
11 skills_by_month[month].extend(skills)
12
13# Analyze trends
14for month, skills in skills_by_month.items():
15 top_5 = Counter(skills).most_common(5)
16 print(f"{month}: {top_5}")
4. Resume Screening
1required_skills = ['python', 'django', 'postgresql']
2nice_to_have = ['react', 'docker', 'aws']
3
4def score_resume(resume_text):
5 candidate_skills = set(extract_skills(resume_text))
6
7 # Required skills (2 points each)
8 required_score = len(candidate_skills & set(required_skills)) * 2
9
10 # Nice to have (1 point each)
11 bonus_score = len(candidate_skills & set(nice_to_have)) * 1
12
13 return required_score + bonus_score
14
15# Rank candidates
16candidates = [...]
17ranked = sorted(candidates, key=lambda c: score_resume(c['resume']), reverse=True)
🔧 API Reference
IndonesianSkillExtractor
Main class for skill extraction.
Methods:
extract(text: str) -> Dict
- Full extraction with metadata
- Returns: skills, counts, categories, proficiency
extract_simple(text: str) -> List[str]
- Simple extraction returning skill names
- Returns: List of normalized skill strings
batch_extract(texts: List[str]) -> List[Dict]
- Process multiple texts
- Returns: List of extraction results
get_top_skills(texts: List[str], top_n: int) -> List[Tuple]
- Get most frequent skills across texts
- Returns: List of (skill, count) tuples
get_stats() -> Dict
- Get model statistics
- Returns: version, total_skills, categories, etc.
Convenience Functions
extract_skills(text: str) -> List[str]
- Quick one-line extraction
- Creates extractor instance automatically
📄 License
This model is released under the MIT License.
Citation:
1@software{indonesian_skill_extractor_2024,
2 author = {Herlambang Haryo Putro},
3 title = {Indonesian Skill Extractor v1.0},
4 year = {2024},
5 publisher = {Hugging Face},
6 url = {https://huggingface.co/herlambangharyoputro/indonesian-skill-extractor-v1}
7}
🤝 Contributions
Part of the Job Market Intelligence Platform project.
Related Datasets:
Contributions welcome! If you:
- Find missing skills or categories
- Have suggestions for improvements
- Want to add more language support
- Build interesting projects using this model
Please open an issue or pull request on GitHub.
📧 Contact
- Author: Herlambang Haryo Putro
- Email: herlambangharyoputro@gmail.com
- GitHub: @herlambangharyoputro
- Project: Job Market Intelligence Platform
🔄 Version History
- v1.0.0 (December 2024): Initial release
- 200+ skills across 7 categories
- 40+ aliases for normalization
- Proficiency level detection
- Indonesian language support
- Zero dependencies
⚠️ Limitations
Coverage
- Limited to predefined skill taxonomy (200+ skills)
- New/emerging skills may be categorized as 'other'
- Domain-specific skills may not be recognized
Language
- Primarily optimized for Indonesian job market
- May not capture all regional variations
- English technical terms preferred over Indonesian equivalents
Accuracy
- Rule-based approach may miss context-dependent skills
- Acronyms can be ambiguous (e.g., "AI" = Artificial Intelligence or Adobe Illustrator)
- Proficiency detection based on keywords only
Recommendations
- Best for structured skill lists (bullets, commas)
- Review 'other' category for domain-specific additions
- Combine with manual review for critical applications
- Consider ML-based approach for unstructured text
🎯 Future Improvements
Planned features for v2.0:
- Expanded skill taxonomy (300+ skills)
- Industry-specific categories
- Skill clustering and relationships
- Confidence scoring
- Multi-language support (Javanese, Sundanese)
- Experience year extraction
- Certification detection
Last Updated: December 2024
Model Version: 1.0.0
Status: ✅ Production Ready
Type: Rule-based NER
For questions or collaboration, visit GitHub.