A library for Probabilistic Graphical Models
—
Functions for evaluating model quality, computing metrics, and validating learned structures. pgmpy provides comprehensive evaluation tools for assessing both model fit and predictive performance.
def correlation_score(model, data, test="chi_square", significance_level=0.05,
score=log_likelihood_score, return_summary=False):
"""
Test correlation between model and data using statistical tests.
Parameters:
- model: DiscreteBayesianNetwork to evaluate
- data: pandas.DataFrame with observed data
- test: statistical test to use ("chi_square", "freeman_tuckey", "log_likelihood", "modified_log_likelihood", "neyman", "cressie_read")
- significance_level: significance threshold for hypothesis testing
- score: scoring function for model comparison
- return_summary: whether to return detailed test summary
Returns:
dict: Test statistic, p-value, and test result
"""
def fisher_c(model, data, ci_test, show_progress=True):
"""
Compute Fisher's C test statistic for model evaluation.
Parameters:
- model: DiscreteBayesianNetwork to test
- data: pandas.DataFrame with data
- ci_test: conditional independence test function
- show_progress: whether to show progress bar
Returns:
dict: Fisher's C statistic and p-value
"""def log_likelihood_score(model, data):
"""
Compute log-likelihood of data given model.
Parameters:
- model: DiscreteBayesianNetwork fitted model
- data: pandas.DataFrame with observed data
Returns:
float: Log-likelihood score (higher is better)
"""
def structure_score(model, data, scoring_method="bic-g", **kwargs):
"""
Compute structure quality score.
Parameters:
- model: DiscreteBayesianNetwork to score
- data: pandas.DataFrame with data
- scoring_method: scoring method ("bic", "aic", "bdeu", "k2", "bic-g", "aic-g")
- kwargs: additional arguments for scoring method
Returns:
float: Structure score
"""def implied_cis(model, data, ci_test, show_progress=True):
"""
Test all conditional independencies implied by the model.
Parameters:
- model: DiscreteBayesianNetwork with structure to test
- data: pandas.DataFrame with observed data
- ci_test: conditional independence test function
- show_progress: whether to show progress bar
Returns:
dict: Results of all CI tests including test statistics and p-values
"""def SHD(true_model, est_model):
"""
Compute Structural Hamming Distance between two graph structures.
Parameters:
- true_model: DiscreteBayesianNetwork with true structure
- est_model: DiscreteBayesianNetwork with estimated structure
Returns:
int: Number of edge differences (additions + deletions + reversals)
"""class BayesianModelProbability:
def __init__(self, data):
"""
Compute model probabilities for structure comparison.
Parameters:
- data: pandas.DataFrame with observed data
"""
def score(self, model):
"""
Compute log marginal likelihood of model.
Parameters:
- model: DiscreteBayesianNetwork to score
Returns:
float: Log marginal likelihood
"""
def get_model_probability(self, models):
"""
Get posterior probabilities over set of models.
Parameters:
- models: list of DiscreteBayesianNetwork objects
Returns:
dict: Model probabilities {model_index: probability}
"""def cross_validate(model, data, folds=5, scoring_method="log_likelihood"):
"""
Perform k-fold cross-validation for model evaluation.
Parameters:
- model: DiscreteBayesianNetwork to evaluate
- data: pandas.DataFrame with complete data
- folds: number of cross-validation folds
- scoring_method: evaluation metric to use
Returns:
dict: Cross-validation scores and statistics
"""
def prediction_accuracy(model, test_data, variables=None):
"""
Compute prediction accuracy on test data.
Parameters:
- model: fitted DiscreteBayesianNetwork
- test_data: pandas.DataFrame with test data (may have missing values)
- variables: list of variables to evaluate predictions for
Returns:
dict: Accuracy metrics for each predicted variable
"""
def classification_metrics(y_true, y_pred, labels=None):
"""
Compute classification performance metrics.
Parameters:
- y_true: true class labels
- y_pred: predicted class labels
- labels: list of class label names
Returns:
dict: Precision, recall, F1-score, and accuracy
"""def mutual_information(model, var1, var2, evidence=None):
"""
Compute mutual information between variables.
Parameters:
- model: DiscreteBayesianNetwork
- var1: first variable name
- var2: second variable name
- evidence: dict of conditioning variables
Returns:
float: Mutual information I(var1; var2 | evidence)
"""
def conditional_entropy(model, var, evidence):
"""
Compute conditional entropy H(var | evidence).
Parameters:
- model: DiscreteBayesianNetwork
- var: variable name
- evidence: dict of conditioning variables
Returns:
float: Conditional entropy
"""
def kl_divergence(model1, model2, variables=None):
"""
Compute KL divergence between two models.
Parameters:
- model1: first DiscreteBayesianNetwork
- model2: second DiscreteBayesianNetwork
- variables: list of variables to compute divergence over
Returns:
float: KL divergence D(model1 || model2)
"""def parameter_sensitivity(model, data, parameter, delta=0.01):
"""
Analyze sensitivity of model predictions to parameter changes.
Parameters:
- model: DiscreteBayesianNetwork
- data: pandas.DataFrame with query data
- parameter: parameter to perturb (CPD entry)
- delta: perturbation amount
Returns:
dict: Sensitivity measures for model outputs
"""
def structure_sensitivity(model, data, edge_modifications):
"""
Analyze impact of structural changes on model performance.
Parameters:
- model: DiscreteBayesianNetwork base model
- data: pandas.DataFrame with evaluation data
- edge_modifications: list of edge changes to test
Returns:
dict: Performance changes for each structural modification
"""from pgmpy.metrics import correlation_score, log_likelihood_score
from pgmpy.models import DiscreteBayesianNetwork
import pandas as pd
# Assume we have a fitted model and test data
model = DiscreteBayesianNetwork([('A', 'C'), ('B', 'C')])
# ... add CPDs and fit model ...
test_data = pd.DataFrame({
'A': [0, 1, 0, 1],
'B': [1, 0, 1, 0],
'C': [0, 1, 1, 0]
})
# Test model-data correlation
correlation_result = correlation_score(
model, test_data,
test="chi_square",
significance_level=0.05
)
print("Correlation test:", correlation_result)
# Compute log-likelihood
ll_score = log_likelihood_score(model, test_data)
print(f"Log-likelihood: {ll_score}")from pgmpy.metrics import SHD, structure_score
# Compare two model structures
true_model = DiscreteBayesianNetwork([('A', 'C'), ('B', 'C')])
learned_model = DiscreteBayesianNetwork([('A', 'B'), ('B', 'C')])
# Compute structural hamming distance
distance = SHD(true_model, learned_model)
print(f"Structural Hamming Distance: {distance}")
# Score structures
true_score = structure_score(true_model, test_data, scoring_method="bic")
learned_score = structure_score(learned_model, test_data, scoring_method="bic")
print(f"True model BIC: {true_score}")
print(f"Learned model BIC: {learned_score}")from pgmpy.metrics import implied_cis
from pgmpy.estimators.CITests import chi_square
# Test all conditional independencies implied by model
ci_results = implied_cis(
model, test_data,
ci_test=chi_square,
show_progress=True
)
print("CI test results:")
for independence, result in ci_results.items():
print(f"{independence}: p-value = {result['p_value']:.4f}")# Perform cross-validation (assuming function exists)
cv_results = cross_validate(
model, test_data,
folds=5,
scoring_method="log_likelihood"
)
print("Cross-validation results:")
print(f"Mean score: {cv_results['mean_score']:.4f}")
print(f"Std deviation: {cv_results['std_score']:.4f}")
print(f"Fold scores: {cv_results['fold_scores']}")# Compute mutual information between variables
mi_ac = mutual_information(model, 'A', 'C')
mi_bc = mutual_information(model, 'B', 'C')
mi_ac_given_b = mutual_information(model, 'A', 'C', evidence={'B': 1})
print(f"I(A; C) = {mi_ac:.4f}")
print(f"I(B; C) = {mi_bc:.4f}")
print(f"I(A; C | B=1) = {mi_ac_given_b:.4f}")
# Compute conditional entropy
h_c_given_ab = conditional_entropy(model, 'C', {'A': 0, 'B': 1})
print(f"H(C | A=0, B=1) = {h_c_given_ab:.4f}")Install with Tessl CLI
npx tessl i tessl/pypi-pgmpy