def drop_labels(events, min_pct=.05):
    """
    Snippet 3.8 page 54

    This function recursively eliminates rare observations.

    :param events: (data frame) events
    :param min_pct: (float) a fraction used to decide if the observation occurs less than
    that fraction
    :return: (data frame) of events
    """
    # Apply weights, drop labels with insufficient examples
    while True:
        df0 = events['bin'].value_counts(normalize=True)

        if df0.min() > min_pct or df0.shape[0] < 3:
            break

        print('dropped label: ', df0.argmin(), df0.min())
        events = events[events['bin'] != df0.argmin()]

    return events