riasec-co 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/data/cobertura.csv +44655 -0
- package/data/convenios.csv +914 -0
- package/data/items_en.json +80 -0
- package/data/items_es.json +80 -0
- package/data/mapping.json +73 -0
- package/data/programs.csv +30810 -0
- package/dist/items.d.ts.map +1 -1
- package/dist/items.js +14 -10
- package/dist/items.js.map +1 -1
- package/dist/programs.d.ts.map +1 -1
- package/dist/programs.js +14 -8
- package/dist/programs.js.map +1 -1
- package/package.json +5 -3
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# riasec-co
|
|
2
|
+
|
|
3
|
+
**Connects each student's vocational profile with Colombia's 17,230 active SNIES programs.**
|
|
4
|
+
|
|
5
|
+
Bayesian adaptive RIASEC engine with the complete SNIES catalog — 33 departments, 297 institutions. Zero runtime dependencies.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/riasec-co)
|
|
8
|
+
[](https://github.com/affromero/riasec-co/actions/workflows/ci.yml)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install riasec-co
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createQuiz, loadPrograms, recommend } from 'riasec-co'
|
|
21
|
+
|
|
22
|
+
// 1. Run adaptive quiz (~12 questions instead of 48)
|
|
23
|
+
const quiz = createQuiz({ language: 'es', mode: 'adaptive' })
|
|
24
|
+
while (!quiz.isComplete()) {
|
|
25
|
+
const q = quiz.nextQuestion()!
|
|
26
|
+
const response = await askUser(q.text) // your UI
|
|
27
|
+
quiz.answer(q.id, response)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(quiz.profile())
|
|
31
|
+
// { R: 0.19, I: 0.27, A: 0.10, S: 0.16, E: 0.10, C: 0.18 }
|
|
32
|
+
console.log(quiz.topTypes(2)) // ['I', 'R']
|
|
33
|
+
|
|
34
|
+
// 2. Get program recommendations
|
|
35
|
+
const results = recommend({
|
|
36
|
+
profile: quiz.profile(),
|
|
37
|
+
programs: loadPrograms(),
|
|
38
|
+
filters: { departments: ['Sucre', 'Cordoba', 'Bolivar'], active: true },
|
|
39
|
+
priors: { enrollmentWeight: -0.3, virtualBoost: 1.5 },
|
|
40
|
+
limit: 10,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
results.forEach((r, i) =>
|
|
44
|
+
console.log(`${i + 1}. ${r.program.nombre_programa} (${r.score.toFixed(2)})`)
|
|
45
|
+
)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### Quiz
|
|
51
|
+
|
|
52
|
+
| Function | Description |
|
|
53
|
+
|----------|-------------|
|
|
54
|
+
| `createQuiz(config?)` | Create a quiz instance (`language`: `"es"` or `"en"`, `mode`: `"adaptive"` or `"full"`) |
|
|
55
|
+
| `quiz.nextQuestion()` | Next item (or `null` if complete) |
|
|
56
|
+
| `quiz.answer(id, response)` | Record a Likert response (1-5) |
|
|
57
|
+
| `quiz.isComplete()` | Whether the quiz has enough information to stop |
|
|
58
|
+
| `quiz.profile()` | Current RIASEC profile (`RIASECProfile`) |
|
|
59
|
+
| `quiz.topTypes(n?)` | Top N types sorted by probability |
|
|
60
|
+
| `quiz.progress()` | `{ answered, total, estimatedRemaining, confidence, entropy }` |
|
|
61
|
+
|
|
62
|
+
### Data
|
|
63
|
+
|
|
64
|
+
| Function | Description |
|
|
65
|
+
|----------|-------------|
|
|
66
|
+
| `loadPrograms()` | All 30,809 SNIES programs (17,230 active) |
|
|
67
|
+
| `loadItems(language)` | 48 IPIP items in `"es"` or `"en"` |
|
|
68
|
+
| `loadMapping()` | RIASEC → CINE field weights |
|
|
69
|
+
| `getCINEFields(programs)` | Unique CINE broad fields |
|
|
70
|
+
| `getDepartments(programs)` | Unique departments |
|
|
71
|
+
|
|
72
|
+
### Recommendations
|
|
73
|
+
|
|
74
|
+
| Function | Description |
|
|
75
|
+
|----------|-------------|
|
|
76
|
+
| `recommend(config)` | Rank programs by profile fit, with enrollment priors and regional boosts |
|
|
77
|
+
|
|
78
|
+
### Scoring Internals
|
|
79
|
+
|
|
80
|
+
| Function | Description |
|
|
81
|
+
|----------|-------------|
|
|
82
|
+
| `uniformPrior()` | Dirichlet α = (1,1,1,1,1,1) |
|
|
83
|
+
| `updateAlpha(alpha, type, response, keyed)` | Bayesian update after one answer |
|
|
84
|
+
| `posteriorMean(alpha)` | E[θ_k] = α_k / Σα |
|
|
85
|
+
| `entropy(alpha)` | Shannon entropy in bits |
|
|
86
|
+
| `confidence(alpha)` | 1 − (entropy / max_entropy) |
|
|
87
|
+
| `cosineSimilarity(a, b)` | Vector similarity [0, 1] |
|
|
88
|
+
| `expectedInfoGain(alpha, type)` | Information gain for adaptive item selection |
|
|
89
|
+
|
|
90
|
+
## How It Works
|
|
91
|
+
|
|
92
|
+
1. **Dirichlet prior** — starts with uniform belief over 6 RIASEC types
|
|
93
|
+
2. **Adaptive selection** — picks the question that maximizes expected information gain
|
|
94
|
+
3. **Bayesian update** — each Likert response updates the posterior
|
|
95
|
+
4. **Entropy stopping** — stops when Shannon entropy < 1.5 bits (~12 questions)
|
|
96
|
+
5. **Program matching** — cosine similarity between profile and CINE field vectors
|
|
97
|
+
6. **Enrollment priors** — downweights oversaturated fields, boosts underserved ones
|
|
98
|
+
|
|
99
|
+
## Data
|
|
100
|
+
|
|
101
|
+
Bundled in the package (no network requests):
|
|
102
|
+
|
|
103
|
+
- **30,809 programs** from Colombia's SNIES/HECAA catalog (24 columns each)
|
|
104
|
+
- **48 IPIP items** in English and Spanish (8 per RIASEC type)
|
|
105
|
+
- **RIASEC → CINE mapping** with weighted associations
|
|
106
|
+
|
|
107
|
+
## Also Available
|
|
108
|
+
|
|
109
|
+
- **Python**: `pip install riasec-co` — [PyPI](https://pypi.org/project/riasec-co/)
|
|
110
|
+
- **R**: `remotes::install_github("afromero/riasec-co", subdir = "r")`
|
|
111
|
+
- **React components**: [`riasec-co-react`](https://www.npmjs.com/package/riasec-co-react)
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|