knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.2, dpi = 72, out.width = "100%")
Synthetic data are only useful if they are faithful to the real data, useful for the analyses people will run, and safe to release. No single number captures all three, so SynthesizerPlus provides a set of complementary measures and plots.
library(SynthesizerPlus) real <- airquality syn <- synthesize(real, by = "Month", seed = 1)
compare_synthetic()cmp <- compare_synthetic(real, syn, seed = 1) cmp summary(cmp)
The ideal column of summary() gives the value expected for a perfect
synthesizer that still produces new records. The components are described
below.
marginal_metrics() reports, for each variable, the Kolmogorov–Smirnov
distance (numeric) or the total variation distance (categorical), the
Wasserstein-1 distance in units of the real standard deviation, and moments
and missing-value rates.
marginal_metrics(real, syn)[, c("variable", "distance", "wasserstein", "mean_real", "mean_synthetic", "missing_real", "missing_synthetic")]
plot_marginals(real, syn) plot_qq(real, syn)
For categorical variables, plot_marginals() (or plot_categorical()) shows
the category shares side by side:
syn_iris <- synthesize(iris, by = "Species", seed = 1) plot_categorical(iris, syn_iris)
association_matrix() works for mixed data: Spearman correlation for pairs
of numeric variables, bias-corrected Cramér's V for pairs of categorical
variables and the correlation ratio for mixed pairs.
plot_association(real, syn, vars = c("Ozone", "Solar.R", "Wind", "Temp"))
If real and synthetic records are exchangeable, a classifier should not be able to predict which set a record comes from.
pmse(real, syn, seed = 1) discriminator_auc(real, syn, seed = 1)
ci_overlap() fits the same regression to both data sets and compares the
confidence intervals (Karr et al., 2006):
ci_overlap(real, syn, Ozone ~ Temp + Wind + Solar.R)[, c("term", "estimate_real", "estimate_synthetic", "std_diff", "overlap")]
Overlaps close to 1 mean that inference on synthetic data leads to the same conclusions.
A synthesizer that copies real records has perfect fidelity but no privacy.
dcr() computes, for each synthetic record, the Gower distance to the
closest real record, and compares it to how close real records are to each
other.
risk <- dcr(real, syn, seed = 1) risk$quantiles risk$exact_match_rate plot_dcr(risk)
Exact copies, or a synthetic distance distribution well to the left of the
real one, are warning signs. Remedies include knots (coarser quantile
functions), lowering dependence, or a larger min_stratum_size.
All plots are also available from the comparison object:
plot(cmp, type = "marginals") plot(cmp, type = "association") plot(cmp, type = "pairs") plot(cmp, type = "qq") plot(cmp, type = "dcr") ggplot2::autoplot(cmp, type = "association") + ggplot2::ggtitle("airquality")
Every plotting function returns a ggplot object, so themes, scales and
labels can be changed with the usual ggplot2 syntax.
Karr, A. F., Kohnen, C. N., Oganian, A., Reiter, J. P. and Sanil, A. P. (2006). A framework for evaluating the utility of data altered to protect confidentiality. The American Statistician, 60(3), 224–232.
Snoke, J., Raab, G. M., Nowok, B., Dibben, C. and Slavkovic, A. (2018). General and specific utility measures for synthetic data. Journal of the Royal Statistical Society A, 181(3), 663–688.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.