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
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
 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)