smsnpycut
A small Python port of the R package smsncut: decision-theoretic optimal cutoff selection for a continuous diagnostic biomarker, modeled with scale mixtures of skew-normal (SMSN) distributions (Skew-Normal and Skew-t).
Given measurements from a healthy and a diseased group, it fits SMSN models by MLE and finds the cutoff that minimizes a weighted misclassification risk (accounting for disease prevalence and asymmetric false-positive/false-negative costs) — rather than just the symmetric Youden index. It also gives asymptotic confidence intervals for the cutoff, ROC/AUC, and Monte Carlo validation.
Install
uv sync
Quick start
import numpy as np
import smsnpycut as sc
rng = np.random.default_rng(0)
healthy = sc.SkewNormal(xi=0.0, omega=1.0, alpha=2.0)
diseased = sc.SkewNormal(xi=2.5, omega=1.2, alpha=-1.0)
fit0 = sc.fit(healthy.rvs(300, random_state=rng), family="SN")
fit1 = sc.fit(diseased.rvs(300, random_state=rng), family="SN")
# 70% prevalence of healthy, false negatives 3x costlier than false positives
c_opt = sc.optimal_cutoff(fit0.dist, fit1.dist, pi0=0.7, pi1=0.3, lam0=1.0, lam1=3.0)
ci = sc.confidence_interval(c_opt, sc.variance(c_opt, fit0, fit1, 0.7, 0.3, 1.0, 3.0))
print(c_opt, ci, sc.auc(fit0.dist, fit1.dist))
See main.py for a full worked example.
API
| Module | Purpose |
|---|---|
distributions |
SkewNormal, SkewT — pdf/cdf/rvs |
fit |
fit(x, family) — MLE via BFGS + Hessian |
cutoff |
optimal_cutoff, youden_cutoff, admissible_interval, boundary_ok |
inference |
variance, confidence_interval, identifiability |
roc |
roc_curve, auc |
simulate |
mc_validate — Monte Carlo check of the cutoff/CI recipe |
Citation
See CITATION.bib for the original R package and its companion paper (de Paula, Mouriño & Dias Domingues, 2026).
Release files for smsnpycut 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| smsnpycut-0.1.0.tar.gz | 41.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| smsnpycut-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.3 kB
Release files / smsnpycut-0.1.0.tar.gz
| Download URL | smsnpycut-0.1.0.tar.gz |
|---|---|
| Size | 41.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b5f28305b0f3fce1fb874f79971985cf8d407b9d29f9d2e05d5681521474625
|
|
BLAKE2b-256 checksum How to use checksums |
005c4dbd8b0147da7535eac30294e8890e36088aac25a32044a8ceb8ed08005d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / smsnpycut-0.1.0-py3-none-any.whl
| Download URL | smsnpycut-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
270f52a93b85ea392d07b827a92173fb75b939cd81f05cb052d350c6533d6e1a
|
|
BLAKE2b-256 checksum How to use checksums |
194bf896708e5a0083d3c9659142c72808f5610f1ed44463e2008a5485f9130f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|