HiDDENg() and HiDDENgt(): grouped entrypoints#
we first import all script dependencies and load the provided data in GSE96583 into an AnnData object
show preamble
hide
# import dependencies and load data
from gzip import decompress
from io import BytesIO
from pathlib import Path
from urllib.request import urlopen
import anndata as ad
import pandas as pd
from scipy.io import mmread
from scipy.sparse import hstack
import found
from found import methods as m
from found import pl
from found.adapters import Pipeline
from found.tune import NaiveMaxScoreTuner
RANDOM_STATE = 42
found.set_seed(RANDOM_STATE)
if (pth := Path("../_build/.cache/GSE96583.h5ad")).exists():
adata = ad.read_h5ad(pth)
else:
base_url = "https://www.ncbi.nlm.nih.gov/geo/download/"
adata = ad.AnnData(
hstack(
[
mmread(BytesIO(decompress(urlopen(url).read()))).tocsc()
for url in [
f"{base_url}?acc=GSM2560248&format=file&file=GSM2560248_2.1.mtx.gz",
f"{base_url}?acc=GSM2560249&format=file&file=GSM2560249_2.2.mtx.gz",
]
]
).T,
obs=pd.read_csv(f"{base_url}?acc=GSE96583&format=file&file=GSE96583_batch2.total.tsne.df.tsv.gz", sep="\t")
.reset_index(names="barcode", drop=False)
.assign(barcode=lambda x: x["stim"] + "_" + x["barcode"].str.extract("([ACTG]+-1)", expand=False))
.set_index("barcode")[["stim", "cluster", "cell", "multiplets"]],
var=pd.read_csv(f"{base_url}?acc=GSE96583&format=file&file=GSE96583_batch2.genes.tsv.gz", sep="\t", header=None)
.set_index(0)
.rename_axis("ENSEMBL", axis="index")
.rename({1: "SYMBOL"}, axis="columns"),
)
adata = adata[~adata.obs["cell"].isna()].copy()
adata.write_h5ad(pth)
print(adata)
it can be of interest to run HiDDEN in a grouped fashion, splitting a dataset according to some discrete variable and then running HiDDEN on each subset separately.
as this is a very common workflow, found provides two entrypoints to handle this for the user: HiDDENg() and HiDDENgt(), the latter providing hyper-parameter tuning and grouping
p_hat, labs = found.HiDDENg(adata, "stim", "ctrl", "cell", Pipeline(m.run_pca, m.reg_logit, m.bin_kmeans), X=adata.X, k=20)
plt = pl.PlotHiDDENOutput(adata, p_hat, labs)
plt.bin_bar("stim", "ctrl", "cell")
we see that megakaryocytes show the most relabeling, so we plot the p_hat values for that cell type specifically
plt[lambda a: a.obs["cell"] == "Megakaryocytes"].reg_vln("stim")
the above workflow assumes that a hyperparameter k for the pipeline is a) known and b) fixed for all cell types.
however, this is not always the case, and so we can use the HiDDENgt() entrypoint to perform tuning combined with factor grouping.
sel, by_param, by_grp = found.HiDDENgt(
adata,
"stim",
"ctrl",
"cell",
NaiveMaxScoreTuner(m.score_ks_diff, range(2, 20, 2)),
Pipeline(m.run_pca, m.reg_logit, m.bin_kmeans, cachable_dimr=True),
X=adata.X,
)
print(sel)
due to the permutation of outputs by grouping and hyperparameter selection, HiDDENgt() returns a set of accessor functions, not raw outputs.
specifically:
the first accessor (here bound to
by_param), returnsHiDDEN()-style output given a mapping from each group to selected hyperparameters, as well as the score values associated with each groupthe second accessor (here bound to
by_grp), returnsHiDDENt()-style output given a specific group
here we can plot the re-mixed together outputs of HiDDENgt() given the optimal hyperparameter for each cell type
p_hat, labs, scores = by_param(sel)
pl.PlotHiDDENOutput(adata, p_hat, labs).bin_bar("stim", "ctrl", "cell")
we can also explore the evolution of score values for specifically megakaryocytes, and see that setting k to 6 seems to yield optimal results
mk_out_only = by_grp("Megakaryocytes")
pl.PlotTunerOutput(
adata[adata.obs["cell"] == "Megakaryocytes"], # we subset our paired anndata value to only megakaryocytes
sel["Megakaryocytes"], # we provided the selected `k` value by indexing the group to choice mapping returned by HiDDENgt
mk_out_only,
).score_line().show()
finally, it is good to note that HiDDENg() (and HiDDENgt()) accept a grp_specific_args argument, which provides the ability to inject arguments into the pipeline in a group specific basis.
we can use this here to run HiDDENg() with different k values per group (using the values selected by HiDDENgt()).
p_hat, labs = found.HiDDENg(
adata,
"stim",
"ctrl",
"cell",
Pipeline(m.run_pca, m.reg_logit, m.bin_kmeans),
grp_specific_args={grp: {"k": opt_k} for grp, opt_k in sel.items()},
X=adata.X,
)
pl.PlotHiDDENOutput(
adata,
p_hat,
labs,
)[lambda a: a.obs["cell"] == "Megakaryocytes"].reg_vln("stim").properties(width=120).show()