Paper: (https://arxiv.org/abs/2202.05250).
Suppose there are
where
Denote by
The Python classes ARMUL
and Baselines
in ARMUL.py
implement three important cases of ARMUL (vanilla, clustered and low-rank) as well as four baseline procedures (single-task learning, data pooling, clustered MTL and low-rank MTL). The current version supports
- multi-task linear regression:
- multi-task logistic regression:
where
Preparation: store the data
of length 2. data[0]
is a list of data[1]
is a list of lbd
of
To implement vanilla ARMUL, run
import numpy as np
from ARMUL import ARMUL
test = ARMUL(link) # link == 'linear' or 'logistic'
test.vanilla(data, lbd, standardization = True, intercept = True)
If standardization = True
(default), the raw features (for linear and logistic regression) and responses (for linear regression only) will be standardized to have zero mean and unit variance. If intercept = True
(default), an all-one feature will be added to the datasets. See ARMUL.py
for other arguments of the function vanilla
, such as the step size and number of iterations of the proximal gradient descent algorithm for optimization. The two components test.models['vanilla']
and test.models['vanilla_gamma']
, respectively. To evaluate the out-of-sample performance, prepare testing data (data_test
) from the data
). Then, execute
test.evaluate(data_test, model = 'vanilla')
This computes the testing errors (mean square errors for linear regression and misclassification errors for logistic regression) on the test.results['errors']
, whose average (weighted by sample sizes) is test.results['average error']
. For linear regression, test.results['R2']
returns the overall R-square on all the data.
Clustered and low-rank ARMUL can be implemented using test.clustered(data, lbd, K)
and test.lowrank(data, lbd, K)
, respectively. Here K
is the number of clusters or the rank.
Vanilla ARMUL has tuning parameters lbd_list
of length lbd_list[s]
being the list
test.cv(data, lbd_list, model = 'vanilla', n_fold = 5, seed = 1000, standardization = True, intercept = True)
estimates the testing error (mean square errors or misclassification errors averaged over all tasks, weighted by sample sizes) of vanilla ARMUL with each configuration n_fold
is the number of folds and seed
is the random seed. After that,
-
test.errors_cv
stores the validations errors corresponding to the$S$ candidate configurations; -
test.lbd_cv
is the selected configuration; -
vanilla ARMUL is refitted on all the training data using the selected configuration, and
test.models['vanilla']
gives the final$\widehat{\Theta}$ .
We can evaluate the obtained test.evaluate(data_test, model = 'vanilla')
as before. The above procedure is helpful for selecting the constant
To apply cross-validation to clustered or low-rank ARMUL, set model = 'clustered'
or model = 'lowrank'
, choose a value for K
, and execute
test.cv(data, lbd_list, model = model, K = K, n_fold = 5, seed = 1000, standardization = True, intercept = True)
For a given K
, it uses cross-validation to select from multiple configurations of lbd_list
.
To implement baseline procedures, run
import numpy as np
from ARMUL import Baselines
base = Baselines(link) # link == 'linear' or 'logistic'
Single-task learning, data pooling, clustered MTL and low-rank MTL correspond to base.STL_train(data)
, base.DP_train(data)
, base.clustered_train(data, K)
and base.lowrank_train(data, K)
, respectively. See ARMUL.py
for other arguments of those methods. The models can be evaluated using base.evaluate(data_test, model)
, where model
is 'STL'
, 'DP'
, 'clustered'
or 'lowrank'
.
See Demo.ipynb
for a real data example.
The folder experiments in the paper
contains all the experimental results and codes of the ARMUL paper. See Demo_reproducibility.ipynb
for how to reproduce the results.
@article{duan2022adaptive,
title={Adaptive and robust multi-task learning},
author={Duan, Yaqi and Wang, Kaizheng},
journal={arXiv preprint arXiv:2202.05250},
year={2022}
}