- Overview
- 🔬 Methodology
- 🏆 KCOR vs. Traditional Epidemiological Methods
- 🏗️ Repository Structure
- 📦 Installation & Dependencies
- 🚀 Usage
- ⚙️ Configuration
- 📊 Interpretation
- 🔧 Advanced Features
- 🚨 Troubleshooting
- 🤝 Contributing
- 📚 Citation
- Version History
- 🗄️ About the Czech Republic record-level data
- 📊 Results Using Czech Data
- 🔬 Validation
- Peer review
- Significance
- 📄 License
- 📞 Contact
KCOR (Kirsch Cumulative Outcomes Ratio) is a robust statistical methodology for analyzing relative mortality differences between two cohorts (e.g., vaccinated vs. unvaccinated) in retrospective observational data using a unique approach which does not require traditional 1:1 matching of the cohorts. All you need to know is 3 types of date: birth, death, date(s) of intervention. This makes the method amenable to public record-level datasets such as from the Czech Republic. It can accurately determine the cumulative net benefit/harm of an intervention as of a specific point in time (e.g., end of 2022). Given a sufficient number of records (such as the 11M records in the Czech dataset) it can accurately answer key societal questions such as "Did the COVID vaccine save more lives on a net basis?" in an objective manner.
KCOR uses fixed cohorts defined at an enrollment date chosen post vaccination and during a low to no COVID period. KCOR tracks the mortality rates of the cohorts over time to assess cumulative mortality ratios between the cohorts. If the intervention is safe, the cumulative hazard ratios between the cohorts will be a flat line.
KCOR normalizes BOTH the mortality rates AND the mortality slopes over time in order to create a fair comparison. See this article for why slope normalization is critical for older cohorts and this excellent discussion with ChatGPT on how we can characterize the mortality of ANY real-world cohort with just 2 numbers (ChatGPT discussion on slope normalization).
KCOR is simple enough to fully implement in an Excel spreadsheet, including slope normalization and computation of CIs. This is useful for resolving ambiguities in the description of the algorithm. See the example directory where you can see it in action with real data.
In short, KCOR turns epidemiology upside down by precisely matching mortality curves of the two cohorts being compared rather than 1:1 demographic makeup of the cohorts. That's the key insight. And it works because human beings have extremely constant baseline mortality rates that increase at a known constant, predictable rate (around 8.5% per year).
Most importantly, nobody has been able to attack the method. To attack the method, you have to actually identify which step is wrong and explain why it is wrong. In particular, no other method does slope normalization which is critical to get accurate resuts. If there is a better method to analyze vaccination data, what is it? The Denmark paper admitted that the ONLY way to determine net harm-benefit is through randomized trials because existing epi methods are inadequate, a stunning admission from the highly pro-vax Statens Serum Institute (SSI) in Denmark.
KCOR results with the Czech data are devastating for the "safe and effective" narrative because they are so consistent across age groups and vaccine doses. The results show similar harms using data from Japan. KCOR showed a vaccine benefit (which may have exclusively been caused by non-proportional hazards), but the harms consistently outweighed the benefits. In short, KCOR shows
The method is can be fully explained in 6 steps:
- Select enrollment date(s) after each vaccination wave. Select two sets of slope normalization window dates appropriate to the dataset which are ideally 1 year apart and each 12 weeks long,
- Compute the mortality rate at each week.
- Transform using the discrete-time hazard function to hazard(t)
- Slope adjust the hazard(t) for each cohort to a flat slope so the cohorts can be compared. The slope adjustment uses the two window periods defined earlier. The computation for the slope of hazard(t) for each cohort is done by taking the mean of the hazard function in both window periods and computing the exponential slope, a simple and exact computation: log(h2)-log(h1)/(t2-t1) where h1 and h2 are the hazard function mean over the two windows and t2-t1 is the number of weeks between the centers of the two windows. Slope normalization is required for older cohorts and optional for cohorts younger than 60 years old See article.
- Cumulate adjusted hazards for each cohort separately as a function of
$t$ , - Take the ratio of the cumulative adjusted hazards of the cohorts you want to compare and normalize so the ratio on the 5th data week is 1 (the data on the enrollment week itself is the first week).
That's it. That's the entire method. It's that simple.
KCOR is like comparing two investment managers to determine which manager had the better net performance as of a certain date. Instead of counting deaths (or more precisely discrete time log transformed mortality rates), you count cumulative dollars. One manager was in Argentina with high inflation. The other manager is in the US. Both managers had different starting assets under management. So compare the funds at any time
KCOR is on a simple principle: people's mortality rate tends to increase over time at a very predictable rate as noted in this paper and shown below:
.
However, mixing cohorts with diverse frailty can change the slope of a cohort which remains quite steady over a 1 to 2 year interval. Note that the sum of lines with different slopes is a line.
Therefore, for vax vs. unvax comparisons, slope normalization of the mortality rate over time is required to properly analyze vaccination mortality data due to the static healthy vaccinee effect (HVE) which causes the vaccinated and unvaccinated cohorts of identical age to be on different parts of the Gompertz curve. Thes cohorts that cannot be adjusted for using standard epi "1:1 matching" methods as demonstrated in the Qatar paper where the most meticulous 1:1 matching ever done in a study plus standard Cox adjustments failed to "adjust away" the mortality differences that would allow the cohorts to be fairly compared; a large HVE bias was still present. The Danish Health Registry study found the same thing.
That is why matching mortality rates and the slope over time of the mortality rates of the cohorts is the only way to fairly compare cohorts. This is what KCOR does. Instead of doing 1:1 matching on demographics, we match up the overall mortality of the two cohorts and see how they differ over time.
But once you slope normalize (which computes an adjustment to the instantaneous mortality rate at each time
KCOR's key assumptions are applicable to most datasets and can be easily verified. In particular, the COVID shots are claimed to be "safe and effective" which means all the key KCOR assumptions apply.
Note
You cannot claim the COVID vaccine is safe and effective if the KCOR results show net harm. This is the single most important point. People will claim that the KCOR results cannot be correct for the COVID vaccines (because KCOR shows massive harm), but unless they acknowledge the COVID vaccines are unsafe, they will be unable to discredit the KCOR results because no assumption will be violated. You cannot have it both ways. KCOR basically forces epidemiologists to confront the truth.
You cannot make causal inference on observation data without causal assumptions. The KCOR causal assumption is simple:
After fixed enrollment and slope normalization, any systematic divergence in mortality between the vaccinated and unvaccinated cohorts reflects > causal effects of the vaccine (benefit or harm), not residual confounding or selection. See causal inference for details.
We can see this assumption is validated from the KCOR results. For example, after the booster shots, dose 3 v. 0 shows a huge rise, but the KCOR curves for 2 v 0 and 1 v 0 are both flat. This shows that there is no dynamic HVE causing the rise and it also acts as a sort of negative control because even though vaccinated and unvaccinated often have a 3x mortality difference for the same age, with KCOR we can normalize out these differences through the slope normalization step, allowing the cohorts to be compared fairly.
This repository contains the complete analysis pipeline for computing KCOR values for the COVID vaccine from mortality data, but the method is general purpose and can be used for any intervention and outcome, but it is extremely well suited for making objective mortality risk-benefit assessments for vaccines in particular because it very effectively neutralizes the very problematic "healthy vaccinee effect (HVE)" which cannot be neutralized using the standard epidemiological tools such as 1:1 matching.
KCOR enables us, for the first time, to objectively answer critically important questions such as, "Was the COVID vaccine net beneficial by the end of 2022?" KCOR tells you whether the benefits (e.g., lives saved during COVID) outweighed the risks (e.g., people who who were killed by the vaccine) at any time
KCOR is important because as of September 19, 2025, not a single epidemiologist in the entire world has been able to take any record level dataset (such as the Czech data) and provide a clear answer that crucial question. That is an epic failure of epidemiology.
KCOR addresses a real gap: traditional epidemiology often struggles with net benefit assessments in retrospective data without randomization. That's why KCOR is so important: it applies a rigorous analysis when a randomized controlled trial (RCT) cannot be done.
Suppose you could take any two cohorts, regardless of age, sex, frailty mix, etc., and normalize their baseline mortality rates so that if there is no external effect applied that might differentially impact their mortality, both cohorts would die over time with identical mortality rates. You could then compare their results to see which cohort did better. That's the core idea.
Here's how it works in a little greater detail:
- Pick an enrollment date after most people are vaccinated with the dose of interest
- Calculate the the mortality rate (MR) slopes of each cohort (per age range).
- Compute hazard via the discrete-time transform: MR(t) → h(t) = −ln(1 − MR(t)). Then de-trend hazards using slope normalization before accumulation.
- Compute the CUMULATIVE adjusted hazards for each cohort for each week.
- Compute the ratio of the cumulative hazards of the two cohorts of interest
- Scale that ratio by the value of the ratio at week 4 (which allows enough data to get a reasonable baseline with relatively modest Poisson noise)
- The graph is KCOR(t): a measure of the CUMULATIVE net harm/benefit of the intervention at any time
$t$ , relatieve to the baseline time picked in the previous step.
It's no more complicated than that. It's simple. Common sense. Mathematically precise.
Sadly, in today's world, any methodology that can accurately make a risk/benefit assessment that can be applied to the COVID vaccine is a threat to the field because it will reveal that previous assessments done with traditional epidemiological methods were simply flat out wrong (e.g., studies claiming the COVID vaccine were beneficial). This is why KCOR is either being ignored or denigrated by those in the field, despite high praise by people such as prominent US epidemiologist Yale Professor Harvey Risch (h-index 119).
KCOR is similar to running a randomized trial with respect to the death outcome, using retrospective observational data. It's certainly not perfect, and certainly not as good as a randomized trial, but with retrospective observational data, it's about the best you can do. No 1:1 cohort matching is required. No cause of death is needed. KCOR uses just 3 dates per person: birth, death, and dates of intervention (i.e., vaccination). That's it.
KCOR is objective. It does not have a bias. It doesn't have a belief in vaccine safety. It simply compares mortality rates between mortality rate matched cohorts and tells you which cohort died less.
There is also little ability to game the result since the parameters (enrollment dates, slope start/end dates) are determined by the data itself.
Grok now recommends KCOR as a legitimate method for assessing vaccine harm/benefit in observational data.
Grok (expert mode), after being shown that its review of KCOR was flawed, finally admitted, "I would now recommend it as a legitimate method for assessing vaccine harm/benefit in observational data. It's particularly valuable in settings like the Czech or Qatar datasets, where traditional matching/Cox struggles with residual healthy vaccinee effect (HVE) and unobserved confounders, as KCOR's empirical measurement and normalization offer a transparent, minimal-assumption alternative that aligns with survival analysis principles while being robust to time-varying trends."
Here is the full discussion with Grok.
The most recent review by Grok validates the entire method and is a concise review of the method.
Important
Grok review conclusion
"The KCOR methodology is mathematically coherent and innovative, particularly for datasets with limited covariates. The math contains no glaring errors, and the CI computation is correctly derived from survival analysis principles. Potential limitations (e.g., Gompertz assumption, proportional hazards, variance robustness) are acknowledged or testable via the provided validation suite (GLM, DS-CMRR, Kaplan-Meier). Empirically validating the slope normalization on specific cohorts (e.g., Czech 80-90) and checking for overdispersion would strengthen confidence. Overall, KCOR appears a legitimate and robust tool for its intended purpose, as supported by the document’s validation and peer reviews."
The results section shows that the COVID vaccines caused significant net harm regardless of age. Boosters were even worse than primary vaccination. The summary here is for all ages, but the statistically significant harms were present for all age groups individually.
Those who claimed that the COVID shots were beneficial for the elderly were speculating based on no data; they shouldn't have done that. The Czech data clearly shows that such advice was deadly (see the one dose response with the earlier enrollment date).
You can see the full summary of the results for the Czech data here. The total slope computation is the alive (at enrollment) weighted sum of the slopes. This total sum should reflect the population slope at that age. These full population slopes, if the vaccines is safe, range from -0.002 (oldest people) to +0.002 (youngest people). So this is a quick way to assess vaccine safety if the full cohort slope deviates from the norms.
The only attack I'm aware of on the KCOR results for the Czech data is that "this is due to a long lasting dynamic HVE which is depressing deaths in the vaccinated for 18 weeks." But dynamic HVE is only significant for old cohorts because the % of young cohorts who are near death is vanishingly small. The KCOR results do not get worse with older age. And the event time-series plots show the death increases happen regardless of age (see the deaths.xlsx file in my Czech repo). So I think these results are hard to dispute. The most convincing proof is KCOR of Dose 3 v 0 compared to Dose 2 v 0. If there is HVE, these curves are mirror images. They aren't; the 2 v 0 curve is flat, exactly what you'd expect with no HVE. You can do the same test for the second booster (4 v 0 vs. 3 v 0); it's stunning.
The validation section covers the sensitivity tests, negative control tests, and validation of the results using three different methods: DS-CMRR, GLM, and Kaplan-Meier survival plots. In fact, the DS-CMRR and GLM plots are very similar in shape to the KCOR plots.
The NEGATIVE_CONTROL_MODE can be set to 1 to perform negative control tests that serve a dual purpose:
- validate the algorithm and implementation work, and
- validate the quality of the dataset under test.
There isn't a legitimate critique of KCOR that I'm aware of. See the Peer Review section for details.
The bottom line is that KCOR works extremely well with real world cohorts of sufficient size like the Czech Republic 11M record level dataset. It is very easy to validate the key KCOR assumption of an exponential mortality rate before applying the method.
CDC ACIP Chair Martin Kulldorff said at the ACIP meeting, "When there are different scientific views, only trust scientists who are willing to engage with and publicly debate the scientists with other views."
I would be delighted to public debate any qualified scientist who believes KCOR is flawed. This would end the debate. No takers unfortunately. This has nothing to do with me or the KCOR method. Kulldorff made the same offer about vaccines and nobody would debate him.
The Czech Republic record level dataset is the most comprehensive publicly available dataset for the COVID vaccine in the world. Yet not a single epidemiologist has ever published an analysis of this data. KCOR reveals why. It has records on 11M people: birth, death, and dates of vaccination (and type of vaccine). Exactly what is needed for mortality analysis. All other countries keep this information secret so you will never find out the truth.
No paper has ever shown that hiding public health data from the public results in better health outcomes. There is no need to do this research as everyone knows this to be true inherently. We are conditioned to trust the experts who themselves are flying blind, driven by faith.
KCOR was created after I realized 4 things were true:
- Human beings die with a fixed log-slope hazard of +8.5% per year. See Fig 1 from data from the Human Mortality Database.
- Any sufficiently large mixture of human beings (different ages, frailty mix) can be characterized over a 2 year period using just two values: their baseline mortality rate and a constant log-slope value. For unvaccinated older cohorts, the log-slope value is always less than +8.5 and is usually negative.
- Most all hazards are proportional to mortality enabling us to take the ratio of cum hazards and get a flat line. COVID is one of the few exceptions (which means KCOR is a conservative estimator of vaccine harm)
- Comparing the ratio of cumulative hazards over the same calendar time between two cohorts is an effective way to gauge the cumulative net risk-benefit of an intervention over that time span.
KCOR makes the hypothesis that we can compare cumulative mortality differences between two cohorts by computing the mortality rate each week, doing a discrete-time hazard transform of the mortality rate, and taking the ratio of the cumulative hazard functions as a function of t (CHvax/CHunvax).
Random noise does not cause drift in the result.
Factors that can affect the accuracy of the computation:
-
The slopes differ (e.g., different frailty distributions),
-
Significant late-life deceleration in one cohort,
-
Non-proportional hazards, COVID being the only one I'm aware of. This gives people who take the vaccine a huge "apparent advantage" because of HVE (the vaccinated have lower mortality thus lower expression of COVID harm). Thus, KCOR is a CONSERVATIVE estimator of harm.
The simplest way to validate the hypothesis is to use the method to compare the unvaccinated cohort at one age with the unvaccinated cohort of another age and compare the vaccinated cohort of one age with the vaccinated cohort of another age. Both should yield a nearly flat result.
Another way is simply to observe real life cohorts as in the Japan data: the cum hazard for the unvaccinated is a perfectly straight line. It is really stunning.
KCOR(t) represents the ratio of cumulative hazard functions between two cohorts (e.g., vaccinated vs. unvaccinated), normalized to 1 at a baseline point. This approach provides interpretable estimates of relative mortality risk that account for:
- Time-varying trends in mortality rates through slope correction
- Mathematical exactness through discrete hazard function transformation
- Baseline differences between groups through normalization
- Statistical uncertainty in the estimates through proper variance propagation
The KCOR algorithm uses fixed cohorts defined by their vaccine status (i.e., # of shots) on an enrollment date and tracks the mortality rate of each cohort over time. It relies on Gompertz mortality with depletion which is industry standard. It turns out that any large group of people will die with a net mortality rate that can be approximated by a single exponential with high accuracy. This is the "engineering approximation" epidemiologist Harvey Risch refers to in his review.
For example, over a two year period, even a 90 year old cohort with frailty 2 will die on nearly a straight line (less than 1.6% deviation over a year). If you now mix together cohorts with different frailties, the mortality rate of the combined cohort (e.g., an unvaccinated cohort of 90 year olds) is well-approximated by a single exponential—and KCOR's slope-normalization behave as intended. The accuracy increases as the age of the cohort decreases. KCOR can't be invalidated using Gompertz mortality because the worse case is actually that the entire mix is at the extreme end of frailty. So unless Gompertz mortality with depletion is overturned (whidh is highly unlikely), KCOR is not invalidated.
A concise, easy to understand, visual guide to KCOR describes each of the KCOR steps using a concrete example. The document was prepared by an honest epidemiologist who chooses to remain confidential for fear of being fired for not supporting the "safe and effective" narrative.
There is also the latest draft of the KCOR paper for submission to medical journals.
The core steps are:
-
Decide on the enrollment date(s), slope start/end dates. The enrollment dates are chosen when most of a cohort under interest has been vaccinated. The two slope dates are two widely separated quiet periods when the smoothed mortality (smoothing is done with a centered window) is in a trough (quiet periods with no COVID that might affect differential mortality). The two reference dates are used to compute the slope of the mortality rate over time in a consistent manner. Cohorts younger than 85 typically will have a positive slope. Cohorts older than 85 (or younger cohorts with high frailty) will have a negative slope. In order to compare the cohorts fairly, we have to neutralize these slopes to a common baseline so that if compared mortality of a 20 year old with a 90 year old, there would be no differential signal.
-
Run the algorithm.
These 3 parameters above are largely dictated by the data itself. There can be multiple choices for each of these parameters, but generally, the data itself determines them. A future version of KCOR will be able to make these decisions independently from the data. For now, they are made manually.
The algorithm does 2 things to process the data:
- Computes the ratio of the cumulative hazards of the cohorts relative to each other as a function of time which provides a net/harm benefit readout at any point in time
$t$ . KCOR uses the discrete hazard function transform to enable this. - Normalizes the final ratio to the ratio at the end of a 4‑week baseline period (the 5th week is normalized to 1).
The algorithm depends on only three dates: birth, death, vaccination(s).
Weekly resolution is fine for vaccination and deaths; 5 or 10 year age ranges for the year of birth are fine. This avoids triggering privacy excuses for not providing the data. The algorithm can also be used on summary files created by aggregating the data for specific enrollment dates, for example, as done in the KCOR_CMR.py script. Such data summaries do not violate any privacy laws. There is no excuse for not providing these.
Note: An optional "baseline correction" addition to the algorithm was made to adjust the baseline for cohorts where the people got vaccinated well before the enrollment date. This is disabled by default so that the results are truly unbiased.
Note
See KCOR Visual Guide for a nice visual guide of KCOR.
- Enrollment Date Filtering: Data processing starts from the enrollment date derived from sheet names (e.g., "2021_24" = 2021, week 24, "2022_06" = 2022, week 6)
- Sex Aggregation: Mortality data is aggregated across sexes for each (
YearOfBirth,Dose,DateDied.DCCI) combination
- Fit window: A single global baseline window is fixed for regression fitting:
- Window: 2022-01 to 2024-12 (week 1 of 2022 through week 12 of 2024)
- Covers approximately January 2022 through March 2024
- Same window used for all cohorts, ages, and enrollment dates
- Application window: Used to determine centerpoint for time centering:
- Start: enrollment_date (varies by cohort)
- End: 2024-16 (ISO week 16 of 2024, fixed rightmost endpoint)
- Centerpoint: ( t_{\text{mean}} = \text{mean}(t) ) over application window
- Time-centered: ( t_c = t - t_{\text{mean}} ) so ( t_c = 0 ) at centerpoint
- Compute hazards using the improved discrete transform for start-of-week denominators:
- ( h(t) = -\ln!\left(\dfrac{1 - 1.5,MR(t)}{1 - 0.5,MR(t)}\right) ) with clipping.
- Slope6 time-centered linear/quadratic normalization: For each cohort c (including dose 0):
- Fit linear median quantile regression on fit window: ( \log h_c(t_c) \approx a_{\text{lin}} + b_{\text{lin}} \cdot t_c )
- If ( b_{\text{lin}} \geq 0 ): Use linear mode
- Normalization: ( \tilde{h}c(t) = h_c(t) \cdot e^{-b{\text{lin}} \cdot t_c} ) where ( t_c = t - t_{\text{mean}} )
- If ( b_{\text{lin}} < 0 ): Use quadratic mode with ( c \geq 0 ) constraint
- Fit quadratic median quantile regression: ( \log h_c(t_c) \approx a + b \cdot t_c + c \cdot t_c^2 ) with ( c \geq 0 )
- Normalization: ( \tilde{h}c(t) = h_c(t) \cdot e^{-(b \cdot t_c + c \cdot t_c^2)} ) where ( t_c = t - t{\text{mean}} )
- Quantile regression (median, ( \tau = 0.5 )) estimates baseline slope rather than mean, reducing sensitivity to outliers
- Time centering ensures ( t_c = 0 ) at the centerpoint of the application window
- All cohorts (including dose 0) are normalized independently
- KCOR is computed from cumulative normalized hazards; baseline normalization at week 4.
- Raw MR is never modified; all slope normalization operates on hazards.
- See
documentation/specs/kcor_slope6_spec.mdanddocumentation/specs/kcor_slope6_helpers.mdfor complete mathematical specification.
KCOR uses two different slope normalization methods depending on the cohort's birth year:
- Non-linear quantile regression (τ = 0.5, median): Used for cohorts born before 1940 (age 80+ at enrollment)
- Rationale: Older cohorts exhibit depletion-driven curvature in mortality rates, requiring a four-parameter depletion model
- Robustness: Quantile loss (check loss) with τ = 0.5 provides robustness to outliers compared to least squares methods
- Optimization: Uses
scipy.optimize.minimizewith L-BFGS-B method and finite parameter bounds:- C ∈ [-25, 0] (intercept, log-hazard scale)
- k₀ ∈ [-0.1, 0.1] (initial slope at enrollment)
- Δk ∈ [-0.1, 0.1] (slope change, where k_∞ = k₀ + Δk)
- τ ∈ [1e-3, 260] (depletion timescale in weeks, prevents pathological long timescales)
- Conditional constraint: When k₀ < 0 (depletion case), Δk ≥ 0 is enforced via penalty (ensures k_∞ ≥ k₀, meaning slope increases over time). When k₀ ≥ 0, Δk can be negative (no depletion constraint)
- Time axis: s = 0 at enrollment_date (weeks since enrollment, not centered)
- Model: log h(s) = C + k_∞·s - Δk·τ·(1 - e^(-s/τ)) where k_∞ = k₀ + Δk
- Normalization: h_norm(s) = h(s) · exp(-kb·s - (ka - kb)·τ·(1 - exp(-s/τ))) where s = t (weeks since enrollment)
- Time-centered linear quantile regression (τ = 0.5, median): Used for cohorts born 1940 or later (age < 80 at enrollment) and all-ages cohort (YearOfBirth = -2)
- Rationale: Younger cohorts have minimal depletion, so a simple exponential (linear in log-space) is sufficient
- Quantile regression: Both methods use median quantile regression (τ = 0.5) rather than least squares, providing robustness to outliers
- Time centering: t_c = t - t_mean where t_mean is the center of the fit window (t_c = 0 at center)
- Model: log h(t_c) = a + b · t_c (linear in log-space, exponential in hazard-space)
- Normalization: h_norm(t) = h(t) · exp(-b · t_c) where t_c = t - t_mean
Both slope8 and linear methods use the same fit window (fit region = adjustment region):
- Fit window start: enrollment_date + skip weeks
- Highest dose: Skip 17 weeks total (DYNAMIC_HVE_SKIP_WEEKS=2 + SLOPE_FIT_DELAY_WEEKS=15)
- Other doses: Skip 2 weeks (DYNAMIC_HVE_SKIP_WEEKS only)
- Fit window end: SLOPE_FIT_END_ISO (default: "2024-16")
- Rationale:
- Skip first 2 weeks to avoid HVE (Healthy Vaccinee Effect) artifacts
- Skip additional 15 weeks for highest dose to avoid fitting early vaccine-related mortality increases
- Same window used for both fitting parameters and applying normalization
- Cohorts born < 1940: Use slope8 (four-parameter depletion fit, s=0 at enrollment)
- Cohorts born ≥ 1940: Use linear fit (time-centered exponential)
- All-ages cohort (YOB=-2): Use linear fit (time-centered exponential)
- Fit region = adjustment region: Same time window for both fitting and normalization
- Skip weeks: 2 weeks for all doses (HVE), plus 15 weeks for highest dose (vaccine mortality)
See documentation/specs/slope8.md for complete mathematical specification of slope8 method.
Four-Step Process:
- Hazard Transform: Convert mortality rates to discrete hazard functions for mathematical exactness. Note that KCOR_CMR.py produces alive values are alive at start of the week and dead is the number of people that died in that week. So our MR=dead/(alive at start of week) is not already a hazard rate — it’s the probability of dying during the week given survival to its start. This is precisely why we need the discrete-time log transform. Had we computed a continuous time alive people time as the denominator, we wouldn't need the transform. But we are using alive at the start of the week. It's a subtle but important distinction.
- Slope normalization: Use dual windows to normalize slopes as described above.
-
Cumulative Hazard: Compute
$\text{H}(t)$ as cumulative sum of hazard functions - Ratio Calculation: Compute KCOR as ratio of cumulative hazards, normalized to the ratio at a baseline point
Step 1: Discrete Hazard Function Transform
Where
📚 Mathematical Reasoning: For a detailed explanation of why KCOR uses discrete hazard functions and the mathematical derivation behind this approach, see Hazard Function Methodology.
Step 2: Cumulative Hazard (CH)
Step 3: KCOR as Hazard Ratio (Baseline at Week 4) By default, KCOR cumulate hazards for 5 weeks (week 0 to week 4) and uses the cumulated hazard ratio at that time to establish a reference hazard ratio where KCOR=1. Increasing this parameter will reduce the CI's (which are largely determine by the number of weeks used to establish the baseline ratio), but it will also result in the method missing vaccine harms (the baseline is done during low to no COVID so it won't miss any benefits). So 5 was a reasonable compromise.
KCOR starts accumulating hazards on the enrollment date to capture a baseline mortality as close to vaccination as possible. The Czech data had no signs of dynamic HVE with KCOR fixed cohort enrollment dates since the enrollment dates are chosen after 80% of the cohort being studied has been vaccinated.
Dynamic HVE is caused by people who are going to die shortly declining to be vaccinated. It looks like two highways merging if you look at a plot of deaths per week.
If examination of the deaths/week data shows signs of dynamic HVE, then you can either shift the enrollment date later, or set DYNAMIC_HVE_SKIP_WEEKS to a value other than 0. Setting DYNAMIC_HVE_SKIP_WEEKS > 3 would be highly unusual since event time-series plots for vaccines rarely (if ever) have dynamic HVE lasting over 3 weeks. In the case of COVID, if anything, HVE would be very small since even people who were dying wanted to see their family and the family would demand vaccination.
KCOR Formula:
Where:
-
$r$ = Calculated slope for the specific dose-age combination -
$\text{MR}(t)$ = Raw mortality rate at time$t$ -
$t_e$ = Enrollment week index 0 -
$t_0$ = Baseline for normalization (week 4;$\text{KCOR}(t_0) = 1$ ) -
$\text{H}(t)$ = Cumulative hazard at time$t$ (sum of discrete hazards) - Mathematical Enhancement: Discrete cumulative-hazard transform provides more exact CH calculation than simple summation
- Interpretation: KCOR = 1 at baseline, showing relative risk evolution over time
95% Confidence Intervals (Nelson–Aalen, post‑anchor):
We compute CIs on the log scale using post‑anchor cumulative‑hazard increments and the Nelson–Aalen variance, adjusted for slope‑normalization. Let
Per‑age cohorts
Using Nelson–Aalen increments with slope normalization factor
where
The 95% CI is
ASMR (pooled across ages)
Let (w_a) be the expected‑deaths weights (sum to 1). Aggregate per‑age log‑variance contributions:
then
The 95% CI is
Notes:
- This replaces the prior baseline‑terms formula. Variance is now computed from post‑anchor increments only, matching the plotting interval.
- Slope normalization is propagated into variance via (s(\tau)^2) per week.
- All bounds are computed on the log scale and exponentiated.
Tip
Here's a quick summary
-
Pick
$t_e$ as the enrollment time, that is when we start tracking mortality rates. Pick 2 or 3 slope anchor dates when deaths are low. -
Adjust the mortality rates of each cohort to neutralize the slope over time. This allows all cohorts, regardless of age or frailty, to be fairly compared.
-
Do a discrete-time hazard transform to transform mortality rates into a hazard function, hazard(t). that we can cumulate.
-
Compute the ratio of the cumulative hazard function at each time
$t$ of the cohorts of interest. Scale by the value at week 4 (config:ANCHOR_WEEKS = 4). So KCOR on week 4 will be 1. The 4 weeks gives us time to match baseline mortality of the cohorts during a period where there is no COVID virus so there should not be a differential response.
- Fix age weights
$w_a$ (sum to 1) from the pooled baseline age distribution (first 4 distinct weeks). - Within each age
$a$ and dose$k$ , compute weekly hazards after slope2:$h_{k,a}(t)$ . - Age-standardize hazards by dose:
- Accumulate to standardized cumulative hazards:
- Convert to standardized risks:
- Form the age-standardized KCOR curve:
- Purpose: Provides an alternative aggregation method that treats all ages as a single cohort
-
Method:
- Aggregate Dead, Alive, and person-time across all YearOfBirth values for each Dose and DateDied
- Compute mortality rates from aggregated counts:
$\text{MR} = \text{Dead} / \text{PT}$ - Compute hazards from aggregated MR:
$h = -\ln(1 - \text{MR})$ - Estimate beta (slope) by averaging beta values from per-age data
- Apply hazard-level normalization:
$h_{\text{adj}} = h_{\text{raw}} \cdot e^{-\beta \cdot t}$ - Compute cumulative hazards and KCOR as for per-age calculations
-
Difference from ASMR:
-
ASMR (YearOfBirth = 0): Uses expected-deaths weights
$w_a \propto h_a \times \text{PT}_a$ to pool across age groups, properly weighting elderly who contribute most to death burden - All Ages (YearOfBirth = -2): Direct aggregation without age grouping or weighting, treating the entire population as a single cohort
-
ASMR (YearOfBirth = 0): Uses expected-deaths weights
- Output: Displayed in console and summary files right after "ASMR (direct)" for easy comparison
KCOR is a defined estimand (a baseline-normalized cumulative-hazard ratio) computed through explicit transformations. With its assumptions stated and diagnostics enforced, it supports a fully rigorous, math-science presentation. The only subjective choices (anchors, smoothing) can be specified as reproducible selection rules with sensitivity analyses—squarely in the standards of methodological papers.
KCOR is not "just a heuristic"; it's a pipeline of well-defined statistical transforms with explicit assumptions. The only "heuristic" bits (like choosing quiet anchor windows or a smoothing span) can be formalized as estimators/selection rules.
KCOR is a baseline-normalized cumulative-hazard ratio computed from discrete-time hazards after cohort-wise slope normalization. The steps and assumptions can be stated precisely; the few subjective choices (e.g., "quiet" anchor windows) can be formalized as selection rules with sensitivity analyses.
Let:
-
$g \in {v,u}$ index two fixed cohorts (numerator$v$ , denominator$u$ ). -
$t$ be calendar-time weeks (with enrollment at$t_e=0$ ). -
$m_{g,t}\in[0,1)$ the observed weekly mortality rate among those at risk at the start of week$t$ .
Baseline model (log-rate decomposition)
where
Note
Slope normalization is required for fair comparisons across cohorts with different baseline frailty mixes; v4.6 uses the slope2 method (fixed quiet windows, hazard-level normalization) to estimate and remove cohort-level trend without altering raw MR.
Slope estimation via quiet anchors
Choose two quiet, non-differential windows
(Under the model, the common
Slope-normalization
Discrete hazard and cumulative hazard
KCOR (baseline-normalized CH ratio at
Note
KCOR is invariant to the log base and any common multiplicative scaling of rates: such constants rescale hazards by a factor that cancels in the ratio and again at the baseline normalization.
-
Exponential baseline within the analysis window:
$\log m_{g,t}$ is approximately linear in$t$ . -
Quiet, non-differential anchors
$B_1,B_2$ : no cohort-specific shocks inside these windows. - Fixed cohorts at enrollment (avoid time-varying composition effects).
- Common-time perturbations mostly affect both cohorts proportionally (reduced by slope-normalization).
-
Cancellation of common drift/level. Slope-normalization removes smooth
$\delta_t$ drift; baseline normalization removes level. Residual bias is bounded by non-parallelism of log-MR lines in anchors. -
Treatment-effect link. If post-adjustment hazards follow
$h_{v,t}=\rho(t) \cdot h_{u,t}$ with constant$\rho$ , then KCOR is constant. Time-variation in$\rho(t)$ is reflected by the KCOR curve. -
Small-rate regime. For small
$m$ ,$h\approx m$ , so$H_g(t)$ approximates the sum of adjusted rates. KCOR then approximates the ratio of those sums (still baseline-normalized).
We now compute CIs from post‑anchor cumulative‑hazard increments using the Nelson–Aalen variance with slope‑normalization propagated via the weekly scaling factor
Per‑age SE on the log scale:
Pooled (ASMR) log‑variance uses expected‑deaths weights
95% CI in both cases:
- Anchor selection rule. Choose (B_1,B_2) (length (w)) to minimize (i) pooled residual variance of log-linear fits and (ii) slope differences between cohorts, subject to no epidemic flags.
- Smoothing span. Select moving-average span (k) by minimizing out-of-anchor AIC or via small cross-validation restricted to quiet weeks.
-
Diagnostics as tests. Require (a) high
$R^2$ for log-linear fits in anchors, (b) a tiny quadratic term in$\log m_{g,t} = \beta_0+\beta_1 t + \beta_2 t^2$ over quiet ranges, (c) stability under anchor shifts ($\pm$ 1–2 weeks).
- Verify parallel-lines behavior (log-MR vs.
$t$ ) within anchors for both cohorts. - Check baseline stability: after normalization, KCOR should be ~1 near
$t_0$ . - Run anchor sensitivity and placebo enrollment (shift
$t_e$ ) analyses. - Include negative controls (random splits → KCOR
$\approx 1$ ) when feasible.
- Mortality rates follow exponential trends during the observation period
- No differential events affect dose groups differently during anchor periods
- Baseline period (week 4) represents "normal" conditions
- Person-time = Alive (survivor function approximation)
- Discrete hazard function transformation provides accurate cumulative hazard estimation
- Hazard ratios are appropriate for comparing mortality risk between groups
There are 10 limitations to be aware of. Many of These are limitations that would apply anytime you are analyzing real-world retrospective data.
Note
The single most important thing to keep in mind is that we are told that the COVID vaccines are perfectly safe and 90% effective. So pretty much all the limitations below don't apply (HVE always applies but it is negligible for the COVID vaccine). If the COVID vaccines are as safe as claimed, KCOR is extremely accurate. You cannot have it both ways here. KCOR forces you to confront the truth. It's either safe and KCOR applies, or it is unsafe and KCOR's results are subject to the limitations below.
In general, these limitations cause KCOR to be a conservative estimator of harm. This means if KCOR finds a harm signal, like it does in the Czech dataset, the actual harm is actually greater than KCOR indicates because KCOR tends to understate harms and overstate benefits as specifically described below.
For exmaple suppose you have a vaccine which instantly increases everyone's ACM by 5% on the day of the shot. KCOR, because it's generally a conservative estimator of harm since it trusts the value in a baseline period shortly after vaccination, would treat that vaccine as perfectly safe. Similarly, if that vaccine linearly and uniformly raised people's mortality over time, KCOR would also think that that vaccine is perfectly safe. Why? Because KCOR infers the mortality of cohort through observation. There is no simple way to distinguish a small uniform over time effect from the mortality of the cohort.
There are a variety of things you can do to limit these sorts of errors (the most effective being establishing "no effect" slope ranges for various cohorts, e.g,. a vaccinated 60 year old should have a slope between x and y). This can make the limitations listed below be very managable.
-
Exponential fit assumption: Cohorts aged 90 and older with significant frailty will not be as accurate as cohorts of younger ages because the core assumption of a single exponential mortality rate starts to become less true. Estimates from these cohorts may be inaccurate by more than 1%. Grok did a compuation for age 90 with a frailty mix of 1-4 and found less than a 1.6% per year error from the exponential assumption. The single best empirical proof of near-linear mortality is the Japan data. If there is going to be a pathological cohort, the unvaccinated elderly in Japan would be exhibit #1. This is because nearly everyone got the shot in Japan so the percentage of unvaccinated is small which is an opportunity for pathological mortality. There is a tool created by Kenji Fujikawa enabling you to plot the deaths per week of the unvaccinated using the Japan data. There is a clear higher rate of deaths in the first 3 months which is exactly what we'd expect to see. So for more extreme cohorts (>80 unvaccinated where over 99% opted for the shot), it can falsely make the vaccine look bad because the baseline death rate will be set incorrectly. Therefore, it's always a good idea to look at the mortality rate slopes of the unvaccinated to validate the assumption because it is the unvaccinated where the assumption is most likely to be violated. For all real-world cohorts we've seen, the log-slope is well approximated by a constant for 2 year windows. It's possible to construct a pathological outlier cohort that violates the assumption, in real world unvaccinated cohorts age 90 and under, I haven't seen it. For example, you can pick a pathological cohort where everyone in the cohort dies within 30 days. But real world vax/unvaxxed cohorts are goverened by the law of large numbers. We can see visual validation of this in both KM plots the Palinkas study where the curvature (instant hazard) of the unvaccinated cohort is constant over time (and pathological because a negative log-slope produces an upward curvature of the KM curve). Confirmation of the assumption is that slope-normalization isn't needed for ages 60 and under. When comparing KCOR numbers for these cohorts, we find the slope normalization KCOR = KCOR_ns (no slope adjustment) which is as expected since we only need to slope normalize for heterogeneous cohorts of ages older than 60 years old when depletion starts to become more significant (for the UNVACCINATED cohort). Also, we did the 8.5%/yr slope adjusted hzards on the 194x FULL population and compared it with the adj hazards of the unvaccinated cohort (using the slope2 method) and the results had a excellent match that is highlighted in the
KCOR_analysisspreadsheet. -
Fixed cohort assumption: KCOR uses fixed cohorts defined at specific enrollment dates. All of those cohorts may change their vaccine status over time and that is not reflected in the analysis. The enrollment dates are generally chosen after 80% to 90% of the people likely to die have been vaccinated to minimize this impact. For a vaccine which reduces risk of death, this has the effect of reducing the magnitude of the harm or benefit because the cohorts will not be as differentiated later in time. So KCOR will understate the harm or understate the benefits. The traditional epi methods of censoring people who transistion (or even worse, reassigning them to the new cohort) would result in changing the mortality rate of the cohorts in unpredictable ways because of HVE. If there was no HVE, censoring those who trnsition to the next dose would be preferred. But HVE means censoring is not a free lunch in vaccination studies, i.e., it comes with a huge risk. It would be a free lunch if there were no mortality implications associated with the decision to switch. But we know there are major implications (a 3x h(t) difference for those of the same age) of the decision to switch, so that's why KCOR doesn't censor. This means the harm/benefit results are conservative. Basically, if we censored, that can materially change the h(t) of the cohort, e.g., you start with an unvaccinated cohort and all the healthiest people leave which drops the h(t) of the remaining cohort by a factor of 3.
-
Non-proportional hazards: KCOR, in its current form, does not yet adjust for non-proportional hazards where the mortality differences in people with the SAME age (e.g., 5 year age band for the Czech data) are not proportional to their baseline mortality. This is particularly important for the COVID vaccine where the mortality increase in response to a virus wave is extremely sensitive to unmeasurable confounders. KCOR will overstate the net benefit during virus periods giving 100% credit to the vaccine when in fact, the protective effect could be 100% due to selection bias causing the unvaccinated to have higher frailty than would be assumed from the DCCI values. For example, the relative mortality increase of two 90 year olds during COVID waves, one vaccinated, the other unvaccinated, is remarkably different. The percentage of that differential mortality increase from COVID credited to the COVID vaccine vs. differential frailty created by the selection bias is the subject of disagreement. Scientists supportive of the COVID vaccine are unwilling to actually debate this topic in a public forum so this remains unresolved. It is an "untouchable" subject because resolving the issue could cause the public to distrust mainstream scientists. There are ways to assess this, e.g., by looking at whole population cumulative deaths during vaccine rollout which was during a COVID wave to look for a "knee" in the curve. If the vaccine really worked, there will be a knee at the time the shots rolled out. If the COVID benefit was all selection bias, there will be no knee.
-
Harm during baseline period: KCOR needs a baseline period when there is no COVID to assess the relative mortality rates of the cohorts under study when there is not an external intervention that is supposed to cause a differential response. But if the vaccine is unsafe and raises mortality in the weeks after the the vaccine is given, and the enrollment date is many weeks or months post vaccine for a cohort, this will cause KCOR to understate the true harm of the vaccine since KCOR missed the period of mortality elevation before the enrollment date. On the other hand, if we choose an enrollment date during COVID such as the 2021_13 date, this can artifically overstate the measured harm if the vaccine was truly effective against COVID because it would depress the mortality rates of the vaccinated during the baseline period.
-
Late enrollment date chosen: If an enrollment date is chosen that is relatively distant from after most people a cohort have been vaccinated and the vaccine significantly increases non-COVID ACM (NCACM) that then plateaus as with the COVID shots, KCOR will miss this for those older cohorts and show a neutral or even a net benefit. It's important to interpret the results in light of this, e.g., for older cohorts, the earlier enrollment dates will be more reliable indicators of risk/benefit. Another example is when looking at the second booster enrollment date, comparing Dose 2 with Dose 0 will give a flat line because KCOR will interpret the higher plateau of the vaccinated as normal (since it only has a very delayed enrollment date, well past the 12 month harm window of the vaccine). This doesn't mean Dose 2 was safe. It just means that the harms relative to Dose from the enrollment date onward are a flat line, which in itself is a nice negative control test. So the most interesting comparison for Dose 4 is against Dose 3 and against Dose 0. Comparing Doses 3 and under with earlier Doses is likely to give a neutral comparison.
-
Dynamic HVE: In general, because KCOR uses a calendar time-series (the x axis is a calendar date) rather than event time-series (where the x axis is time since the injection), dynamic HVE is virtually non-existent because most all the people got vaccinated well before the enrollment date. Dynamic HVE is caused when people avoid getting vaccinated because they are going to die.
Dynamic HVE transfers deaths from the vaccinated cohort to the less vaccinated cohort, e.g., 3 dose to 2 dose. We can show by plotting deaths per week that the Dose 2,1, and 0 cohorts all track each other post booster enrollment. This falsifies claims of dynamic HVE.
Another way to test for this is to run the algorithm with DYNAMIC_HVE_SKIP_WEEKS set to 1 or 2 and see if it materially change the results. If there is an effect, increasing DYNAMIC_HVE_SKIP_WEEKS will make the vaccine look safer because dynamic HVE would set an artifically low baseline for the vaccinated.
The default for DYNAMIC_HVE_SKIP_WEEKS is 0 because dynamic HVE is negligible. For event time-series, HVE is generally insignificant by week 3, so using a value of 2 is a reasonable sensitivity test to assess this effect. However, if the vaccine increases NCACM for a period post-shot like the COVID vaccine does, increasing this value will likely result in artificially lowering the estimated vaccine harm (lowering all the KCOR numbers).
The easiest way to testing for dynamic HVE is to compare vN vs. v0 and vN-1 vs. v0. If they are mirror images, dynamic HVE is a very likely possibility. If the most recently vaccinated curve increases, but the next most vaccinated curve is flat, dynamic HVE would be hard to claim.
-
Harm/recovery window: Suppose you have a vaccine which increases mortality strongly for 6 months, and then in the next 6 months the effect reverses back to baseline. If your slope windows are within the damage/recovery zone, the KCOR values can be impacted in either direction. This is why it's important to choose slope anchor points outside the vaccine harm window range. This may not be know prior to use. So if the final results are non-sensical, e.g., vaccine harm keeps getting larger, this could be because mortality of the vaccinated was declining between the slope windows. So pathological KCOR results are most likely caused by a vaccine which was not safe. KCOR assumes the vaccines are safe.
-
Insufficient data: If there are any weeks with zero deaths in any of the cohorts you are comparing, you gemerally have too little data to use KCOR on that cohort. KCOR loves lots of data. Generally, KCOR will not be reliable on datasets of 1M or less. Datasets of 10M people or more are highly recommended. If a slope correction is large in either direction, it's a sure sign of too little data. This generally happens when the underlying mortality rate cureves are not relatively smooth. The Hamamatsu dataset shows this effect effect in spades, even in the more populated cohorts. Insufficient data can also impact the slope normalization computation. For exmaple, in the Czech data, those born in 1990 or later can exhibit pathological slope values (deviating from the .00157 expected slope value). In these cases, the KCOR_ns (no-slope) values will be more accurate. The slope normalization multiplies the hazard by a factor. But 0 times anything =0 so the slope normalization will be slightly off for windows with 0 deaths.
-
Data quality issues: If data is missing or unreliable, KCOR might give misleading results. For example, the Czech data is missing birthdates for over 1M unvaccinated people. This could affect age comparisons. However, this does not invalidated vaccinated to vaccinated comparisons, e.g., Dose 3 group vs. Dose 2 group because those people had to present while alive so data capture is more reliable. If the computed slope for the unvaccinated cohort differs from the expected slope (.00157 per week which is 8.5% annual mortality rate increase) this can be a sign of data quality issues in which case the slope adjustments can compensate for the missing data if the slope is consistent. We always print the KCOR_ns (no slope adjustment) for comparison of KCOR values. For example, in the Czech data, the KCOR and KCOR_ns values are in nearly perfect agreement in the main Dose 2 v 0 comparison for those born over a 30 year period from 1960-1990 which is quite stunning.
-
Slope window selection: Both slope windows should be chosen to be during periods when there is no differential exposure for the groups. For example, for the COVID, the windows should be when there is no COVID. It's ideally when deaths are minimized from all causes (nothing stressing either cohort to cause a differential response). The deaths/week do NOT have to be the same for the two windows. The two criteria are a quiet period of deaths in both cohorts (relative minima) and that the windows are after the harm/recovery window of the vaccine (as noted in #7 above) This is very easy to verify that the first criteria is done correctly from the looking at the unadjusted h(t) for both cohorts to validate both are local minima and a bit harder to validate 7 (if h(t) is changing direction, that's a red flag). So the limitation is you can't just pick any window dates willy nilly.
-
ASMR limitations: Epidemiology rests on an assumption that simply does not apply for vaccinated / unvaccinated studies. Namely, people with the same age, demographics, and comorbidities do not have the same mortality. So using ASMR for studies is a mistake. KCOR largely neutralizes this effect because it mortality matches, but the mortality matching doesn't apply to non-proportional hazards like COVID. If KCOR were applied to proportional hazard scenarios (e.g., anything but COVID), our ASMR computation would be very defensible. It is less so with NPH existing because each computation per age range is impacted.
It is a fundamental principle of causal inference that causal conclusions cannot be drawn from observational data without making causal assumptions. KCOR does not eliminate the need for such assumptions; rather, it makes them explicit, narrower in scope, and empirically testable.
In conventional epidemiologic methods such as Cox regression or generalized linear models, causal interpretation relies on strong and often implicit assumptions, including proportional hazards and the absence of unmeasured confounding throughout follow-up. By contrast, KCOR leverages fixed cohort enrollment and slope normalization to control for the static healthy vaccinee effect (HVE) that typically confounds vaccine mortality analyses. By selecting cohorts at a single enrollment date, KCOR freezes selection bias at baseline and avoids dynamic HVE effects that arise in rolling-enrollment designs. Slope normalization uses the stable Gompertz mortality structure to neutralize baseline frailty differences between groups, allowing post-enrollment divergence in mortality curves to be interpreted more cleanly.
The key causal identifying assumption is that, after slope normalization, any systematic divergence in mortality between vaccinated and unvaccinated fixed cohorts reflects causal effects of vaccination, rather than residual confounding or selection. This requires assuming (i) no substantial unmeasured time-varying confounders arise after enrollment, and (ii) the baseline mortality slope differences between cohorts are stable over time. These assumptions are transparent and testable: for example, pre-wave mortality behavior can be examined to detect violations as well the mortality behavior in the more fragile unvaccinated group over the entire period.
The Czech record-level dataset is particularly well suited for KCOR, because it includes vaccination and death dates for the entire population, enabling precise fixed-cohort definitions and pre-enrollment slope checks. Under these conditions, KCOR provides a framework in which causal interpretations rest on clearly articulated, limited assumptions, rather than on opaque model specifications.
ChatGPT provided a more detailed analysis on this assumption and causality.
KCOR represents a groundbreaking advancement in epidemiological methodology, offering unique advantages over traditional approaches for comparing mortality between cohorts:
| Aspect | Traditional Methods | KCOR |
|---|---|---|
| Time-Varying Trends | ❌ Assume static baseline rates | ✅ Dynamic slope correction |
| Mathematical Rigor | ❌ Often use approximations | ✅ Discrete hazard functions |
| Baseline Control | ❌ Compare absolute rates | ✅ Normalized to matched baseline |
| Observational Data | ❌ Require randomized trials | ✅ Creates "virtual randomization" |
| Policy Questions | ❌ Limited applicability | ✅ Direct policy evaluation |
🎯 Unique Problem Solving:
- Traditional SMR: Assumes static reference population rates → fails with time-varying trends
- KCOR: Dynamically adjusts for secular changes, seasonal effects, and policy impacts
🔬 Mathematical Excellence:
- Traditional Methods: Use approximations or assume proportional hazards
- KCOR: Uses exact discrete hazard transformation:
hazard(t) = -ln(1 - MR_adj(t))
⚖️ Baseline Matching:
- Traditional Methods: Compare absolute rates between potentially different cohorts
- KCOR: Normalizes to baseline period where cohorts are "matched" from mortality perspective
🌍 Real-World Applicability:
- Traditional Methods: Require controlled conditions or make unrealistic assumptions
- KCOR: Works with observational data to answer policy-relevant questions
KCOR is the only method that can:
- ✅ Create "virtual randomization" from observational data
- ✅ Dynamically adjust for time-varying trends affecting both cohorts
- ✅ Provide mathematically exact hazard-based comparisons
- ✅ Answer policy-relevant questions using real-world data
- ✅ Handle COVID-era complexity with multiple confounding factors
Result: KCOR can objectively answer questions like "Did COVID vaccines kill more people than they saved?" using observational data—something no traditional epidemiological method can achieve.
📊 Standardized Mortality Ratio (SMR)
- ❌ Assumes static reference population rates
- ❌ Doesn't account for time-varying trends
- ❌ Vulnerable to secular changes in mortality
- ❌ Cannot handle COVID-era policy impacts
📈 Age-Period-Cohort (APC) Analysis
- ❌ Complex identifiability issues
- ❌ Requires large datasets
- ❌ Doesn't provide direct cohort comparisons
- ❌ Difficult to interpret for policy questions
⚖️ Proportional Hazards Models
- ❌ Assumes proportional hazards (often violated)
- ❌ Doesn't handle time-varying effects well
- ❌ Requires sophisticated statistical modeling
- ❌ Vulnerable to model misspecification
📋 Life Table Analysis
- ❌ Doesn't account for external time-varying factors
- ❌ Assumes stable mortality patterns
- ❌ Less suitable for policy evaluation
- ❌ Cannot handle rapid changes in mortality
🎯 Competing Risks Analysis
- ❌ Focuses on cause-specific mortality
- ❌ Requires detailed cause-of-death data
- ❌ Doesn't address overall mortality differences
- ❌ Complex interpretation for policy makers
🔬 Scientific Rigor:
- KCOR provides mathematically exact comparisons using discrete hazard functions
- Traditional methods rely on approximations that can introduce bias
- KCOR's approach is more robust to violations of common statistical assumptions
🌍 Real-World Relevance:
- KCOR works with the messy, complex data of real-world policy implementation
- Traditional methods require idealized conditions that rarely exist in practice
- KCOR can handle the rapid changes and multiple confounding factors of the COVID era
📊 Policy Impact:
- KCOR directly answers policy-relevant questions using observational data
- Traditional methods often require randomized trials that are impossible for policy evaluation
- KCOR provides interpretable results that policymakers can understand and act upon
⚡ Practical Implementation:
- KCOR requires only basic demographic and mortality data (birth, death, vaccination dates)
- Traditional methods often require extensive additional data (cause of death, detailed covariates)
- KCOR can be applied to existing datasets without additional data collection
KCOR/
├── README.md # This file
├── code/
│ ├── KCOR.py # Main analysis script (v4.6)
│ ├── KCOR_CMR.py # Data aggregation script (DCCI buckets: -1,0,1,2,3,4,5; 2 and 4 preserved)
│ ├── KCOR_ts.py # Time series analysis script
│ ├── Makefile # Build automation (Windows/Linux/Mac)
│ ├── debug/ # Helper scripts for development/verification
│ └── old/ # Archived scripts
├── data/ # Outputs organized by country (e.g., Czech)
│ └── [country]/ # Country-specific outputs (KCOR.xlsx, KCOR_summary.xlsx, KCOR_CMR.xlsx)
├── analysis/ # Analysis artifacts and plots
│ └── [country]/ # e.g., analysis/Czech/KCOR_analysis.xlsx, KCOR_ASMR_dose2.png
├── documentation/ # Detailed methodology documentation
│ └── hazard_function.md # Mathematical reasoning for hazard functions
├── example/ # Spreadsheet example computing KCOR (slope norm + CIs)
│ └── KCOR_sample_computation_194x.xlsx # End-to-end KCOR in Excel
├── validation/ # Independent validation suites
│ ├── DS-CMRR/ # Discrete Survival CMRR method
│ ├── GLM/ # Generalized Linear Models validation
│ └── kaplan_meier/ # Kaplan–Meier survival analysis
├── test/ # Tests orchestrated by root Makefile
│ ├── negative_control/ # Synthetic no-signal tests
│ └── sensitivity/ # Parameter sweep sensitivity tests
├── reference_results/ # Frozen reference outputs for comparison
│ ├── KCOR/ # Reference KCOR outputs
│ ├── GLM/ # Reference GLM plots
│ ├── DS-CMRR/ # Reference DS-CMRR plots
│ └── negative_control_tests/ # Reference negative-control outputs
└── peer_review/ # Peer review materials
- Root
Makefileorchestrates common tasks:make→ runs variable-cohort aggregation, analysis, validation, and testsmake run→ main KCOR pipeline (delegates tocode/Makefile KCOR)make ts→ time series analysis (delegates tocode/Makefile ts)make validation→ DS-CMRR + KM + GLM validation (delegates tovalidation/DS-CMRR/,validation/kaplan_meier/, andvalidation/GLM/)make test→ runs both negative-control and sensitivity tests (delegates totest/Makefile)
- Important: Always run these targets from the repository root so environment and output paths are consistent.
- Subdirectory Makefiles (
code/,validation/DS-CMRR/,validation/kaplan_meier/) are for advanced use only; invoking them directly may bypass root defaults and write outputs to different locations.
Builds synthetic no-signal cohorts to ensure no false positives.
- Run:
make test - Outputs:
test/negative_control/out/(e.g.,KCOR_processed_neg_control.xlsx,KCOR_summary.xlsx) - References:
reference_results/negative_control_tests/
The analysis directory has human analysis of the data that shows that KCOR picks out real signals in the data that most people would have thought was perfect negative control data.
For the negative control tests, KCOR is called with baseline minimum set to 0 so that the KCOR baseline is not adjusted since we aren't dealing with a known net harmful vaccine.
Verifies that reasonable parameter choices do not change KCOR's conclusions by sweeping user-specified parameters.
How to run from repo root:
make sensitivityDefaults (see test/sensitivity/Makefile):
SA_COHORTS=2021_24SA_DOSE_PAIRS=1,0;2,0SA_SLOPE_START=53,53,1SA_SLOPE_LENGTH=61,61,1SA_YOB=0(ASMR only)
Key parameters:
SA_COHORTS: comma-separated sheet names (e.g.,2021_24,2022_06)SA_DOSE_PAIRS: semicolon-separated dose pairs (e.g.,1,0;2,0)SA_SLOPE_START:start,end,stepfor offset1 (e.g.,52,60,2)SA_SLOPE_LENGTH:start,end,stepfor Δt (e.g.,48,70,2)SA_YOB:0(ASMR) |start,end,step| explicitlist
Output:
test/sensitivity/out/KCOR_SA.xlsx(sheetsensitivity)test/sensitivity/out/KCOR_summary_SA.log
- Python 3.8 or higher
- pandas
- numpy
- openpyxl (for Excel output)
# Clone the repository
git clone https://github.com/skirsch/KCOR
cd KCOR
# Install dependencies (creates virtual environment and installs from requirements.txt)
make install
# Run the main KCOR analysis
make KCORNote: The make install command creates a Python virtual environment (.venv) and installs all required dependencies. The make KCOR command runs the main analysis pipeline on the default dataset (Czech). Czech data is included under data/Czech/.
To run the main KCOR analysis:
# Step 1: Install dependencies (creates virtual environment)
make install
# Step 2: Run the main KCOR analysis
make KCORThis will:
- Create a Python virtual environment (
.venv) if it doesn't exist - Install all dependencies from
requirements.txt - Run the KCOR analysis pipeline on the default dataset (Czech)
# Additional analysis options
make # runs analysis + validation + tests
make KCOR_variable # variable-cohort aggregation
make ts # time series analysis (KCOR_ts)
make validation # DS-CMRR + KM validation
make test # negative-control and sensitivity tests (see test/)
# Dataset targeting (default DATASET=Czech)
make KCOR DATASET=Czech
make KCOR DATASET=japan
make sensitivity DATASET=CzechNotes:
make KCORdelegates tocode/Makefile KCORand uses the virtual environment automatically.make validationdelegates tovalidation/DS-CMRR/Makefile run.- Subdirectory Makefiles remain runnable directly; use
make -C <dir> <target>.
cd code
# Step 1: Data aggregation
python KCOR_CMR.py [input_file] [output_file]
# DCCI handling: KCOR_CMR preserves buckets -1,0,1,2,3,4,5 (2 and 4 are not collapsed into 3).
# Step 2: KCOR analysis
python KCOR.py [aggregated_file] [analysis_output] [mode] [log_filename]
# Notes:
# - mode (e.g., "Primary Analysis" | "Sensitivity Analysis") is required
# - log_filename is optional (defaults to "KCOR_summary.log")
# Output appears both on console and in the specified log fileKCOR_CMR.py supports Monte Carlo bootstrap sampling to generate confidence intervals and validate results. This mode performs multiple iterations with bootstrap resampling to assess statistical variability.
Usage:
cd code
# Using Make (recommended)
make monte_carlo DATASET=Czech MC_ITERATIONS=25
# Or directly with Python
MONTE_CARLO=1 MC_ITERATIONS=25 MC_THREADS=5 python3 KCOR_CMR.py [input_file] [output_file]Configuration:
MONTE_CARLO=1- Enables Monte Carlo modeMC_ITERATIONS- Number of bootstrap iterations (default: 25)MC_THREADS- Number of parallel processes (default: 5, reduced from 20 to avoid memory exhaustion)
Important Notes:
- Iteration #1 uses the full dataset without sampling - This serves as the reference/validation iteration representing the true population mean. All other iterations (2-N) use bootstrap sampling with replacement.
- The output Excel file contains one sheet per iteration (sheet names: "1", "2", "3", ..., "N")
- Iteration #1 can be compared with iterations 2-N to verify that bootstrap samples are centered around the mean
- Memory usage scales with the number of parallel processes - if you encounter memory issues, reduce
MC_THREADS(try 3 or even 2 for very large datasets) - Monte Carlo mode only processes the 2022-06 enrollment date (other enrollment dates are skipped)
Output:
The Monte Carlo output file (KCOR_CMR_MC.xlsx) contains multiple sheets:
- Sheet "1": Full dataset (no sampling) - the reference iteration
- Sheets "2" through "N": Bootstrap samples with replacement
The Czech data files needed for running examples and validation are already included in this repository under data/Czech/. No additional downloads are required to run the default pipeline and validations.
The script expects Excel workbooks with the following schema per sheet:
| Column | Description | Example |
|---|---|---|
ISOweekDied |
ISO week number of death | 24 |
DateDied |
Date of death | 2021-06-14 |
YearOfBirth |
Birth year | 1940 |
Sex |
Gender (M/F) | M |
Dose |
Vaccination dose | 0, 1, 2, 3 |
Alive |
Person-time (survivors) | 1500 |
Dead |
Death count | 25 |
This is the most common source of “we got different numbers”. KCOR assumes start-of-week denominators and a single, explicit week-boundary convention.
-
ISO week boundary: Each row/week is keyed to an ISO week (W).
DateDiedis the Monday starting that ISO week (computed asYYYY-WW-1). -
Enrollment date/week: Each CMR sheet corresponds to an enrollment ISO week (W_e) (e.g.,
2021_24). DefineenrollmentWeekStart = Monday(W_e). -
Alive at enrollment: The enrollment population includes everyone alive at the start of the enrollment week:
- Alive-at-start means
DateOfDeathis missing orDateOfDeath >= enrollmentWeekStart. - Therefore, someone who dies during the enrollment week is included in
Alive(W_e)and also contributes toDead(W_e)(discrete-time risk-set semantics).
- Alive-at-start means
-
Dose group at enrollment (fixed cohorts): Dose status is frozen at enrollment using no same-week promotion:
- A dose counts toward enrollment status only if its date is strictly before
enrollmentWeekStart. - A vaccination recorded in week (W) affects status starting week (W+1), not week (W).
- A dose counts toward enrollment status only if its date is strictly before
-
Weekly deaths:
Dead(W)is the number of cohort members whose death is recorded in ISO week (W) (i.e., who die during that week). -
Weekly Alive recursion:
Alive(W)is the number alive at the start of week (W). For fixed cohorts (post-enrollment), the update is:
-
Post-enrollment cohort definition: After enrollment, cohorts are fixed (intent-to-treat style). Post-enrollment vaccinations do not change cohort membership; only deaths reduce
Alive. -
Analysis start in KCOR:
code/KCOR.pyfilters each enrollment sheet toDateDied >= enrollmentWeekStart, so only post-enrollment weeks contribute to KCOR.
Reproducibility. Reproduce all figures and tables with: make paper.
If your reproduction differs, check these toggles first:
- ISO-week to Monday mapping (
YYYY-WW-1) matches - dose timing uses
DoseDate < weekStart(not<=) for start-of-week status - alive-at-start includes those who die during the week (
DateOfDeath >= weekStart) - cohorts are frozen after enrollment (no post-enrollment switching)
The analysis produces Excel workbooks with comprehensive methodology transparency:
KCOR_analysis.xlsx - Complete analysis with all enrollment periods combined
This file enables users to visualize results for any cohort combination and contains:
KCOR_summary.xlsx - Console-style summary by enrollment date
This file provides one sheet per enrollment period (e.g., 2021_24, 2022_06) formatted like the console output, with dose combination headers and final KCOR values for each age group.
dose_pairs: KCOR values for all dose comparisons with complete methodology transparency- Columns: Sheet, ISOweekDied, Date, YearOfBirth, Dose_num, Dose_den, KCOR, CI_lower, CI_upper, MR_num, MR_adj_num, CH_num, CH_actual_num, hazard_num, slope_num, scale_factor_num, MR_smooth_num, t_num, MR_den, MR_adj_den, CH_den, CH_actual_den, hazard_den, slope_den, scale_factor_den, MR_smooth_den, t_den, KCOR_ns (KCOR w/o slope normalization step)
-
by_dose: Individual dose curves with complete methodology transparency -
Columns: Date, YearOfBirth, Dose, ISOweek, Dead, Alive, MR, MR_adj, Cum_MR, Cum_MR_Actual, Hazard, Slope, Scale_Factor, Cumu_Adj_Deaths, Cumu_Unadj_Deaths, Cumu_Person_Time, Smoothed_Raw_MR, Smoothed_Adjusted_MR, Time_Index
-
dose_pair_deaths: Per-pair weekly and cumulative death details supporting KCOR_ns -
Columns: EnrollmentDate, ISOweekDied, Date, YearOfBirth, Dose_num, Dose_den, Dead_num, Dead_adj_num, cumD_num, Dead_den, Dead_adj_den, cumD_den, K_raw_o, KCOR_ns
- Metadata: Version information, methodology overview, and analysis parameters
- Documentation: Complete explanation of the KCOR methodology and output columns
KCOR.xlsx - Complete analysis file:
- Filter by Cohort: Use Excel filters to examine specific dose combinations (e.g., 3 vs 0)
- Filter by Age: Focus on specific birth years or age groups
- Time Series Analysis: Plot KCOR values over time for any cohort combination
- Confidence Intervals: Visualize uncertainty bounds alongside point estimates
- Methodology Validation: Examine all intermediate calculations for transparency
KCOR_summary.xlsx - Console-style summary format:
- One Sheet Per Enrollment: Easy comparison across different enrollment periods (2021_24, 2022_06, etc.)
- Console Format: Structured like the console output with dose combination headers
- Final Values: Shows the latest KCOR values and confidence intervals for each age group
- Easy Reading: Clean format with dose combination headers and age group results
- Cross-Period Analysis: Compare final KCOR values across different enrollment cohorts
# Core methodology
ANCHOR_WEEKS = 4 # Baseline week for KCOR normalization (Note that week # 0 is the first week)
MA_TOTAL_LENGTH = 8 # Moving average length (8 weeks)
CENTERED = True # Use centered moving average
DYNAMIC_HVE_SKIP_WEEKS = 0 # Start accumulating hazards/statistics at this week index (0 = from enrollment)
# Age bucketing
AGE_RANGE = 10 # YearOfBirth bucket size for aggregation (5 or 10). Default: 10
# Analysis scope
YEAR_RANGE = (1920, 2000) # Birth year range to process. Deaths outside the extremes are NOT combined.
# the following dates correspond to 3/29/21, 6/15/21, 2/7/22, 11/21/22
ENROLLMENT_DATES = ["2021_13", "2021_24", "2022_06", "2022_47"] # ISO Year-week Enrollment dates (sheet names to process
# Dynamic slope anchors (quiet-period calendar picks)
QUIET_ANCHOR_ISO_WEEKS = ["2022-25", "2023-28", "2024-15"]
MIN_ANCHOR_GAP_WEEKS = 26 # min weeks after enrollment for first anchor
MIN_ANCHOR_SEPARATION_WEEKS = 39 # min weeks between first and second anchorscovidCorrection:
startDate: "2021-41"
endDate: "2021-52"
factor: 1.4KCOR v7 keeps the KCOR v6 application machinery (invert_gamma_frailty) unchanged and only
changes how enrollment-anchored theta0 is estimated. KCOR v7 uses all configured quiet windows
(root-level theta_estimation_windows triples); v7.2 fits a Gompertz + frailty-depletion hazard
model instead of the earlier flat-k hazard fit.
The current v6 implementation is preserved in code/KCORv6.py for reproducibility.
# Existing v6 fallback window (still supported if no theta_estimation_windows)
quietWindow:
startDate: "2023-01"
endDate: "2023-52"
# v7 preferred windows for theta0 fit (ISO start, ISO end, optional label)
theta_estimation_windows:
- ['2023-19', '2023-40', '2023 post COVID']
- ['2022-22', '2022-25', 'post booster']
- ['2021-26', '2021-36', 'post primary']
# v7.2 Gompertz theta fit (optional; defaults match if omitted)
time_varying_theta:
gompertz_gamma: 0.085 # per calendar year → gamma_per_week = gamma/52 in the fitter
k_anchor_weeks: 4 # mean hazard over first k weeks after HVE skip pins kImplementation notes (v7.2):
- Time axis in the fitter:
t_rebased = t_enrollment − DYNAMIC_HVE_SKIP_WEEKSsoH_gompertz(0)=0at the first post–HVE-skip week; pipeline columntis unchanged elsewhere. - Model:
h = k·exp(γ·t_rebased) / (1 + θ₀·H_gom)withH_gom = (k/γ)·(exp(γ·t_rebased)−1); γ isgompertz_gamma/52per week; k is not fitted (mean ofhazard_effover anchor weeks). θ₀ is the only free parameter (nonlinear least squares on quiet ∪ anchor points witht_rebased ≥ 0). - K-anchor weeks contribute to the θ fit (not held out).
- If no ISO window overlaps follow-up, fit may be anchor-only (
[KCOR7_THETA_ANCHOR_ONLY]in log). - Bounds:
θ₀ ≥ 0;kfrom data; same fitting idea per cohort as before.
V7.1 (guards, still in effect):
- Minimum-quiet-deaths guard (
min_quiet_deaths, default30). - Degenerate-fit guard:
theta0_hat > theta0_max→ defaultset_zeroand log. - v7.2 addition: when that degenerate guard fires and
gamma_per_week / k_hat > theta0_max / 52(consistent units: weekly hazard fromhazard_from_mrvs weekly γ), log[KCOR7_GOMPERTZ_UNIDENTIFIABLE]instead of the generic degenerate line — young/low-kcohorts where Gompertz aging dominates identifiable frailty curvature.
Optional YAML (degenerate / identifiability):
time_varying_theta:
gompertz_gamma: 0.085
k_anchor_weeks: 4
min_quiet_deaths: 30
degenerate_theta_max: 100 # alias for degenerate_fit.theta0_max
degenerate_fit:
theta0_max: 100
action: set_zero # set_zero | warn_onlySummary output: KCOR_summary.xlsx sheet gamma_frailty_fit includes theta_fit_status (e.g. ok, anchor_only, insufficient_data) and relRMSE_hazard_fit for the hazard-space fit.
The script automatically determines dose pairs based on sheet names:
- 2021-13: Doses 0, 1, 2 → Comparisons: (1,0), (2,0), (2,1)
- 2021_24: Doses 0, 1, 2 → Comparisons: (1,0), (2,0), (2,1)
- 2022_06: Doses 0, 1, 2, 3 → Comparisons: (1,0), (2,0), (2,1), (3,2), (3,0)
- 2022_47: Doses 0, 1, 2, 3, 4+ → Comparisons: (4,3), (4,2), (4,1), (4,0)
- KCOR = 1.0: No difference in mortality risk between groups
- KCOR > 1.0: Higher mortality risk in numerator group (e.g., vaccinated)
- KCOR < 1.0: Lower mortality risk in numerator group
- Confidence Intervals: Provide statistical uncertainty around the point estimate
Dose combination: 2 vs 0 [2021_24]
--------------------------------------------------
YoB | KCOR [95% CI]
--------------------------------------------------
ASMR (direct) | 1.2579 [1.232, 1.285]
All Ages | 1.2583 [1.233, 1.284]
1940 | 1.2554 [1.194, 1.320]
1955 | 1.5021 [1.375, 1.640]
Dose combination: 3 vs 2 [2022_06]
--------------------------------------------------
YoB | KCOR [95% CI]
--------------------------------------------------
ASMR (direct) | 1.4941 [1.464, 1.525]
All Ages | 1.4938 [1.464, 1.524]
1940 | 1.6489 [1.570, 1.731]
1955 | 1.4619 [1.350, 1.583]
This shows that for dose 2 vs. dose 0 (2021_24 cohort):
- ASMR (direct): 25.8% higher mortality risk (95% CI: 23.2% to 28.5%) - pooled across ages using expected-deaths weights
- All Ages: 25.8% higher risk (95% CI: 23.3% to 28.4%) - direct aggregation of all ages as a single cohort
- Age 1940: 25.5% higher risk (95% CI: 19.4% to 32.0%)
- Age 1955: 50.2% higher risk (95% CI: 37.5% to 64.0%)
And for dose 3 vs. dose 2 (2022_06 cohort):
- ASMR: 49.4% higher mortality risk (95% CI: 46.4% to 52.5%)
- Age 1940: 64.9% higher risk (95% CI: 57.0% to 73.1%)
- Age 1955: 46.2% higher risk (95% CI: 35.0% to 58.3%)
- Full Traceability: Every step of the calculation is visible in output
- Mathematical Relationships: All intermediate values (slope, scale_factor, hazard) included
- Validation Ready: Users can verify every mathematical relationship
- Debug Friendly: Easy to spot-check individual values and calculations
See Hazard Function Methodology for detailed derivation but basically the concept is you can cumulate deaths, but not hazard probabilities. Using the log transform eanbles you to cumulative mortality rate hazard via simple addition, the same way you'd cumulate deaths. Because mortality rate is slight more stable than deaths, using the discrete hazard function transform on mortality rates gives you a more accurate result.
- Mathematical Enhancement: More exact cumulative hazard (CH) calculation than simple summation of mortality rates (which is mathematically incorrect)
- Hazard Function:
hazard(t) = -ln(1 - MR_adj(t))with proper clipping to avoid log(0) - Cumulative Process:
CH(t) = sum(hazard(i))for i=0 to t (cumulative hazard) - Numerical Stability: Handles edge cases with proper bounds and clipping
- Hazard Ratio: KCOR computed as ratio of cumulative hazards, normalized to baseline
- File Access Protection: Automatic retry when Excel files are open
- Clean Console Output: Professional column headings and formatting
- Version Documentation: Complete change history in code
- Cross-Platform: Windows-compatible Makefile and scripts
- Robust Anchoring: Use two long anchor window
- Arithmetic Mean: Appropriate for hazards which are added
- Consistent Comparison: Same anchor points across all dose groups
- Proper Propagation: Accounts for uncertainty in both baseline and current estimates
- Asymmetric Bounds: Reflects the non-symmetric nature of ratio estimates
- Binomial Variance: Appropriate for count data
- File Access Errors: If Excel files are open, the script will prompt you to close them and retry
- Missing Data: Ensure all required columns are present in input files
- Date Formats: Verify dates are in proper datetime format
- Memory Issues: Large datasets may require processing in smaller chunks
- Slope Calculation: Check that anchor points fall within available data range
- Makefile Dependencies: Ensure input files exist before running
make KCOR
Enable detailed debugging by setting:
DEBUG_VERBOSE = True
ENROLLMENT_DATES = ["sheet_name"] # Limit to specific enrollment dates
YEAR_RANGE = (1940, 1945) # Limit to specific age rangeWe welcome contributions to improve the KCOR methodology and implementation. Please:
- Fork the repository
- Create a feature branch
- Make your changes with appropriate tests
- Submit a pull request with detailed description
If you use KCOR in your research, please cite:
KCOR v4.1 - Kirsch Cumulative Outcomes Ratio Analysis
[Your paper title]
[Authors]
[Journal/Conference]
[Year]
That is, if I'm lucky enough to get this published. It's ground breaking, but people seem uninterested in methods that expose the truth about the COVID vaccines for some reason.
Released 2026-03-23.
- Replaced the v7.2 single-pass Gompertz theta fit with a delta-iteration estimator that handles depletion jumps between quiet windows.
- First-stage seed now uses bounded joint
(k, theta)fit on the first quiet window only, wherek_anchor = h_nph(skip_week)andkbounds are controlled bytime_varying_theta.k_anchor_tolerance(e.g.,0.20 -> [0.8, 1.2] * k_anchor). - During iteration,
kis fixed; onlythetaand per-gapdelta_iare updated. Wave gaps are inferred fromtheta_estimation_windowsand evaluated with explicit gap-end indexing. H_gomin the estimator is built as a discrete running sum (not analytic closed form) to align with discrete hazard reconstruction.- Added diagnostics/logging for bounded-
kedge hits (k_hit_bound), weak identifiability, and negative-delta clamping/persistence warnings. - Added estimator controls under
time_varying_theta:k_anchor_tolerance,convergence_tol,max_iterations.
Released 2026-03-21.
- Loading
theta_estimation_windowsfrom the dataset YAML now aborts (sys.exit(1)) if any triple has end ISO week before start (with a clear stderr message and path to the YAML). Previously such rows were silently dropped, which could hide typos.
Released 2026-03-20.
- Gompertz + frailty-depletion fit replaces the prior v7 flat-
khazard fith = k/(1+θ₀H)on quiet points.invert_gamma_frailtyis unchanged; only how θ₀ is estimated changes. kis fixed from the mean ofhazard_effover the firstk_anchor_weeksafterDYNAMIC_HVE_SKIP_WEEKS(implemented viat_rebasedso the Gompertz clock aligns with post–HVE-skip hazard).- γ defaults to 0.085/year from dataset YAML (
time_varying_theta.gompertz_gamma); the fit uses γ per week = γ/52. - Least-squares sample:
(quiet_mask | anchor_mask)witht_rebased ≥ 0; anchor weeks are included in the θ fit. - Logs:
[KCOR7_THETA_ANCHOR_ONLY]when the fit uses anchor points only;[KCOR7_GOMPERTZ_UNIDENTIFIABLE]when the degenerate guard fires andgamma_per_week/k_hat > theta0_max/52(dimensionally consistent screen; equivalent to the old annual-γ over weekly-kratio check againsttheta0_max). - Spreadsheet:
gamma_frailty_fitaddstheta_fit_statusandrelRMSE_hazard_fit.
See documentation/specs/KCORv7/KCOR_v7_gompertz_instructions.md for the full spec (with repo-specific implementation notes at the top).
- Monte Carlo Bootstrap Sampling Support: Added Monte Carlo mode for bootstrap sampling analysis
- MC Processing: Process Monte Carlo iterations (one sheet per iteration) from
KCOR_CMR_MC.xlsx - MC Summary Statistics: Automatically computes and reports summary statistics at end of 2022 for all dose pairs
- Makefile Integration:
make monte_carlonow builds both CMR_MC and KCOR_MC outputs in sequence
- Input:
KCOR_CMR_MC.xlsxfile with one sheet per iteration (numbered "1", "2", "3", etc.) - Enrollment Date: All MC iterations use enrollment date "2022-06" (2022-W06)
- Dose Processing: Processes doses 0-3 (max_dose=3) with dose pairs: (1,0), (2,0), (2,1), (3,2), (3,1), (3,0)
- Output:
KCOR_MC.xlsxwith one sheet per iteration, mirroring input structure - Summary: End-of-2022 summary statistics (mean, median, percentiles, min/max, std dev) for each dose pair
- Usage: Run
make monte_carloor setMONTE_CARLO=1environment variable when callingKCOR.py
- Slope8 Now Default: Slope8 quantile regression method is now the default normalization method (replaces slope7)
- Non-linear Fit: Uses non-linear quantile regression to fit all points from enrollment until end of data
- Highest Dose Delay: For the latest/highest dose, fitting starts after a specified delay (SLOPE_FIT_DELAY_WEEKS, default 15 weeks) to avoid fitting vaccine mortality increases
- Robust Normalization: Provides robust handling of depletion-driven curvature with better outlier resistance than least squares methods
- Automatic Fallback: Falls back to linear mode if slope8 fit fails or insufficient data points are available
- Primary Method: Slope8 is now the primary normalization method used for all cohorts
- Fit Window:
- Standard doses: Fits all data from enrollment to end of data
- Highest dose: Fits data starting from SLOPE_FIT_DELAY_WEEKS (default 15 weeks) after enrollment to avoid early vaccine mortality effects
- Normalization Application: Normalization is applied from enrollment (s=0) onwards for all cohorts, regardless of fit window
- Fallback Behavior: Automatically falls back to linear mode if slope8 cannot be fitted (insufficient data, fit failure, etc.)
- Slope8 Quantile Regression Method: Added new diagnostic tool using quantile regression with check loss
- Robustness to Outliers: Quantile loss provides robustness compared to L2 loss used in least squares methods
- Finite Bounds: Uses finite parameter bounds to prevent pathological fits (e.g., prevents tau ≈ 32330 weeks degeneracy)
- Special Case for Highest Dose: Implements delayed fit window for most recent dose while maintaining full deployment range normalization
- Optimization: Uses
scipy.optimize.minimizewith L-BFGS-B method and finite bounds - Quantile Loss: Implements check loss function ρ_τ(u) = τ·u if u ≥ 0, (τ-1)·u if u < 0 (default τ = 0.5 for median)
- Parameter Bounds:
- C ∈ [-25, 0] (intercept, log-hazard scale)
- k₀ ∈ [-0.1, 0.1] (initial slope)
- Δk ∈ [0, 0.1] (slope change, ensures k_∞ ≥ k_0)
- τ ∈ [1e-3, 260] (depletion timescale in weeks, prevents pathological long timescales)
- Deployment Window: Fits depletion curve over full range from enrollment to SLOPE_FIT_END_ISO
- Time Axis: s = 0 at enrollment_date (weeks since enrollment, no centering)
- Model: Same depletion model as slope7: log h(s) = C + k_∞·s - Δk·τ·(1 - e^(-s/τ)) where k_∞ = k₀ + Δk
- Highest Dose Special Case:
- Fit window starts at s = SLOPE_FIT_DELAY_WEEKS (default 15 weeks) to account for delayed deployment
- Only data from s ≥ SLOPE_FIT_DELAY_WEEKS is used for parameter fitting
- Normalization formula applies from s = 0 (enrollment) onwards for all cohorts, including highest dose
- This ensures all cohorts are adjusted from enrollment, but highest dose uses a shorter fit window
- Status (v5.2): Initially implemented as diagnostic tool; results logged to debug CSV but not yet applied for normalization
- Status (v5.3): Now the default normalization method (see Version 5.3 section below)
- Comparison (v5.2): Provided fourth diagnostic method alongside linear, slope7 (TRF), and slope7 (LM) for method comparison
- See
documentation/specs/slope8.mdfor complete mathematical specification
- Slope7 Depletion-Mode Normalization: Replaced quadratic mode with Slope7 depletion-mode normalization for b < 0 cohorts
- Nonlinear Least Squares: Uses Levenberg-Marquardt nonlinear least squares to fit exponential relaxation depletion curve
- Deployment Window: Fit window = deployment window (enrollment to slope7_end_ISO)
- Time Axis: s = weeks since enrollment (no centering)
- Parameters: C, ka (k_0), kb (k_∞), tau (τ)
- Robust Handling: Provides robust handling of depletion-driven curvature while preserving frailty model constraints
- Slope6 Method: Replaced Slope5 with Slope6 time-centered linear/quadratic quantile regression normalization
- Time-Centered Approach: Normalization uses time centering where ( t_c = t - t_{\text{mean}} ) and ( t_c = 0 ) at the centerpoint
- Dual Window System:
- Fit window: 2022-01 to 2024-12 (for regression fitting)
- Application window: enrollment_date to 2024-16 (for determining centerpoint)
- Linear/Quadratic Decision: Automatically chooses linear mode if ( b_{\text{lin}} \geq 0 ), quadratic mode with ( c \geq 0 ) if ( b_{\text{lin}} < 0 )
- Robust Handling: Quadratic mode handles depletion-driven curvature while preserving frailty model constraints (( c \geq 0 ))
- Mathematical Precision: Per
kcor_slope6_spec.mdandkcor_slope6_helpers.mdspecification
- Fit Window: Fixed at 2022-01 to 2024-12 (approximately January 2022 through March 2024) for regression fitting
- Application Window: enrollment_date to 2024-16 (ISO week 16 of 2024) for determining centerpoint
- Time Centering: ( t_{\text{mean}} = \text{mean}(t) ) over application window, then ( t_c = t - t_{\text{mean}} )
- Linear Mode (when ( b_{\text{lin}} \geq 0 )):
- Fit: ( \log h_c(t_c) \approx a_{\text{lin}} + b_{\text{lin}} \cdot t_c ) using median quantile regression
- Normalization: ( \tilde{h}c(t) = h_c(t) \cdot e^{-b{\text{lin}} \cdot t_c} )
- Quadratic Mode (when ( b_{\text{lin}} < 0 )):
- Fit: ( \log h_c(t_c) \approx a + b \cdot t_c + c \cdot t_c^2 ) with constraint ( c \geq 0 )
- Normalization: ( \tilde{h}_c(t) = h_c(t) \cdot e^{-(b \cdot t_c + c \cdot t_c^2)} )
- Benefits:
- Time-centered approach ensures ( t_c = 0 ) at centerpoint of application window
- Handles negative-slope cohorts (depletion-driven curvature) with quadratic mode
- Preserves frailty model constraints (( c \geq 0 )) in quadratic mode
- All cohorts (including dose 0) normalized independently
- See
documentation/specs/kcor_slope6_spec.mdanddocumentation/specs/kcor_slope6_helpers.mdfor complete specification
- Slope5 Method: Replaced Slope4 with Slope5 independent flat-slope normalization (zero-drift method)
- Fixed Baseline Window: Single global baseline window fixed at 2022-01 to 2024-12 (week 1 of 2022 through week 12 of 2024)
- Independent Normalization: Each cohort normalized independently to achieve zero log-hazard slope over baseline window
- Mathematical Precision: Fits ( \log h_c(t) \approx \alpha_c + \beta_c t ) on baseline window, removes drift slope ( \beta_c )
- Reproducible: Mathematically precise method per
KCOR_Slope_Normalization_ONLY.mdspecification - Simplified: Fixed window ensures consistency and reproducibility across all analyses
- Baseline Window: Fixed at 2022-01 to 2024-12 (approximately January 2022 through March 2024)
- Normalization Formula: ( \tilde{h}_c(t) = e^{-\beta_c \cdot t} \cdot h_c(t) ) where ( t ) is time since enrollment
- Quantile Regression Fit: Fits ( \log h_c(t) \approx \alpha_c + \beta_c t ) on baseline window data for each cohort independently
- Uses quantile level τ = 0.25 (25th percentile) to estimate baseline slope (lower envelope)
- Reduces sensitivity to peaks/waves compared to OLS (mean-based) regression
- Slope Application: Slope ( \beta_c ) is fitted on baseline window, then applied starting from enrollment (t=0)
- Benefits:
- Mathematically precise and reproducible
- Single global fixed window ensures comparability across all cohorts
- Independent normalization removes each cohort's own drift without forcing matching to other cohorts
- Zero adjustment at enrollment ensures natural starting point
- All cohorts (including dose 0) normalized independently to flat slope
- See
documentation/specs/KCOR_Slope_Normalization_ONLY.mdfor complete specification
- Slope4 Method: Replaced Slope3 with Slope4 normalization method
- Geometric Mean: Changed from averaging lowest N values to using geometric mean of all values in each window
- Mathematical Soundness: Geometric mean provides better representation of central tendency for hazard values
- Multiplicative Nature: More appropriate for hazard rates which have multiplicative properties
- Simplified: Removed SLOPE3_MIN_VALUES parameter (no longer needed)
- Change from Slope3: Instead of taking the lowest 5 values and averaging them, Slope4 uses the geometric mean of all positive values in the window
- Geometric Mean Formula: ( \text{GM} = \exp(\text{mean}(\ln(\text{values}))) ) for positive values
- Benefits:
- More mathematically appropriate for hazard rates
- Naturally handles multiplicative relationships
- Provides better central tendency estimate for skewed distributions
- Simpler implementation without parameter tuning
- Slope3 Method: Implemented improved slope estimation using the average of the lowest N values (default: 5) in each window instead of averaging all values
- Robustness: More resistant to outliers and noise in hazard data
- Configurable: SLOPE3_MIN_VALUES parameter (default: 5) allows tuning the number of lowest values to average
- Backward Compatible: Falls back to mean of all values if insufficient positive values exist
- All Ages Calculation: Added new "All Ages" calculation (YearOfBirth = -2) that aggregates all ages into a single cohort
- Dual Age Aggregation: Both ASMR (pooled with weights) and All Ages (direct aggregation) are now computed and displayed
Slope3 Method Details (superseded by Slope4 in v4.8, then by Slope5 in v4.9, then by Slope6 in v5.0)
- Problem: Averaging all values in slope windows can be sensitive to outliers and noise
- Solution: Sort hazard values in each window, filter out zeros/negatives, take the lowest N values, then average
- Benefits: More stable slope estimates, especially for cohorts with variable or noisy mortality patterns
- Parameter: SLOPE3_MIN_VALUES (default: 5) controls how many lowest values to include in the average
- Purpose: Provides an alternative to ASMR pooling by treating all ages as a single aggregated cohort
- Method: Aggregates Dead, Alive, and person-time across all YearOfBirth values for each Dose and DateDied
- Difference from ASMR:
- ASMR (YearOfBirth = 0): Pools across age groups using expected-deaths weights (w_a ∝ h_a × PT_a)
- All Ages (YearOfBirth = -2): Direct aggregation without age grouping or weighting
- Display: Shown in console and summary outputs right after "ASMR (direct)"
- Use Case: Useful for comparing overall population-level effects without age-specific weighting
- KCOR_CMR DCCI stratification update: DCCI
2and4are now preserved as separate strata. - Removed DCCI collapse: Previous KCOR_CMR behavior that collapsed DCCI
2-4into3was removed. - Expanded DCCI buckets: KCOR_CMR now uses
{-1, 0, 1, 2, 3, 4, 5}.
- COVID hazard adjustment (Czech): Adjusts unvaccinated hazards during specified COVID weeks using a simple scaling around h0
- Configurable in dataset YAML:
covidCorrectionblock defines start/end ISO weeks and scaling factor
- Simplified two window slope normalization using
- Normalization now applies at the hazard stage only; raw MR values are never modified
- Removed Czech-specific unvaccinated MR adjustment and all anchor/windows parameters from defaults
- Cleaned console/log parameter dump to reflect SIN parameters only
- Added missing 3 vs 1 comparison for the 2022_06 cohort
- Improved KCOR Scaling Logic: Fixed baseline normalization adjustment to properly scale the scale factor
- Corrected Scaling Application: Scaling now applied to the scale factor, not individual KCOR values
- Enhanced Parameter Management: Single ENROLLMENT_DATES parameter replaces DEBUG_SHEET_ONLY
- Streamlined Processing: Removed 2021_13 enrollment date, focusing on 2021_24 and 2022_06 cohorts
- Transparent Logging: Original and adjusted scale factors logged when scaling is applied
- Preserved Relationships: All K_raw relationships maintained while correcting baseline bias
- Updated Examples: README examples updated with latest KCOR values from current analysis
- Before (v4.2): Scaling applied to individual KCOR values after computation
- After (v4.3): Scaling applied to the scale factor during computation
- Logic: Check final KCOR value, if < threshold, adjust scale factor by 1/final_KCOR
- Result: Proper baseline correction while preserving all relative relationships
- Transparency: Original and adjusted scale factors logged for full methodology transparency
- Option 2+ Expected-Deaths Weighting: Fixed ASMR pooling to properly reflect death burden
- Corrected ASMR Values: ASMR now reflects actual mortality impact, not population size
- Dose-Dependent Pattern Discovery: Revealed accelerating mortality pattern (1→2→3 doses)
- Mathematical Correctness: Elderly properly weighted, young under-weighted in ASMR
- Robust Implementation: Uses pooled quiet baseline window with smoothed mortality rates
- Enhanced Documentation: Complete explanation of Option 2+ methodology
- KCOR Normalization Fine-Tuning: Automatic baseline correction for unsafe vaccine effects
- Before (v4.1): Weights = person-time only → over-weighted young people
- After (v4.2): Weights = hazard × person-time → properly weighted by death burden
- Formula:
w_a ∝ h_a × PT_a(W)where h_a = smoothed mean MR in quiet window - Result: ASMR values now reflect actual mortality impact rather than population size
- Automatic Detection: Checks KCOR values on specified final date (default: April 1, 2024)
- Baseline Correction: Scales all KCOR values when KCOR_final < FINAL_KCOR_MIN (default: 0 disables scaling)
- Unsafe Vaccine Fix: Corrects for artificially high baseline mortality rates during normalization
- Transparent Process: Scaling factor is logged for full methodology transparency
- Conservative Approach: Only applies when clear evidence of baseline bias exists
- Dose 1 vs 0 (2021_24): KCOR = 1.05 (4.81% increased mortality risk)
- Dose 2 vs 0 (2021_24): KCOR = 1.26 (25.8% increased mortality risk)
- Dose 3 vs 0 (2022_06): KCOR = 1.55 (54.9% increased mortality risk)
- Pattern: Dose-dependent accelerating mortality with cohort-specific effects
- Discrete Hazard Function Transform: Enhanced mathematical exactness in CH calculation using hazard functions
- Hazard Ratio Methodology: KCOR computed as ratio of cumulative hazards with proper normalization
- Complete Methodology Transparency: All intermediate values included in output
- Error Handling: Automatic retry when Excel files are open
- Clean Console Output: Professional formatting with column headings
- Cross-Platform Build: Windows-compatible Makefile and scripts
- Version Documentation: Complete change history in code
- Hazard Values:
hazard_num/den- Discrete hazard function results - Slope Values:
slope_num/den- Slope used for each cohort - Scale Factors:
scale_factor_num/den-exp(-slope × (t - t0))values - Time Indices:
t_num/den- Time index (weeks from enrollment) - Smoothed MR:
MR_smooth_num/den- Smoothed MR values used for slope calculation
- Four-Step Process: MR_adj → hazard → cumsum(hazard) → hazard ratio for KCOR
- Hazard Function Transform:
hazard(t) = -ln(1 - MR_adj(t))with proper clipping - Cumulative Hazard:
CH(t) = sum(hazard(i))for mathematical exactness - Hazard Ratio:
KCOR(t) = (CH_v(t)/CH_u(t)) / (CH_v(t0)/CH_u(t0)) - Numerical Stability: Proper clipping to avoid log(0) and overflow
- Validation Ready: All mathematical relationships visible in output
The KCOR analysis of Czech vaccination and mortality data reveals significant findings across all dose levels compared to unvaccinated individuals:
| DOSE | KCOR | 95% CI | Risk Increase | Enrollment |
|---|---|---|---|---|
| 1 | 1.0453 | [1.016, 1.075] | +4.5% | 2021_24 |
| 2 | 1.2091 | [1.184, 1.235] | +20.9% | 2021_24 |
| 3 | 1.6354 | [1.603, 1.668] | +63.5% | 2022_06 |
- Dose 1 shows small harm - 4.5% increased mortality (2021_24; significant). The 2022_06 cohort estimate (1.0156) is not statistically significant (CI includes 1.0) because most of the harm happens within 6 months of the shot which was long ago in that cohort. Looking at Dose 1 much closer to vaccination gives a very large signal (over 40%). See the summary log for details.
- Dose 2 shows significant harm with 20.9% increased mortality (2021_24) and 6.5% (2022_06)
- Dose 3 shows severe harm with 53.5% increased mortality vs dose 2 and 63.5% vs dose 0 (2022_06), both highly significant
- Dose-dependent accelerating mortality - risk increases with additional doses
Key Insights:
- First dose shows significant harm - 5.2% (2021_24) to 11.9% (2022_06) increased mortality risk
- Second dose shows varying harm - 5.0% to 25.8% increased mortality risk depending on cohort
- Third dose shows severe harm - 49.4% to 54.9% increased mortality risk
- Cohort-dependent effects - 2021_24 cohort shows stronger dose 2 effects than 2022_06
- Accelerating pattern - each additional dose causes exponentially more harm
- No protective effect - all doses show statistically significant harm
Biological Interpretation: This pattern suggests that:
- Dose 1: Causes immediate and significant harm with no protective benefit
- Dose 2: Causes additional harm, with effects varying by timing of administration
- Dose 3: Causes severe cumulative damage with accelerating mortality risk
This dose-dependent accelerating mortality pattern provides compelling evidence of cumulative vaccine toxicity rather than simple linear dose-response effects.
⚠️ Important Note on Dose 1 Harm Estimates for older cohorts in the 2021_24 and subsequent enrollment periods
The Dose 1 harm estimates are likely CONSERVATIVE (underestimated) due to the enrollment period timing:
- Enrollment starts months after first doses: The analysis begins enrollment periods (2021_24, 2022_06) many months after the first COVID-19 vaccine doses were administered to elderly populations
- Early harm missed: Any immediate or early-term mortality effects from Dose 1 that occurred before the enrollment periods are not captured in this analysis
- Baseline period protection: The enrollment period was deliberately chosen to start after major COVID-19 waves to ensure accurate baseline mortality rate calculations
- Conservative interpretation: This means the true harm from Dose 1 is likely higher than the neutral effect (KCOR ≈ 1.0) shown in these results
This conservative bias is particularly important for understanding the true cumulative impact of COVID-19 vaccination on mortality risk.
For detailed results including age-specific analyses and all dose combinations, see the comprehensive analysis files:
- CMR Analysis:
analysis/Czech/KCOR_CMR_analysis.xlsx - 📈 Complete Analysis:
data/Czech/KCOR_summary.xlsx- Age-standardized and age-specific results by enrollment cohort - 📊 Full Dataset:
data/Czech/KCOR.xlsx- Complete analysis with all intermediate calculations - 📋 Console Output:
data/Czech/KCOR_summary.log- Detailed console output from analysis (dual output: console + file) - 🧮 KCOR Interactive Plotting Workbook:
analysis/Czech/KCOR_analysis.xlsx- Excel workbook for plotting KCOR(t) curves for any cohort/dose mix
These results demonstrate a dose-dependent accelerating mortality pattern that provides compelling evidence of cumulative vaccine toxicity:
- First dose (1 vs 0): Significant harm with 5.2% to 11.9% increased mortality risk
- Second dose (2 vs 0): Additional harm with 5.0% to 25.8% increased mortality risk
- Third dose (3 vs 0): Severe harm with 54.9% increased mortality risk
This pattern shows that all doses cause statistically significant harm with no protective benefit at any dose level. The analysis reveals cumulative damage with accelerating mortality risk for each additional dose. This finding is consistent across different enrollment cohorts and age groups, providing robust evidence of dose-dependent vaccine toxicity in the Czech population.
After getting the Hamamatsu data which I put in the data/japan directory, in the root directory run:
make convert # convert the .gz source to KRF format defaults to japan
make CMR_from_krf # this converts krf to Czech format and call make CMR to create the CMR file
make KCOR DATASET=japan # when done, we now have a KCOR_CMR.xlsx input file so do as normal
Unfortunately, there is too little data for most cohorts to be usable, especially younger cohorts.
The KCOR methodology has been independently validated using multiple approaches to ensure the robustness and accuracy of the results:
The validation/ directory contains multiple independent validation approaches to analyzing the Czech data: GLM, DS-CMRR, Kaplan-Meier, naturally matched cohorts, Aarstad correlation analysis, and time series analysis (KCOR_ts).
Here are the KCOR results for direct comparison with other methods (such as GLM and DS-CMRR) that produce similar style curves
-
GLM Validation: A completely different methodology using Generalized Linear Models with variable cohorts rather than fixed cohorts. This approach creates output that looks nearly identical to KCOR results, providing strong independent validation. Defaults use 4‑week ticks with vertical grid lines.
GLM validation results showing remarkable consistency with KCOR methodology
-
DS-CMRR Validation: Discrete Survival Cumulative Mortality Rate Ratio method for independent verification
This method can be used with either fixed or variable cohorts. I chose to run it against fixed cohorts because that is the more meaningful outcome, but others are free to run it against variable cohorts.
Question answered: "Between two groups defined at baseline, who accumulated more death risk over the window?"
Readout: DS-CMRR is the ratio of cumulative hazards between two pre-specified groups—closest to a trial-like contrast.
The smoking gun of extreme vaccine harm here is that the CMRR curve slope for dose 2 vs. dose 0 (and other combinations) increases sharply during the baseline period (when the vaccine causes the most increase in mortality). There is a CMRR simulation in the analysis directory which shows for any normal parameters, the slope at the start should be quite modest.
DS-CMRR output KCOR(t) for Czech data, dose 2 vs unvaccinated (single-sheet 2021_24)
-
Kaplan–Meier Validation: Traditional survival analysis on naturally matched cohorts (equalized initial population at enrollment) using
validation/kaplan_meier/.Observation: With naturally matched cohorts, the curves diverge with the unvaccinated cohort exhibiting lower mortality over time.
-
Naturally Matched Cohorts: I also validated using naturally matched cohorts where the cohorts are defined such that they had very similar deaths/week during the baseline and next COVID wave to demonstrate that matched cohort will diverge when a booster shot is given to a subset of the vaccinated group (which, if the vaccine was safe, should cause deaths to decrease, not increase).
So this plot finds net harm, but possibly a modest mortality benefit. KCOR, GLM, DS-CMRR, and KM (properly interpreted) reflects the same thing as this raw data.
This plot shows that with naturally matched cohorts, the curves remain aligned but when people got the boosters, it prevented their mortality from returning to baseline levels (slope of the cumulative death curve). This is why there was a negative net harm.
-
Aarstad Correlation Analysis: Independent correlation analysis of CDC deaths data by county, providing external validation of KCOR findings.
Aarstad correlation analysis showing consistent patterns with KCOR methodology
-
Time Series Analysis (KCOR_ts): A complementary analysis that computes mortality rates per week for cohorts defined relative to the time they received their vaccination dose, rather than fixed enrollment dates. Unlike KCOR_CMR which uses fixed enrollment dates, this groups cohorts by the calendar month they received their dose.
This analysis processes each dose (1-4) independently, as if that dose is the only dose received, and tracks mortality over 200 weeks after vaccination. Output includes:
dose: Vaccination dose (1-4)vaccination_month: Calendar month of vaccination (1-12)Decade_of_Birth: Birth decade (1920-1970)week_after_dose: Weeks since vaccination (0-200)alive: Number of people alive at start of weekdead: Number of deaths during weekh(t): Weekly hazard functioncum h(t): Cumulative hazard from week 0
Run:
make tsormake ts DATASET=Czech- Output:
data/Czech/KCOR_ts.xlsx - Documentation:
documentation/specs/time_series.md
This analysis provides an alternative perspective on mortality patterns by tracking cohorts from their vaccination date rather than a fixed enrollment date, complementing the fixed-cohort approach used in the main KCOR analysis.
In addition to the validation suite, the repository includes:
-
Negative-Control Tests (
test/negative_control/): Builds synthetic no-signal cohorts to ensure no false positives.- Run:
make test - Outputs:
test/negative_control/out/(e.g.,KCOR_processed_neg_control.xlsx,KCOR_summary.xlsx) - References:
reference_results/negative_control_tests/
These two graphs below show even with 10 and 20 year age differences between the cohorts, KCOR is able to accurately normalize the mortality and find neglible differences. Only when there is a real signal will there be a difference. Do you know of any other epidemiology tool that will find no signal in these groups which have dramatically different composition? All the methods I'm aware of require you to do 1:1 matching.
- Run:
-
Sensitivity Tests (
test/sensitivity/): Sweeps key parameters (cohorts, anchors, ages) to check stability.- Run:
make testormake sensitivity - Outputs:
test/sensitivity/out/(e.g.,KCOR_SA.xlsx,KCOR_summary_SA.log) - References:
reference_results/sensitivity/
- Run:
- Methodological Robustness: Verify KCOR results using alternative statistical approaches
- Cross-Validation: Ensure consistency across different analytical methods
- Sensitivity Analysis: Test the stability of results under different assumptions
- Reproducibility: Independent verification of KCOR computations
The validation studies confirm:
- Consistent Findings: KCOR results are robust across different analytical approaches
- Methodological Soundness: The discrete hazard function approach is mathematically valid
- Statistical Reliability: Confidence intervals and uncertainty quantification are appropriate
- Reproducibility: Results can be independently replicated using different implementations
For detailed validation results and methodology comparisons, see the validation/ directory.
Harvey Risch, with an h-index of 119, is arguably one of the top epidemiologists in the world. He reviewed an earlier version of KCOR and I made a transcript of the Zoom call. The bottom line is he didn't find any flaws in the methodology but noted that it would be hard to convince the epidemiology community because it is an engineering approach to making the harm/benefit assessment (he used the term "heuristic").
- Yale Professor Harvey Risch review (PDF):
peer_review/KCOR_Risch_review.pdf - Grok assessment: Grok validated the methodology, the documentation, and the implementation. It said the math was sound, but it didn't think people actually died per Gompertz mortality. It didn't have a real world counterexample.
"The KCOR method is a transparent and reproducible way to assess vaccine safety using only the most essential data. By relying solely on date of birth, vaccination, and death, it avoids the covariate manipulation and opaque modeling that plague conventional epidemiology, while slope normalization directly accounts for baseline mortality differences between groups. Applied to the Czech registry data, KCOR revealed a consistent net harm across all age groups. Given the strength and clarity of this signal, vaccine promoters will have no choice but to fall back on ideology rather than evidence in their response."
— Nicolas Hulscher, MPH
Epidemiologist and Administrator
McCullough Foundation
"KCOR cuts through the complication and obfuscation that epidemiologists tend to add to their models. A good model is as simple (and explainable) as it needs to be, but no simpler. Our goal in scientific analysis is to develop the simplest model that predicts the most, and KCOR fulfils that promise. It's easily explainable in English and correctly accounts for confounds that are hard to tease out of data. It makes the most use of the available data without complex bias-inducing "adjustments" and "controls". Kirsch has developed a novel method using key concepts from physics and engineering that can tease out the effects of a population-wide intervention when the "gold standard" RCT is unavailable or impossible. The cleverness of this approach shows how using simple physical pictures that are clearly explainable can clearly show what the obscure models in epidemiology cannot even begin to tackle. Complex methods often add bias and reduce explainability and cannot easily be audited by people without a Ph.D. in statistics. How many epidemiologists even understand all the transforms and corrections they make in their models? Without the ability to describe the analysis in simple language, it is impossible to make policy decisions and predictions for the future. Kirsch's new approach shows how we can easily monitor future interventions and quickly understand how safe and effective they are (and communicate that to the public effectively). It should be a standard tool in the public health toolbox. The disaster of COVID has had one positive effect where the smart people in science and engineering have become aware of the poor data analysis done in epidemiology and has brought many eyes into a once obfuscated field."
- US government epidemiologist who wants to keep his job
"For analyzing data such as from Czech government sources, where detailed comorbidity and cause of death information is not available, I'm not aware of any method that is likely to yield a more accurate result than KCOR."
- Epidemiologist with 12 years experience who wants to keep his job. Full review here.
If you had more variables, yes—methods like target trial emulation or g-computation could be "superior." But with just DOB, death, and vaccination:
-
KCOR is arguably the strongest you can do, because it enforces comparability by slope-neutralizing frailty and gives a time-resolved harm/benefit function.
-
A well-designed matched-cohort ASMR analysis (matching on age × calendar time, then computing excess deaths) is probably the only mainstream alternative. But it doesn't address the static HVE the way your slope correction does.
-
Dynamic Healthy Vaccinee Effect modeling (fit a decay curve for HVE explicitly and subtract it) is another approach people are experimenting with, but it usually requires more assumptions and doesn't generalize as cleanly.
With the constraints you've outlined:
-
No, there isn't a clearly superior epidemiological method in the mainstream toolbox.
-
KCOR is innovative precisely because it does what Cox/KM/ASMR matching can't: it corrects for frailty slope and produces a cumulative net harm/benefit curve.
-
The only possible challenger would be a Bayesian hierarchical survival model that explicitly encodes Gompertz mortality slopes, HVE decay, and vaccination as a time-varying covariate. But that would be more parametric/assumption-laden and less transparent than KCOR.
👉 So the short answer: For datasets limited to DOB, death, and vaccination dates, KCOR is about as good as it gets. The only "superior" option would be if you had richer covariates (comorbidities, SES, cause of death, infection timing). Without those, KCOR has the advantage of being both interpretable and robust against the main structural biases.
Grok claimed KCOR is mathematically sound, but in a later discussion claimed that KCOR is fundamentally flawed because relies on assumptions about the data that are clearly wrong, such as that you can normalize slope mortality for frail cohorts.
At first, Grok tried to argue that even for ideal Gompertz cohorts, KCOR would fail. So I had it compute the mortality rate change for age 80 with frailty 3 (which is more extreme than real life) and it realized there was only a 1.6% differential after 2 years. I pointed out KCOR is averaged out over that period so the error would be half that amount. I also pointed out that the slope computation is done over a year period in the center so the net error would be even smaller since it would error one way early and the other way later which further reduces the error.
Next Grok asked about the flu and other mortality disruptions. I said that virtually all such disruptions are proportional to baseline mortality and would be normalized out. The ONLY calendar disruption that is non-linear and large enough to impact the KCOR curves was COVID and it gave the vaccine the benefit of the doubt because KCOR assumes proportional hazards which are violated by the COVID virus; COVID kills the frail disproportionally more than would be predicted by the mortality ratio as you can instantly demostrate for yourself using the official Czech data by looking at different age groups in 2020 vs. 2019. You'll see no mortality increase under 45 at the end of 2020, but a >2X mortality increase for those over 85. The bottom line; KCOR is conservative since it assumes proportional hazards so it gives the vaccine the credit for COVID that it doesn't deserve.
Then the final argument was there is no possible way a 80-90 year old unvaccinated cohort could be slope normalized with an exponential because of the massive mix of frailty and depletion, even though we just went over that case. So I showed it that the actual Czech data could be fit with a straight line and that decimated its set of arguments. So much for the debunk attempts.
Grok could have said something like "before using KCOR, validate that the cohorts under study can be accurately adjusted with a simple exponential." If people did that, they'd be pleasantly surprised that there is no flaw. But instead, Grok simply dismissed KCOR as flawed because it assumes KCOR must be flawed because it conflicts with the "safe and effective" narrative.
In the real world, the underlying mortality trend is nearly linear over a 2 year period for most all cohorts of interest and most all hazards are proportional to mortality (COVID being the rare exception where KCOR will give a conservative harm estimate). If needed, KCOR can easily be adapted to highly frail cohorts using piecewise slope normalization if it is necessary to get extreme accuracy for these cases. Grok seemed more interested in trashing the method than pointing out how it's objections can be easily overcome.
Here is the full discussion with Grok showing it lacked actual evidence that falsifies KCOR and finally said that it would recommend KCOR (see Grok Review)
Read this excellent review.
"KCOR is not just a statistical trick—it’s an epistemological challenge to the medical‑industrial complex. It says: “Give me only your raw dates, and I’ll tell you whether your narrative survives arithmetic.” In a world drowning in models and PR, that level of raw honesty is revolutionary."
This project is licensed under the MIT License — see https://opensource.org/licenses/MIT for details.
For questions about the methodology or implementation, please open an issue on GitHub or contact the development team.
Note: This software is designed for research purposes. Users should carefully validate results and consider the specific context of their data and research questions.







