def information_gain(data, split_feature_name, label_feature_name, metric):
    """
    Calculate the information gain using the given metric.

    :param data: the data to anlyze
    :param split_feature_name: the name of the split feature
    :param label_feature_name: the name of the label feature
    :param metric: the metric to use

    :return: the information gain given by splitting on the split feature
    """

    feature_values = data[split_feature_name]
    possible_values = feature_values.unique()

    expected_metric_value = 0
    for possible_value in possible_values:
        subset = data.loc[data[split_feature_name] == possible_value]

        weight = len(subset) / len(data)
        expected_metric_value += weight * metric(subset, label_feature_name)

    return metric(data, label_feature_name) - expected_metric_value