{"id":26829819,"url":"https://github.com/scai-bio/syndat","last_synced_at":"2026-03-06T19:12:25.402Z","repository":{"id":213560876,"uuid":"734391183","full_name":"SCAI-BIO/syndat","owner":"SCAI-BIO","description":"Synthetic data quality evaluation \u0026 visualization ","archived":false,"fork":false,"pushed_at":"2026-01-26T08:35:28.000Z","size":805,"stargazers_count":4,"open_issues_count":7,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-04T21:59:35.019Z","etag":null,"topics":["data-quality","data-visualization","synthetic-data"],"latest_commit_sha":null,"homepage":"https://syndat.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SCAI-BIO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-21T15:05:08.000Z","updated_at":"2026-01-26T08:35:30.000Z","dependencies_parsed_at":"2024-05-16T02:15:04.758Z","dependency_job_id":"18da65db-af2a-48df-8d39-51e48a8ab395","html_url":"https://github.com/SCAI-BIO/syndat","commit_stats":null,"previous_names":["scai-bio/syndat"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/SCAI-BIO/syndat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCAI-BIO%2Fsyndat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCAI-BIO%2Fsyndat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCAI-BIO%2Fsyndat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCAI-BIO%2Fsyndat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SCAI-BIO","download_url":"https://codeload.github.com/SCAI-BIO/syndat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCAI-BIO%2Fsyndat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30192613,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-quality","data-visualization","synthetic-data"],"created_at":"2025-03-30T13:19:18.020Z","updated_at":"2026-03-06T19:12:25.393Z","avatar_url":"https://github.com/SCAI-BIO.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cpicture align=\"left\"\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/SCAI-BIO/syndat/refs/heads/main/docs/logo/syndat_white.svg\"\u003e\n  \u003cimg alt=\"Syndat Logo\" src=\"https://raw.githubusercontent.com/SCAI-BIO/syndat/refs/heads/main/docs/logo/syndat.svg\"\u003e\n\u003c/picture\u003e\n\n[![DOI](https://zenodo.org/badge/734391183.svg)](https://doi.org/10.5281/zenodo.15791976)\n![tests](https://github.com/SCAI-BIO/syndat/actions/workflows/tests.yaml/badge.svg) [![codecov](https://codecov.io/gh/SCAI-BIO/syndat/branch/main/graph/badge.svg)](https://codecov.io/gh/SCAI-BIO/syndat) ![docs](https://readthedocs.org/projects/syndat/badge/?version=latest\u0026style=flat) ![version](https://img.shields.io/pypi/v/syndat)\n\n[![NFDI4Health](https://img.shields.io/badge/Developed_in-NFDI4Health-1E88E5)](https://www.nfdi4health.de)\n[![SYNTHIA](https://img.shields.io/badge/Extended_in-SYNTHIA-8E24AA)](https://www.ihi-synthia.eu)\n\n\n\n# About\n\nSyndat is a software package that provides basic functionalities for the evaluation and visualisation of synthetic data. Quality scores can be computed on 3 base metrics (Discrimation, Correlation and Distribution) and data may be visualized to inspect correlation structures or statistical distribution plots. \n\nSyndat also allows users to generate stratified and interpretable visualisations, including raincloud plots, GOF plots, and trajectory comparisons, offering deeper insights into the quality of synthetic clinical data across different subgroups.\n\n# Installation\n\nInstall via pip:\n\n```bash\npip install syndat\n```\n\n# Usage\n\n## Fidelity metrics\n\n### Jenson-Shannon Distance\n\nThe Jenson-Shannon distance is a measure of similarity between two probability distributions. In our case, we compute\nprobability distributions for each feature in the datasets and compute and can thus compare the statistic feature \nsimilarity of two dataframes. \n\nIt is bounded between 0 and 1, with 0 indicating identical distributions. \n\n### (Normalized) Correlation Difference\n\nIn addition to statistical similarity between the same features, we also want to make sure to preserve the correlations\nacross different features. The normalized correlation difference measures the similarity of the correlation matrix of \ntwo dataframes.\n\nA low correlation difference near zero indicates that the correlation structure of the synthetic data is similar to the \nreal data.\n\n### Discriminator AUC\n\nA classifier is trained to discriminate between real and synthetic data. Based on the Receiver Operating Characteristic \n(ROC) curve, we compute the area under the curve (AUC) as a measure of how well the classifier can distinguish between \nthe two datasets. \n\nAn AUC of 0.5 indicates that the classifier is unable to distinguish between the two datasets, while an AUC of 1.0 \nindicates perfect discrimination.\n\nExemplary usage:\n\n```python\nimport pandas as pd\nfrom syndat.metrics import (\n    jensen_shannon_distance,\n    normalized_correlation_difference,\n    discriminator_auc\n)\n\nreal = pd.DataFrame({\n    'feature1': [1, 2, 3, 4, 5],\n    'feature2': ['A', 'B', 'A', 'B', 'C']\n})\n\nsynthetic = pd.DataFrame({\n    'feature1': [1, 2, 2, 3, 3],\n    'feature2': ['A', 'B', 'A', 'C', 'C']\n})\n\nprint(jensen_shannon_distance(real, synthetic))\n\u003e\u003e {'feature1': 0.4990215421876156, 'feature2': 0.22141025172133794}\n\nprint(normalized_correlation_difference(real, synthetic))\n\u003e\u003e 0.24571345029108108\n\nprint(discriminator_auc(real, synthetic))\n\u003e\u003e 0.6\n```\n\n### Scoring Functions\n\nFor convenience and easier interpretation, a normalized score can be computed for each of the \nmetrics instead:\n\n```python\n# JSD score is being aggregated over all features\ndistribution_similarity_score = syndat.scores.distribution(real, synthetic)\ndiscrimination_score = syndat.scores.discrimination(real, synthetic)\ncorrelation_score = syndat.scores.correlation(real, synthetic)\n```\n\nScores are defined in a range of 0-100, with a higher score corresponding to better data fidelity.\n\n## Visualization\n\nVisualize real vs. synthetic data distributions, summary statistics and discriminating features:\n\n```python\nimport pandas as pd\nimport syndat\n\nreal = pd.read_csv(\"real.csv\")\nsynthetic = pd.read_csv(\"synthetic.csv\")\n\n# plot *all* feature distribution and store image files\nsyndat.visualization.plot_distributions(real, synthetic, store_destination=\"results/plots\")\nsyndat.visualization.plot_correlations(real, synthetic, store_destination=\"results/plots\")\n\n# plot and display specific feature distribution plot\nsyndat.visualization.plot_numerical_feature(\"feature_xy\", real, synthetic)\nsyndat.visualization.plot_numerical_feature(\"feature_xy\", real, synthetic)\n\n# plot a shap plot of differentiating feature for real and synthetic data\nsyndat.visualization.plot_shap_discrimination(real, synthetic)\n```\n\n\n## Postprocessing\n\nPostprocess synthetic data to improve data fidelity:\n\n```python\nimport pandas as pd\nimport syndat\n\nreal = pd.read_csv(\"real.csv\")\nsynthetic = pd.read_csv(\"synthetic.csv\")\n\n# postprocess synthetic data\nsynthetic_post = syndat.postprocessing.assert_minmax(real, synthetic)\nsynthetic_post = syndat.postprocessing.normalize_float_precision(real, synthetic)\n```\n\n## Evaluation and Visualization of Synthetic Clinical Trial Data\n\nAn example demonstrating how to compute distribution, discrimination, and correlation scores, as well as how to generate stratified visualizations (gof, raincloud and other plots), is available in `examples/rct_example.py`.\n\n# Acknowledgements\n\nThis work was done as part of the [NFDI4Health](https://www.nfdi4health.de) Consortium. \n\nIt is currently also being extended as part of the [SYNTHIA](https://www.ihi-synthia.eu/) collaboration.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscai-bio%2Fsyndat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscai-bio%2Fsyndat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscai-bio%2Fsyndat/lists"}