{"id":44880637,"url":"https://github.com/cetic/tsquared","last_synced_at":"2026-02-17T16:04:40.921Z","repository":{"id":62585415,"uuid":"315611890","full_name":"cetic/tsquared","owner":"cetic","description":"Python implementation of Hotelling's T2 for process monitoring + MYT decomposition","archived":false,"fork":false,"pushed_at":"2025-09-09T11:22:44.000Z","size":3520,"stargazers_count":10,"open_issues_count":4,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-01-21T19:26:37.112Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/cetic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"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":"2020-11-24T11:31:51.000Z","updated_at":"2025-01-13T18:20:37.000Z","dependencies_parsed_at":"2022-11-03T22:06:23.652Z","dependency_job_id":"293ed1c2-c5a7-4d2f-8adc-ec69461bb1e0","html_url":"https://github.com/cetic/tsquared","commit_stats":{"total_commits":89,"total_committers":3,"mean_commits":"29.666666666666668","dds":0.4157303370786517,"last_synced_commit":"b37a7a58fbe2e1b2a6e4fed34e4218dfcd35e13e"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/cetic/tsquared","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cetic%2Ftsquared","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cetic%2Ftsquared/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cetic%2Ftsquared/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cetic%2Ftsquared/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cetic","download_url":"https://codeload.github.com/cetic/tsquared/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cetic%2Ftsquared/sbom","scorecard":{"id":271622,"data":{"date":"2025-08-11","repo":{"name":"github.com/cetic/tsquared","commit":"6b68648412047bc9a286e62ccf93f10fcfca71b2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T13:33:00.637Z","repository_id":62585415,"created_at":"2025-08-17T13:33:00.637Z","updated_at":"2025-08-17T13:33:00.637Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29549240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T14:33:00.708Z","status":"ssl_error","status_checked_at":"2026-02-17T14:32:58.657Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":[],"created_at":"2026-02-17T16:04:37.467Z","updated_at":"2026-02-17T16:04:40.915Z","avatar_url":"https://github.com/cetic.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TSquared\n\nPython implementation of Hotelling's T-squared (T2) for process monitoring and MYT decomposition.\n\n## Table of Contents\n\n1. [Features](#features)\n2. [Installation](#installation)\n3. [Questions](#questions)\n\t- [How TSquared is related to t-test?](#questions_ttest)\n\t- [How TSquared is related to Mahalanobis Distance?](#questions_mahalanobis_dist)\n\t- [How TSquared is related to MCD?](#questions_mcd)\n\t- [Should I use PCA with TSquared?](#questions_pca)\n\t- [Can I apply TSquared to any kind of process? What are the conditions on parameters to use TSquared?](#questions_conditions)\n\t- [Should I clean dataset before training? Is there a procedure to clean the data?](#questions_cleaning)\n\t- [What variables cause the outlier? What is MYT decomposition?](#questions_myt)\n\t- [How deviation types impact TSquared?](#questions_types)\n\t- [Is a TSquared monitoring sufficient? Or do I still need univariate monitoring?](#questions_sufficient)\n\t- [UCL, what does that mean in multivariate context? How to compute UCL?](#questions_ucl)\n\t- [My data are not normally distributed. Does it help to apply a Box-Cox transformation on each variables?](#questions_boxcox)\n4. [References](#references)\n\n## \u003ca name=\"features\"\u003e\u003c/a\u003e Features\n\n1. Classical multivariate T2 chart in which Hotelling's T2 statistic is computed as a distance of a multivariate observation from the multivariate mean scaled by the covariance matrix of the variables\n2. Python scikit-learn -like implementation\n3. Efficient with large datasets\n4. MYT decomposition\n\n## \u003ca name=\"installation\"\u003e\u003c/a\u003e Installation\n\nTSquared requires:\n\n- Python (\u003e= 3.6)\n- NumPy\n- Pingouin\n- scikit-learn\n- SciPy\n\nTSquared can be installed from PyPI:\n\n```sh\npip install tsquared\n```\n\n## \u003ca name=\"questions\"\u003e\u003c/a\u003e Questions\n\n### \u003ca name=\"questions_ttest\"\u003e\u003c/a\u003e How TSquared is related to t-test?\n\nHotelling's T2 is a generalization of the t-statistic for multivariate hypothesis testing\nWhen a single multivariate observation is compared to a reference distribution, it can be viewed as a generalization of the z-score.\nThe difference is the nature of the entities (point \u003e\u003c distribution) that are considered in the distance computation and in the denominator of the equation also.\n\n\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/z-score.jpg\"\u003e\n\nWhat's the relationship with z-score then?\n\n\u003ca href=\"figures/equ_zscore.png\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/equ_zscore.png\" width=\"300\"\u003e\u003c/a\u003e\n\n\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/equ_T2.png\" width=\"450\"\u003e\n\nX is in this case the observation (point) in the multivariate space.\n\nThe covariance matrix of the reference multivariate distribution is formed by covariance terms between each dimensions and by variance terms (square of standard deviations) on the diagonal.\n\n### \u003ca name=\"questions_mahalanobis_dist\"\u003e\u003c/a\u003e How TSquared is related to Mahalanobis Distance?\n\n\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/equ_mahalanobis.PNG\" width=\"550\"\u003e\n\n### \u003ca name=\"questions_mcd\"\u003e\u003c/a\u003e How TSquared is related to MCD?\n\nMCD = minimum covariance determinant is an algorithm available in the Outlier Detection framework pyOD\nMCD is based on Mahalanobis Squared Distance (MSD =~ Hotelling's T2)\nBased on the distribution of MSD, the training consists to find the subgroup of points ($h \u003c n$) that minimizes the covariance determinant. This subgroup of points can be thought of as the minimum number of points which must not be outlying (with $h \u003e n/2$ to keep a sufficient number of point)\n\n⟹ It is equivalent to the cleaning operation in TSquared.\n\n### \u003ca name=\"questions_pca\"\u003e\u003c/a\u003e Should I use PCA with TSquared?\n\nYes, you can!\n\nBut this should be done cautiously\n\n1. PCA defines new coordinates for each points\n2. PCA is often used to reduce dimensionality by selecting the strongest \"principal\" components defining the underlying relation between variables\n3. T2 score on all PCA components = T2 on all original variables \n\nCan we apply T2 on a reduced number of (principal) components?\nLet's try a 2D example. In the following picture, the relation between Var1 and Var2 is mostly linear, these variables are strongly correlated. Let's suppose that the first component of the PCA is sufficient to define the relation, second component being the noisy part of the relation.\n\n\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/Capture_pca.PNG\" width=\"500\"\u003e\n\nIn this case, monitoring any future observation is like applying a z-score (1 dimension) to this observation compared to the distribution of all past observations projected on the first component axis.\n\nIf a loss of correlation happened between Var1 and Var2, it won't be seen on this univariate monitoring because it is the second component that will be impacted. This can happened if the sensor capturing Var2 is defective. \n\nBy extension to more dimensions, we understand that reducing \"blindly\" the number of components before a TSquared monitoring is not advised. It is certainly not a thing to do in case of sensors validation.\n\nInstead, if PCA is used to reduce the dimensionality, it is advised to monitor as well the residual group of components in a separated monitoring.\n\n### \u003ca name=\"questions_conditions\"\u003e\u003c/a\u003e Can I apply TSquared to any kind of process? What are the conditions on parameters to use TSquared?\n\nThe basic assumption is that all variables should be normally distributed. \nHowever, the algorithm is tolerant to some extent if the distributions are not perfectly normal.\n\n### \u003ca name=\"questions_cleaning\"\u003e\u003c/a\u003e Should I clean dataset before training? Is there a procedure to clean the data?\n\nYes, the cleaner the better\n\nThe TSquared procedure can be applied 1 or 2 times to the training set and outliers can be filtered at each round.\n\nThe risk to work with a training set not clean is to have an univariate outlier which is an inlier in multivariate, the multivariate UCL being too large (Observation n°78).\n\n\u003cimg src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/Image_inlier.png\"\u003e\n\n### \u003ca name=\"questions_myt\"\u003e\u003c/a\u003e What variables cause the outlier? What is MYT decomposition?\n\n### \u003ca name=\"questions_types\"\u003e\u003c/a\u003e How deviation types impact TSquared?\n\n### \u003ca name=\"questions_sufficient\"\u003e\u003c/a\u003e Is a TSquared monitoring sufficient? Or do I still need univariate monitoring?\n\n### \u003ca name=\"questions_ucl\"\u003e\u003c/a\u003e UCL, what does that mean in multivariate context? How to compute UCL?\n\n### \u003ca name=\"questions_boxcox\"\u003e\u003c/a\u003e My data are not normally distributed. Does it help to apply a Box-Cox transformation on each variables?\n\nThe experiment was done using TSquared auto-cleaning function and Box-Cox transformation on each variables.\n\n## \u003ca name=\"references\"\u003e\u003c/a\u003e References\n\n- \u003ccite\u003e Decomposition of T2 for Multivariate Control Chart Interpretation, ROBERT L. MASON, NOLA D. TRACY and JOHN C. YOUNG\u003c/cite\u003e\n\n\t[Decomposition of T2 for Multivariate Control Chart Interpretation]: ../Références/Decomposition%20of%20T2%20for%20Multivariate%20Control%20Chart%20Interpretation.pdf\n\n- \u003ccite\u003e Application of Multivariate Statistical Quality Control In Pharmaceutical Industry, Mesut ULEN, Ibrahim DEMIR\u003c/cite\u003e\n\n\t[Application of Multivariate Statistical Quality Control In Pharmaceutical Industry]: ../Références/Application%20of%20Multivariate%20Statistical%20Quality%20Control%20In%20Pharmaceutical%20Industry.pdf\n\n- \u003ccite\u003e Identifying Variables Contributing to Outliers in Phase I, ROBERT L. MASON, YOUN-MIN CHOU, AND JOHN C. YOUNG\u003c/cite\u003e\n\n\t[Identifying Variables Contributing to Outliers in Phase I]: ../Références/Identifying%20variables%20contributing%20to%20outliers%20in%20Phase%20I.pdf\n\n- \u003ccite\u003e Multivariate Control Charts for Individual Observations, NOLA D. TRACY, JOHN C. YOUNG, ROBERT L. MASON\u003c/cite\u003e\n\n\t[Multivariate Control Charts for Individual Observations]: ../Références/Multivariate%20control%20charts%20for%20individual%20observations.pdf\n\n\u003c!---\n![](figures/z-score.jpg)\n![](figures/equ_zscore.png)\n![](figures/equ_T2.png)\n---\u003e\n\u003c!---\n\u003ca href=\"https://github.com/cetic/TSquared/tree/master/figures/z-score.jpg\"\u003e\u003cimg class=\"fig\" src=\"https://raw.githubusercontent.com/cetic/tsquared/master/figures/z-score.jpg\" style=\"width:100%; height:auto;\"/\u003e\u003c/a\u003e\n---\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcetic%2Ftsquared","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcetic%2Ftsquared","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcetic%2Ftsquared/lists"}