This article is detailing about an important concept in Machine Learning and enhances the modelling process, particularly in binary classification problems.

  1. What is the Weight of Evidence (WOE)?
  2. Use case of WOE
  3. How to Calculate WOE?
  4. How it is useful in Logistic Regression
  5. What is Information Value (IV)?
  6. How to Calculate IV?
  7. Interpretation of IV
  8. Needs of WOW & IV
  9. How to calculate WOE and IV in Python

What is the Weight of Evidence (WOE)?

Weight of Evidence (WOE) and Information Value (IV) are often used as preprocessing techniques in logistic regression, specifically in the context of binary classification problems where the dependent variable is categorical with two outcomes (0 or 1).

WOE is applied to transform predictor variables, especially categorical or continuous ones, into a format suitable for logistic regression.

Use case of WOE

Weight of Evidence is often used in credit scoring, fraud detection, Risk Modelling, and any binary classification problem where understanding the impact of predictor variables on the target variable is crucial.

How to Calculate WOE?


Step 1. Data Binning/Grouping

For continuous variables, divide the variable into bins or intervals. For categorical variables, each category is treated as a separate bin.

Step 2. Calculate WOE

For each bin, calculate the percentage of events and non-events.

Calculate the Weight of Evidence (WOE) using the formula.

WOE=ln(%of Events / %of Non-events​)

How is it useful in Logistic Regression?

What is Information Value (IV)?

Information Value (IV) is a metric used to measure the predictive power of a variable in a binary classification model, such as logistic regression. The IV is often calculated in conjunction with the Weight of Evidence (WOE) for each category or bin of a predictor variable.

How to Calculate IV?

IV=∑(%of Non-events−%of Events)×WOE
  1. Calculate the WOE for each bin or category of a variable.
  2. Calculate the percentage of events and non-events in each bin.
  3. Compute the difference between the percentage of non-events and events in each bin.
  4. Multiply the difference by the WOE for each bin.
  5. Sum up the results across all bins to get the Information Value

Interpretation of IV

Higher IV values indicate a stronger predictive power of the variable.

IV can be interpreted as follows.

Information Value Predictive power
Less than 0.02 Not useful for prediction
0.02 to 0.1 Weak predictive power
0.1 to 0.3 Moderate predictive power
0.3 to 0.5 Strong predictive power
Greater than 0.5 Suspicious predictive power


Needs of WOW & IV

How to calculate WOE and IV in Python?

You can use the below function in Python by passing a dataset, the feature of interest (feature_b), the target variable (target), and the target categories (target_category). The function will return a DataFrame (dset) containing WoE-related information and the calculated IV.

def calculate_woe_iv(dataset, feature_b, target,target_category):

    dataset[feature_b].replace([np.inf, -np.inf], np.nan, inplace = True)

    if dataset[feature_b].dtype in ['float64', 'int64'] and 'flag' not in feature_b.lower():
        dataset['feature'] = pd.qcut(dataset[feature_b], q = [0, .05, .1, .2,.4, .6, .8,0.9,0.95, 1],
                                     duplicates = 'drop', precision = 0).values.add_categories(['Missing', 'Others'])
    else:
        dataset['feature'] = dataset[feature_b]

    dataset['feature'].fillna('Missing', inplace = True)

    lst = []
    num_rows = dataset.shape[0]

    val_list = dataset['feature'].unique()
    for val in val_list:
        occ_val = dataset[dataset['feature'] == val].count()['feature']
        if occ_val < 0.005 * num_rows :
            dataset['feature'] = np.where(dataset['feature'] == val, 'Others', dataset['feature'])

    val_list = dataset['feature'].unique()
    for val in val_list:
        lst.append({
        'Feature': feature_b,
        'Value': val,
        'All': dataset[dataset['feature'] == val].count()['feature'],
        'Good': dataset[(dataset['feature'] == val) & (dataset[target] == 0)].count()['feature'],
        'Bad': dataset[(dataset['feature'] == val) & (dataset[target] == 1)].count()['feature']
        })

    dset = pd.DataFrame(lst)
    dset['Event_rate'] = dset['Bad'] / dset['All']
    dset['Prop'] = dset['All'] / dset['All'].sum()
    dset['Prop_Good'] = dset['Good'] / dset['Good'].sum()
    dset['Prop_Bad'] = dset['Bad'] / dset['Bad'].sum()
    dset['WoE'] = np.log(dset['Prop_Good'] / dset['Prop_Bad'])
    dset = dset.replace({'WoE': {np.inf: 0, -np.inf: 0}})
    dset['IV_component'] = (dset['Prop_Good'] - dset['Prop_Bad']) * dset['WoE']

    iv = dset['IV_component'].sum()

    dset = dset.sort_values(by = 'Event_rate')

    return  dset, iv

I hope you find this information useful.

Happy Learning!