def get_stroke_probability(self, person): model_spec = load_model_spec("StrokeMIPartitionModel") strokePartitionModel = StatsModelLinearRiskFactorModel( RegressionModel(**model_spec)) strokeProbability = scipySpecial.expit( strokePartitionModel.estimate_next_risk(person)) return strokeProbability
def testInteractionModel(self): testPerson = self.people[32] expected_model_result = ( np.array(testPerson._sbp).mean() * testPerson._age[-1] * self.ageSbpInteractionCoeff + np.array(testPerson._sbp).mean() * self.sbpInteractionCoeff) model = StatsModelLinearRiskFactorModel(self.interactionModel) person_data = self.population_dataframe.iloc[32] actual_model_result = model.estimate_next_risk_vectorized(person_data) self.assertAlmostEqual(expected_model_result, actual_model_result, 5)
def testSimpleModel(self): df = init_vectorized_population_dataframe([self.person], with_base_gcp=True) person_data = df.iloc[0] expected_model_result = ( self.simpleModelResultSM.params["age"] * person_data.age + self.simpleModelResultSM.params["Intercept"]) model = StatsModelLinearRiskFactorModel(self.simpleModelResult) actual_model_result = model.estimate_next_risk_vectorized(person_data) self.assertEqual(expected_model_result, actual_model_result)
def testModelWithLogMeanParameter(self): testPerson = self.people[10] expected_model_result = ( self.logMeanModelResultSM.params["age"] * testPerson._age[-1] + self.logMeanModelResultSM.params["logMeanSbp"] * np.log(np.array(testPerson._sbp).mean()) + self.logMeanModelResultSM.params["Intercept"]) model = StatsModelLinearRiskFactorModel(self.logMeanModelResult) person_data = self.population_dataframe.iloc[10] actual_model_result = model.estimate_next_risk_vectorized(person_data) self.assertAlmostEqual(expected_model_result, actual_model_result, 5)
def testModelWithCategoricalParameter(self): testPerson = self.people[21] testRace = testPerson._raceEthnicity raceParamName = f"raceEthnicity[T.{int(testRace)}]" expected_model_result = ( self.raceModelResultSM.params["age"] * testPerson._age[-1] + self.raceModelResultSM.params[raceParamName] + self.raceModelResultSM.params["Intercept"]) model = StatsModelLinearRiskFactorModel(self.raceModelResult) person_data = self.population_dataframe.iloc[21] actual_model_result = model.estimate_next_risk_vectorized(person_data) self.assertAlmostEqual(expected_model_result, actual_model_result, 5)
def _initialize_linear_risk_model(self, referenceName, modelName, log=False): model = load_regression_model(modelName) self._repository[referenceName] = StatsModelLinearRiskFactorModel( model, log)
def __init__( self, mi_case_fatality=default_mi_case_fatality, stroke_case_fatality=default_stroke_case_fatality, mi_secondary_case_fatality=default_secondary_mi_case_fatality, stroke_secondary_case_fatality=default_secondary_stroke_case_fatality, secondary_prevention_multiplier=default_secondary_prevention_multiplier, ): self.mi_case_fatality = mi_case_fatality self.mi_secondary_case_fatality = (mi_secondary_case_fatality,) self.stroke_case_fatality = stroke_case_fatality self.stroke_secondary_case_fatality = stroke_secondary_case_fatality self.secondary_prevention_multiplier = secondary_prevention_multiplier model_spec = load_model_spec("StrokeMIPartitionModel") self.strokePartitionModel = StatsModelLinearRiskFactorModel(RegressionModel(**model_spec))
def testInteractionModel(self): testPerson = self.people[32] self.assertAlmostEqual( np.array(testPerson._sbp).mean() * testPerson._age[-1] * self.ageSbpInteractionCoeff + np.array(testPerson._sbp).mean() * self.sbpInteractionCoeff, StatsModelLinearRiskFactorModel( self.interactionModel).estimate_next_risk(testPerson), 5)
def testModelWithLogMeanParameter(self): testPerson = self.people[10] self.assertAlmostEqual( self.logMeanModelResultSM.params['age'] * testPerson._age[-1] + self.logMeanModelResultSM.params['logMeanSbp'] * np.log(np.array(testPerson._sbp).mean()) + self.logMeanModelResultSM.params['Intercept'], StatsModelLinearRiskFactorModel( self.logMeanModelResult).estimate_next_risk(testPerson), 5)
def testModelWithCategoricalParameter(self): testPerson = self.people[21] testRace = testPerson._raceEthnicity self.assertAlmostEqual( self.raceModelResultSM.params['age'] * testPerson._age[-1] + self.raceModelResultSM.params['raceEthnicity[T.' + str(int(testRace)) + ']'] + self.raceModelResultSM.params['Intercept'], StatsModelLinearRiskFactorModel( self.raceModelResult).estimate_next_risk(testPerson), 5)
def testLagAndMean(self): testPerson = self.people[12] self.assertAlmostEqual( self.meanLagModelResultSM.params['age'] * testPerson._age[-1] + self.meanLagModelResultSM.params['meanSbp'] * np.array(testPerson._sbp).mean() + self.meanLagModelResultSM.params['lagSbp'] * testPerson._sbp[-1] + self.meanLagModelResultSM.params['Intercept'], StatsModelLinearRiskFactorModel( self.meanLagModelResult).estimate_next_risk(testPerson), 5)
def testSimpleModel(self): self.assertEqual( self.simpleModelResultSM.params['age'] * self.person._age[-1] + self.simpleModelResultSM.params['Intercept'], StatsModelLinearRiskFactorModel( self.simpleModelResult).estimate_next_risk(self.person))
class CVOutcomeDetermination: default_mi_case_fatality = 0.13 default_secondary_mi_case_fatality = 0.13 default_stroke_case_fatality = 0.15 default_secondary_stroke_case_fatality = 0.15 default_secondary_prevention_multiplier = 1.0 # fatal stroke probability estimated from our meta-analysis of BASIC, NoMAS, GCNKSS, REGARDS # fatal mi probability from: Wadhera, R. K., Joynt Maddox, K. E., Wang, Y., Shen, C., Bhatt, # D. L., & Yeh, R. W. # (2018). Association Between 30-Day Episode Payments and Acute Myocardial Infarction Outcomes # Among Medicare # Beneficiaries. Circ. Cardiovasc. Qual. Outcomes, 11(3), e46–9. # http://doi.org/10.1161/CIRCOUTCOMES.117.004397 def __init__( self, mi_case_fatality=default_mi_case_fatality, stroke_case_fatality=default_stroke_case_fatality, mi_secondary_case_fatality=default_secondary_mi_case_fatality, stroke_secondary_case_fatality=default_secondary_stroke_case_fatality, secondary_prevention_multiplier=default_secondary_prevention_multiplier, ): self.mi_case_fatality = mi_case_fatality self.mi_secondary_case_fatality = (mi_secondary_case_fatality,) self.stroke_case_fatality = stroke_case_fatality self.stroke_secondary_case_fatality = stroke_secondary_case_fatality self.secondary_prevention_multiplier = secondary_prevention_multiplier model_spec = load_model_spec("StrokeMIPartitionModel") self.strokePartitionModel = StatsModelLinearRiskFactorModel(RegressionModel(**model_spec)) def _will_have_cvd_event(self, ascvdProb): return npRand.uniform(size=1) < ascvdProb def _will_have_mi(self, person, outcome_model_repository, vectorized=False, manualMIProb=None): if manualMIProb is not None: return npRand.uniform(size=1) < manualMIProb # if no manual MI probablity, estimate it from oru partitioned model strokeProbability = self.get_stroke_probability(person, vectorized) return npRand.uniform(size=1) < (1 - strokeProbability) def get_stroke_probability(self, person, vectorized=False): strokeProbability = 0 if vectorized: strokeProbability = scipySpecial.expit( self.strokePartitionModel.estimate_next_risk_vectorized(person) ) else: strokeProbability = scipySpecial.expit( self.strokePartitionModel.estimate_next_risk(person) ) return strokeProbability def _will_have_fatal_mi(self, person, vectorized=False, overrideMIProb=None): fatalMIProb = overrideMIProb if overrideMIProb is not None else self.mi_case_fatality fatalProb = ( self.mi_secondary_case_fatality if self.has_prior_mi(person, vectorized) else fatalMIProb ) return npRand.uniform(size=1) < fatalProb def _will_have_fatal_stroke(self, person, vectorized=False, overrideStrokeProb=None): fatalStrokeProb = ( overrideStrokeProb if overrideStrokeProb is not None else self.stroke_case_fatality ) fatalProb = ( self.stroke_secondary_case_fatality if self.has_prior_stroke(person, vectorized) else fatalStrokeProb ) return npRand.uniform(size=1) < fatalProb def get_risk_for_person(self, outcome_model_repository, person, vectorized): if vectorized: return outcome_model_repository.get_risk_for_person( person, OutcomeModelType.CARDIOVASCULAR, years=1, vectorized=True ) else: return outcome_model_repository.get_risk_for_person( person, OutcomeModelType.CARDIOVASCULAR, years=1 ) def has_prior_stroke(self, person, vectorized): return person.stroke if vectorized else person._stroke def has_prior_mi(self, person, vectorized): return person.mi if vectorized else person._mi def has_prior_stroke_mi(self, person, vectorized): return self.has_prior_stroke(person, vectorized) or self.has_prior_mi(person, vectorized) def assign_outcome_for_person( self, outcome_model_repository, person, vectorized=False, years=1, manualStrokeMIProbability=None, ): cvRisk = self.get_risk_for_person(outcome_model_repository, person, vectorized) if self.has_prior_stroke_mi(person, vectorized): cvRisk = cvRisk * self.secondary_prevention_multiplier return self.get_or_assign_outcomes( cvRisk, person, outcome_model_repository, vectorized, manualStrokeMIProbability ) def get_or_assign_outcomes( self, cvRisk, person, outcome_model_repository, vectorized, manualStrokeMIProbability ): if self._will_have_cvd_event(cvRisk): if self._will_have_mi( person, outcome_model_repository, vectorized, manualStrokeMIProbability ): return self.get_outcome( person, True, self._will_have_fatal_mi(person, vectorized), vectorized ) else: return self.get_outcome( person, False, self._will_have_fatal_stroke(person, vectorized), vectorized ) elif vectorized: person.miNext = False person.strokeNext = False person.deadNext = False return person def get_outcome(self, person, mi, fatal, vectorized): if vectorized: person.miNext = mi person.strokeNext = not mi person.deadNext = fatal person.miFatal = mi and fatal person.strokeFatal = not mi and fatal person.ageAtFirstMI = ( person.age if (person.ageAtFirstMI is None) or (np.isnan(person.ageAtFirstMI)) else person.ageAtFirstMI ) person.ageAtFirstStroke = ( person.age if (person.ageAtFirstStroke is None) or (np.isnan(person.ageAtFirstStroke)) else person.ageAtFirstStroke ) return person else: return Outcome(OutcomeType.MI if mi else OutcomeType.STROKE, fatal)