Provides single-function pipelines for applied machine learning with tabular data, as commonly found in psychological, behavioral, and health research. The supervised pipeline, supervised_ml(), performs exploratory checks, preprocessing, training of several models with cross-validation, hyperparameter tuning, test-set evaluation, threshold optimization, calibration, fairness analysis, decision curve analysis, and model interpretation with permutation importance and Shapley values. The unsupervised pipeline, unsupervised_ml(), covers k-means, hierarchical, DBSCAN, Gaussian mixture, and latent class clustering with selection of the number of clusters, dimensionality reduction (PCA, t-SNE, UMAP), and anomaly detection (isolation forest, local outlier factor, Mahalanobis distance). The causal pipeline, causal_ml(), estimates treatment effects with propensity scores, meta-learners, double machine learning, causal forests, and targeted maximum likelihood estimation. Also includes learning-curve based sample size estimation, block and diversity-based data splitting, and export of results to text and JSON.
PsyML provides single-function machine learning pipelines for tabular data, as commonly found in psychological, behavioral, and health research. It is organized around three approaches:
| Approach | Research question | Main function |
|---|---|---|
| Supervised learning | How well can we predict an outcome we already observe? | supervised_ml() |
| Unsupervised learning | Are there groups or unusual cases when there is no outcome? | unsupervised_ml() |
| Causal inference | What is the effect of a treatment or exposure on an outcome? | causal_ml() |
In more detail:
supervised_ml(): classification and regression. Exploratory checks,
preprocessing, training of several models with cross-validation,
hyperparameter tuning, test-set evaluation, threshold optimization,
calibration, fairness and decision curve analysis, and interpretation
(model-specific or permutation importance, Kernel SHAP values).unsupervised_ml(): clustering (k-means, hierarchical, DBSCAN, Gaussian
mixtures, latent class analysis), dimensionality reduction (PCA, t-SNE,
UMAP), and anomaly detection (isolation forest, LOF, Mahalanobis distance).causal_ml(): treatment effect estimation with propensity scores
(matching, IPW, doubly robust), meta-learners, double machine learning,
causal forests, and TMLE.It also includes sample size estimation for machine learning based on
learning curves (ml_sample_size()), block and diversity-based train/test
splitting, and export of the results to text and JSON files.
PsyML is a renamed and revised version of the easyML package by the same author.
# Development version from GitHub
# install.packages("remotes")
remotes::install_github("jventural/PsyML")
library(PsyML)
set.seed(1)
n <- 300
df <- data.frame(x1 = rnorm(n), x2 = rnorm(n), x3 = rnorm(n))
df$y <- factor(ifelse(df$x1 + 0.5 * df$x2 + rnorm(n) > 0, "yes", "no"))
result <- supervised_ml(
data = df,
target = "y",
models = c("glm", "rf"),
cv_folds = 5,
seed = 2026
)
print(result)
summary(result)
plot(result)
predict(result, df[1:5, ])
result <- unsupervised_ml(
data = iris,
exclude_cols = "Species",
methods = c("clustering", "reduction", "anomaly"),
clustering_algorithms = c("kmeans", "hierarchical"),
reduction_methods = "pca",
anomaly_methods = "mahalanobis",
seed = 2026
)
print(result)
cluster_profile(result, original_data = iris[, 1:4])
set.seed(1)
n <- 500
d <- data.frame(x1 = rnorm(n), x2 = rnorm(n))
d$treat <- rbinom(n, 1, plogis(0.5 * d$x1))
d$y <- 1 + 0.8 * d$treat + d$x1 + 0.5 * d$x2 + rnorm(n)
result <- causal_ml(d, treatment = "treat", outcome = "y",
methods = c("propensity", "meta_learners"), seed = 2026)
print(result)
size <- ml_sample_size(
task = "classification",
metric = "auc",
target = 0.80,
reps = 100,
seed = 2026
)
size$recommend_n
plot_learning_curve(size)
Functions that use random numbers have a seed argument whose default is
NULL: the random number generator is not touched unless you supply a seed
(or call set.seed() yourself).
Nothing is written to disk unless you give a path:
out <- tempdir()
export_verbose_txt(result, file.path(out, "analysis.txt"))
export_verbose_json(result, file.path(out, "analysis.json"))
save_all_plots(result, path = out)
explain_with_ai() and generate_report_with_ai() send a summary of the
results to a large language model provider (Groq or OpenAI). They need your
own API key, given in api_key or in the environment variable
PSYML_API_KEY.
Jose Ventura-Leon (ORCID 0000-0003-2996-4244).
MIT