Aggregates labelled announcements into one skill distribution per
(ESCO group, CP code) pair, the sufficient statistic a centroid classifier
needs. The result is a small sparse object that can be saved, versioned and
shipped: predict_cp5_centroid() scores new announcements against it without
seeing the training data again.
Usage
build_cp_profiles(
postings,
skills,
restrictor = "idesco_level_5",
target = "cp2021_id_level_5",
restrictor_na = NULL,
skill_col = "escoskill_level_3",
min_support = 1L,
smooth_alpha = 0.1,
shrink_beta = 50,
weighting = "none",
sector = FALSE,
verbose = TRUE
)Arguments
- postings
A data.table of labelled announcements. Needs
general_id, therestrictorcolumn, thetargetcolumn, andidsectorwhensector = TRUE. Rows whose target isNAor empty are ignored.- skills
A data.table with
general_idandskill_col.- restrictor
Character naming the column that restricts the candidate space (default
"idesco_level_5").- target
Character naming the CP2021 column to learn (default
"cp2021_id_level_5").- restrictor_na
Sentinel values of
restrictormeaning "no occupation code", normalised toNA.NULL(default) resolves to"Unclassifiable"for a level-5 restrictor and to nothing otherwise.- skill_col
Character naming the skill column (default
"escoskill_level_3").- min_support
Integer: candidates supported by fewer than this many labelled announcements are dropped from their group (default 1, keep all).
- smooth_alpha
Numeric additive (Lidstone) smoothing applied to the skill counts before normalising (default 0.1).
- shrink_beta
Numeric shrinkage of each class profile toward its ESCO group's profile:
theta_c = (n_c * theta_hat_c + beta * pi_e) / (n_c + beta)(default 50).0disables it; large values collapse every candidate onto the group profile, which is the identity the harness tests.- weighting
Character vector of the diagonal skill weightings to precompute, any of
"none","idf","balassa". Only the ones a distance actually needs are used at prediction time.- sector
Logical: also learn a smoothed sector distribution per candidate, scored as a naive-Bayes term (default FALSE). Requires
idsectorinpostings.- verbose
Logical: print a one-line summary (default TRUE).
Value
A list of class cp_profiles carrying the pair index, the sparse
skill counts per pair and per group, the class sizes, the skill vocabulary,
the optional sector counts, the requested weight vectors, and the
smoothing parameters. Its size is governed by the number of
(group, code) pairs, not by the number of announcements.
Details
Profiles are stored as counts, not as the smoothed distributions. The
smoothing and the shrinkage are applied by predict_cp5_centroid() when it
materialises a group's block, so one build serves many scoring parameters and
the stored object stays sparse.
shrink_beta interpolates between the class profile and its group's:
a class with few announcements is pulled toward the group, one with many is
left alone. This is the axis the 2026-03 attempt lacked, and it is also the
axis that makes the model falsifiable — see predict_cp5_centroid().
See also
predict_cp5_centroid(), and predict_cp5_knn() for the
neighbour-search model this one is measured against.
Examples
postings <- data.table::data.table(
general_id = as.character(1:6),
idesco_level_5 = rep(c("1000.1", "2000.1"), each = 3),
cp2021_id_level_5 = c(
"1.1.1.1.1", "1.1.1.1.1", "1.1.1.1.2",
"2.2.2.2.0", "2.2.2.2.0", "2.2.2.2.0"
)
)
skills <- data.table::data.table(
general_id = as.character(rep(1:6, each = 2)),
escoskill_level_3 = c(
"s1", "s2", "s1", "s2", "s1", "s3",
"s4", "s5", "s4", "s5", "s4", "s6"
)
)
p <- build_cp_profiles(postings, skills, verbose = FALSE)
p$pairs
#> grp code pair_id grp_id n_c
#> <char> <char> <int> <int> <int>
#> 1: 1000.1 1.1.1.1.1 1 1 2
#> 2: 1000.1 1.1.1.1.2 2 1 1
#> 3: 2000.1 2.2.2.2.0 3 2 3