Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/methods/shareclaw_lda_lsqr_auto/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
__merge__: /src/api/comp_method.yaml
name: "shareclaw_lda_lsqr_auto"
label: ShareClaw LDA LSQR Auto
summary: "Standardize PCA coordinates and fit a shrinkage-aware linear discriminant analysis classifier."
description: |
ShareClaw LDA LSQR Auto applies a StandardScaler to the PCA embedding and
then fits a LinearDiscriminantAnalysis classifier using the LSQR solver with
automatic shrinkage. In our ShareClaw-driven search, this variant delivered
the strongest Zebrafish macro-F1 among the lightweight linear baselines we
evaluated.
references:
bibtex: |
@article{fisher1936use,
title = {The use of multiple measurements in taxonomic problems},
author = {Fisher, Ronald Aylmer},
journal = {Annals of Eugenics},
volume = {7},
number = {2},
pages = {179--188},
year = {1936}
}
links:
repository: https://github.com/anubhav1004/shareclaw
documentation: https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html
info:
preferred_normalization: log_cp10k
resources:
- type: python_script
path: script.py
engines:
- type: docker
image: openproblems/base_python:1
setup:
- type: python
packages: scikit-learn
runners:
- type: executable
- type: nextflow
directives:
label: [midtime, midmem, midcpu]
54 changes: 54 additions & 0 deletions src/methods/shareclaw_lda_lsqr_auto/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import anndata as ad
import pandas as pd
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

## VIASH START
par = {
"input_train": "resources_test/task_label_projection/cxg_immune_cell_atlas/train.h5ad",
"input_test": "resources_test/task_label_projection/cxg_immune_cell_atlas/test.h5ad",
"output": "output.h5ad",
}
meta = {
"name": "foo",
}
## VIASH END


def require_pca(adata_obj, label):
if "X_pca" not in adata_obj.obsm:
raise KeyError(f"{label} is missing obsm['X_pca']")


print("Load input data", flush=True)
input_train = ad.read_h5ad(par["input_train"])
input_test = ad.read_h5ad(par["input_test"])

require_pca(input_train, "input_train")
require_pca(input_test, "input_test")

print("Fit to train data", flush=True)
classifier = Pipeline(
steps=[
("scale", StandardScaler()),
("model", LinearDiscriminantAnalysis(solver="lsqr", shrinkage="auto")),
]
)
classifier.fit(input_train.obsm["X_pca"], input_train.obs["label"].astype(str))

print("Predict on test data", flush=True)
label_pred = classifier.predict(input_test.obsm["X_pca"])

print("Create output data", flush=True)
output = ad.AnnData(
obs=pd.DataFrame({"label_pred": label_pred}, index=input_test.obs.index),
uns={
"method_id": meta["name"],
"dataset_id": input_test.uns["dataset_id"],
"normalization_id": input_test.uns["normalization_id"],
},
)

print("Write output data", flush=True)
output.write_h5ad(par["output"], compression="gzip")
39 changes: 39 additions & 0 deletions src/methods/shareclaw_lda_svd/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
__merge__: /src/api/comp_method.yaml
name: "shareclaw_lda_svd"
label: ShareClaw LDA SVD
summary: "Standardize PCA coordinates and fit a linear discriminant analysis classifier with the SVD solver."
description: |
ShareClaw LDA SVD applies a StandardScaler to the PCA embedding and then fits
a LinearDiscriminantAnalysis classifier with the SVD solver. In our ShareClaw
search loop, this was the strongest macro-F1 performer on the official small
task resources while also materially improving the local Zebrafish baseline.
references:
bibtex: |
@article{fisher1936use,
title = {The use of multiple measurements in taxonomic problems},
author = {Fisher, Ronald Aylmer},
journal = {Annals of Eugenics},
volume = {7},
number = {2},
pages = {179--188},
year = {1936}
}
links:
repository: https://github.com/anubhav1004/shareclaw
documentation: https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html
info:
preferred_normalization: log_cp10k
resources:
- type: python_script
path: script.py
engines:
- type: docker
image: openproblems/base_python:1
setup:
- type: python
packages: scikit-learn
runners:
- type: executable
- type: nextflow
directives:
label: [midtime, midmem, midcpu]
54 changes: 54 additions & 0 deletions src/methods/shareclaw_lda_svd/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import anndata as ad
import pandas as pd
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

## VIASH START
par = {
"input_train": "resources_test/task_label_projection/cxg_immune_cell_atlas/train.h5ad",
"input_test": "resources_test/task_label_projection/cxg_immune_cell_atlas/test.h5ad",
"output": "output.h5ad",
}
meta = {
"name": "foo",
}
## VIASH END


def require_pca(adata_obj, label):
if "X_pca" not in adata_obj.obsm:
raise KeyError(f"{label} is missing obsm['X_pca']")


print("Load input data", flush=True)
input_train = ad.read_h5ad(par["input_train"])
input_test = ad.read_h5ad(par["input_test"])

require_pca(input_train, "input_train")
require_pca(input_test, "input_test")

print("Fit to train data", flush=True)
classifier = Pipeline(
steps=[
("scale", StandardScaler()),
("model", LinearDiscriminantAnalysis(solver="svd")),
]
)
classifier.fit(input_train.obsm["X_pca"], input_train.obs["label"].astype(str))

print("Predict on test data", flush=True)
label_pred = classifier.predict(input_test.obsm["X_pca"])

print("Create output data", flush=True)
output = ad.AnnData(
obs=pd.DataFrame({"label_pred": label_pred}, index=input_test.obs.index),
uns={
"method_id": meta["name"],
"dataset_id": input_test.uns["dataset_id"],
"normalization_id": input_test.uns["normalization_id"],
},
)

print("Write output data", flush=True)
output.write_h5ad(par["output"], compression="gzip")
37 changes: 37 additions & 0 deletions src/methods/shareclaw_logreg_balanced/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
__merge__: /src/api/comp_method.yaml
name: "shareclaw_logreg_balanced"
label: ShareClaw Logistic Regression Balanced
summary: "Standardize PCA coordinates and fit a class-balanced logistic regression classifier for macro-F1-oriented label projection."
description: |
ShareClaw Logistic Regression Balanced applies a StandardScaler to the PCA
embedding and fits a logistic regression classifier with balanced class
weights. The goal is to preserve a simple, reproducible linear baseline while
improving performance on rarer classes that matter for macro F1.
references:
bibtex: |
@book{hosmer2013applied,
title = {Applied logistic regression},
author = {Hosmer Jr, D.W. and Lemeshow, S. and Sturdivant, R.X.},
year = {2013},
publisher = {John Wiley \& Sons},
volume = {398}
}
links:
repository: https://github.com/anubhav1004/shareclaw
documentation: https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html
info:
preferred_normalization: log_cp10k
resources:
- type: python_script
path: script.py
engines:
- type: docker
image: openproblems/base_python:1
setup:
- type: python
packages: scikit-learn
runners:
- type: executable
- type: nextflow
directives:
label: [midtime, midmem, midcpu]
62 changes: 62 additions & 0 deletions src/methods/shareclaw_logreg_balanced/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import anndata as ad
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

## VIASH START
par = {
"input_train": "resources_test/task_label_projection/cxg_immune_cell_atlas/train.h5ad",
"input_test": "resources_test/task_label_projection/cxg_immune_cell_atlas/test.h5ad",
"output": "output.h5ad",
}
meta = {
"name": "foo",
}
## VIASH END


def require_pca(adata_obj, label):
if "X_pca" not in adata_obj.obsm:
raise KeyError(f"{label} is missing obsm['X_pca']")


print("Load input data", flush=True)
input_train = ad.read_h5ad(par["input_train"])
input_test = ad.read_h5ad(par["input_test"])

require_pca(input_train, "input_train")
require_pca(input_test, "input_test")

print("Fit to train data", flush=True)
classifier = Pipeline(
steps=[
("scale", StandardScaler()),
(
"model",
LogisticRegression(
max_iter=500,
solver="lbfgs",
random_state=7,
class_weight="balanced",
),
),
]
)
classifier.fit(input_train.obsm["X_pca"], input_train.obs["label"].astype(str))

print("Predict on test data", flush=True)
label_pred = classifier.predict(input_test.obsm["X_pca"])

print("Create output data", flush=True)
output = ad.AnnData(
obs=pd.DataFrame({"label_pred": label_pred}, index=input_test.obs.index),
uns={
"method_id": meta["name"],
"dataset_id": input_test.uns["dataset_id"],
"normalization_id": input_test.uns["normalization_id"],
},
)

print("Write output data", flush=True)
output.write_h5ad(par["output"], compression="gzip")
37 changes: 37 additions & 0 deletions src/methods/shareclaw_logreg_scaled/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
__merge__: /src/api/comp_method.yaml
name: "shareclaw_logreg_scaled"
label: ShareClaw Logistic Regression Scaled
summary: "Standardize PCA coordinates before fitting a higher-iteration logistic regression classifier for label projection."
description: |
ShareClaw Logistic Regression Scaled applies a StandardScaler to the PCA
embedding provided in the task inputs before fitting a multinomial logistic
regression classifier. The goal is to preserve the simplicity of a linear
baseline while using a more stable optimization setup for the task.
references:
bibtex: |
@book{hosmer2013applied,
title = {Applied logistic regression},
author = {Hosmer Jr, D.W. and Lemeshow, S. and Sturdivant, R.X.},
year = {2013},
publisher = {John Wiley \& Sons},
volume = {398}
}
links:
repository: https://github.com/anubhav1004/shareclaw
documentation: https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html
info:
preferred_normalization: log_cp10k
resources:
- type: python_script
path: script.py
engines:
- type: docker
image: openproblems/base_python:1
setup:
- type: python
packages: scikit-learn
runners:
- type: executable
- type: nextflow
directives:
label: [midtime, midmem, midcpu]
54 changes: 54 additions & 0 deletions src/methods/shareclaw_logreg_scaled/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import anndata as ad
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

## VIASH START
par = {
"input_train": "resources_test/task_label_projection/cxg_immune_cell_atlas/train.h5ad",
"input_test": "resources_test/task_label_projection/cxg_immune_cell_atlas/test.h5ad",
"output": "output.h5ad",
}
meta = {
"name": "foo",
}
## VIASH END


def require_pca(adata_obj, label):
if "X_pca" not in adata_obj.obsm:
raise KeyError(f"{label} is missing obsm['X_pca']")


print("Load input data", flush=True)
input_train = ad.read_h5ad(par["input_train"])
input_test = ad.read_h5ad(par["input_test"])

require_pca(input_train, "input_train")
require_pca(input_test, "input_test")

print("Fit to train data", flush=True)
classifier = Pipeline(
steps=[
("scale", StandardScaler()),
("model", LogisticRegression(max_iter=500, solver="lbfgs", random_state=7)),
]
)
classifier.fit(input_train.obsm["X_pca"], input_train.obs["label"].astype(str))

print("Predict on test data", flush=True)
label_pred = classifier.predict(input_test.obsm["X_pca"])

print("Create output data", flush=True)
output = ad.AnnData(
obs=pd.DataFrame({"label_pred": label_pred}, index=input_test.obs.index),
uns={
"method_id": meta["name"],
"dataset_id": input_test.uns["dataset_id"],
"normalization_id": input_test.uns["normalization_id"],
},
)

print("Write output data", flush=True)
output.write_h5ad(par["output"], compression="gzip")