-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy path590_SSL.qmd
More file actions
192 lines (144 loc) · 7.17 KB
/
Copy path590_SSL.qmd
File metadata and controls
192 lines (144 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# Further Classification Models
## Learning Objectives and Evaluation Lens
- **Objective**: handle classification settings that go beyond single-label fully supervised learning.
- **Data context**: multilabel corpora and partially labeled datasets.
- **Validation**: strict separation of labeled/unlabeled/test data with leakage controls.
- **Primary metrics**: macro/micro F1 for multilabel tasks; confusion-based metrics for SSL classification.
- **Common pitfalls**: pseudo-label confirmation bias, class imbalance, and distribution mismatch.
## Multilabel classification
Some datasets, for example reviews of applications and mobile application
repositories such as the App Store or Google Play, contain reviews that can
have several labels at the same time (e.g., bugs, feature requests, UI issues).
Similarly, a software issue may belong to multiple components or concern
multiple quality attributes simultaneously.
In **multilabel classification**, each instance can be assigned to more than
one class. Common approaches are:
- **Binary Relevance (BR)**: train one independent binary classifier per label.
Simple but ignores label co-occurrence.
- **Classifier Chains (CC)**: extend BR by passing previous predictions as
features to the next classifier, capturing label dependencies.
- **Label Powerset (LP)**: treat each unique label combination as a single
class; exact but combinatorially expensive.
In R, the `mldr` package provides data structures and learners for multilabel
classification. For a tidy workflow, `mlr3` with its multilabel task type is an
alternative. Evaluation uses **Hamming loss** (fraction of wrong label
assignments), **macro/micro F1**, and **subset accuracy** (all labels correct).
```{r eval=FALSE}
# Sketch with mldr
# library(mldr)
# mldr_dataset <- mldr_from_dataframe(df, labelIndices = label_col_indices)
# summary(mldr_dataset)
```
## Ordinal Classification
Many SE outcomes are not nominal but **ordinal**: defect severity
(low < medium < high < critical), code review priority, or technical debt
level. Standard classifiers treat classes as exchangeable and ignore the
ordering, which can inflate nominal error rates on practically small mistakes.
Approaches:
- **Ordinal regression** (proportional-odds model): extends logistic regression
with monotonicity constraints across thresholds.
- **Threshold decomposition**: convert the ordinal problem into a series of
binary problems using cumulative link models.
- **Cost-sensitive learning**: assign asymmetric misclassification costs that
reflect the ordinal distance.
In R, the `ordinal` package implements cumulative link (mixed) models.
```{r eval=FALSE}
# library(ordinal)
# m <- clm(severity ~ loc + complexity, data = train_df)
# predict(m, newdata = test_df)
```
## Weak and Distant Supervision
In SE datasets, labels are often derived from heuristics rather than manual
annotation — for example, a file is labelled "defective" if a commit message
contains the word *fix* or *bug* (SZZ approach), or a commit is labelled as
a "feature addition" based on keyword matching. These automatically generated,
imperfect labels are called **weak labels** or **distant labels**.
**Consequences:**
- Label noise can substantially degrade model performance.
- Models may learn to predict the labelling heuristic rather than the
underlying concept.
- Standard evaluation metrics are optimistic if the test set uses the same
noisy labels as training.
**Mitigations:**
- Use a small set of carefully hand-labelled instances to validate label
quality.
- Apply label-noise-robust learning algorithms (e.g., learning with noisy
labels via bootstrapping or noise-tolerant loss functions).
- Report sensitivity analyses showing performance variation under different
label-cleaning thresholds.
## Active Learning
**Active learning** addresses the situation where unlabeled data is abundant
but labeling is expensive (requiring expert code review, manual bug
classification, or security audit). The learner iteratively queries an
*oracle* (typically a human expert) for the labels of the most informative
instances.
Common query strategies:
- **Uncertainty sampling**: query the instance on which the current model is
least confident.
- **Query by committee**: train a committee of models; query the instance with
the highest disagreement.
- **Expected model change**: query the instance that would most change the model.
In SE, active learning has been applied to defect labeling, code review
prioritization, and test-case selection. The key advantage is that fewer
expert-labeled examples are needed to reach a target accuracy.
```{r eval=FALSE}
# Active learning loop sketch (uncertainty sampling)
# 1. Start with small labeled set L, large unlabeled pool U
# 2. Train classifier on L
# 3. Compute prediction entropy on U
# 4. Select top-k most uncertain instances → send to oracle
# 5. Add newly labeled instances to L, remove from U
# 6. Repeat until budget exhausted
```
## Semi-supervised Learning
Self-train a model on semi-supervised data.
### Practical caveats
Semi-supervised learning can improve performance when unlabeled data matches
the same distribution as labeled data, but it can also amplify errors.
Key risks and guardrails:
1. **Confirmation bias**: wrong pseudo-labels can reinforce themselves.
: Use confidence thresholds and add pseudo-labels gradually.
2. **Distribution mismatch**: unlabeled pool may differ from labeled data.
: Monitor drift and evaluate on a clean held-out set.
3. **Overconfidence**: probabilities may be poorly calibrated.
: Prefer calibrated models or conservative thresholds.
4. **Leakage**: test data must never be used in pseudo-label loops.
: Keep strict train/validation/test separation.
The legacy examples in this chapter used `DMwR2::SelfTrain`, which is no longer
actively maintained. A standard modern alternative in R workflows is to combine
`tidymodels` with a pseudo-labeling loop.
```{r ssl, message=FALSE, warning=FALSE, eval = FALSE}
library(tidymodels)
## Small example with the Iris classification data set
set.seed(123)
data(iris)
## Split into train / test
idx <- sample(seq_len(nrow(iris)), 100)
tr <- iris[idx, ]
ts <- iris[-idx, ]
## Hide labels for a large subset of the training data
tr_ssl <- tr
nas <- sample(seq_len(nrow(tr_ssl)), 70)
tr_ssl$Species[nas] <- NA
## Start from labeled rows only
labeled <- tr_ssl |> dplyr::filter(!is.na(Species))
unlabeled <- tr_ssl |> dplyr::filter(is.na(Species))
## Base learner
wf <- workflow() |>
add_recipe(recipe(Species ~ ., data = labeled)) |>
add_model(decision_tree() |> set_engine("rpart") |> set_mode("classification"))
## Pseudo-labeling loop (single pass for teaching clarity)
fit0 <- fit(wf, data = labeled)
probs <- predict(fit0, unlabeled, type = "prob")
preds <- predict(fit0, unlabeled, type = "class")
## Keep only high-confidence pseudo-labels
conf <- apply(as.matrix(probs), 1, max)
selected <- conf >= 0.9
pseudo <- unlabeled[selected, ]
pseudo$Species <- preds$.pred_class[selected]
augmented <- dplyr::bind_rows(labeled, pseudo)
fit_ssl <- fit(wf, data = augmented)
## Evaluate on held-out test set
pred_ssl <- predict(fit_ssl, ts, type = "class")
yardstick::conf_mat_vec(ts$Species, pred_ssl$.pred_class)
```