Hive-Systems / pyfair

Factor Analysis of Information Risk (FAIR) model written in Python. Managed and maintained by Hive Systems
https://www.hivesystems.com
MIT License
89 stars 45 forks source link

Secondary losses computed through input_multi_data are wrong #43

Open arognoni opened 2 years ago

arognoni commented 2 years ago

The secondary losses computed through input_multi_data are wrong. Here are some examples:

model1 = pyfair.FairModel(name="Insider Threat", n_simulations=10)
model1.input_multi_data('Secondary Loss', {
    'Reputational': {
        'Secondary Loss Event Frequency': {'constant': 1},
        'Secondary Loss Event Magnitude': {'constant': 10},
    },
    'Legal': {
        'Secondary Loss Event Frequency': {'constant': 1},
        'Secondary Loss Event Magnitude': {'constant': 10},
    }
})

In this case, the secondary loss should be 20 (10 x 1 + 10 x 1) for all simulations. However, all elements of model1._model_table["Secondary Loss"] are equal to 101. If one sets all the frequencies to 1:


model2 = pyfair.FairModel(name="Insider Threat", n_simulations=10)
model2.input_multi_data('Secondary Loss', {
    'Reputational': {
        'Secondary Loss Event Frequency': {'constant': 0},
        'Secondary Loss Event Magnitude': {'constant': 10},
    },
    'Legal': {
        'Secondary Loss Event Frequency': {'constant': 0},
        'Secondary Loss Event Magnitude': {'constant': 10},
    }
})

All elements of model2._model_table["Secondary Loss"] are equal to 100 instead of 0. Furthermore, an error is returned if one uses more than two loss types:

model3 = pyfair.FairModel(name="Insider Threat", n_simulations=10)
model3.input_multi_data('Secondary Loss', {
    'Reputational': {
        'Secondary Loss Event Frequency': {'constant': 1},
        'Secondary Loss Event Magnitude': {'constant': 10},
    },
    'Legal': {
        'Secondary Loss Event Frequency': {'constant': 1},
        'Secondary Loss Event Magnitude': {'constant': 10},
    },
    'Response': {
        'Secondary Loss Event Frequency': {'constant': 1},
        'Secondary Loss Event Magnitude': {'constant': 10},
    }
})

The result is:

in FairModel.input_multi_data(self, target, kwargs_dict)
    286 """Input data for multiple items that roll up into an aggregate
    287 
    288 As of now, this is only used for Secondary Loss when calculating
   (...)
...
--> 258 df1, df2 = df_dict.values()
    259 combined_df = df1 * df2
    260 # Sum

ValueError: too many values to unpack (expected 2)