Модели машинного обучения — это мощные инструменты для прогнозирования и извлечения информации из данных. Однако оценка производительности этих моделей имеет решающее значение для обеспечения их эффективности.

В этом сообщении блога мы рассмотрим несколько важных показателей модели машинного обучения и обсудим, почему они необходимы для оценки производительности модели. Мы также предоставим реализацию кода на Python для расчета этих показателей.

  1. КС (Колмогоров-Смирнов):

KS — популярная метрика, используемая для измерения разделения между положительными и отрицательными образцами в задаче бинарной классификации. Он оценивает, насколько хорошо модель различает два класса. KS находится в диапазоне от 0 до 1, причем более высокие значения указывают на лучшее разделение. Значение KS, равное 1, означает идеальную дискриминацию.

import os
import random
import numpy as np
import pandas as pd
from modelEvaluation import *
from ExcelHelper import *
import modelEvaluation

def random_seed(seed):
    os.environ['PYTHONHASHSEED'] = str(seed)  # Python general
    np.random.seed(seed)
    random.seed(seed)  # Python random

def KS(actual_val, pred_val, wt=1):
    '''
    Calculates KS (Kolmogorov-Smirnov) statistic.

    Args:
        actual_val: Actual values.
        pred_val: Predicted values.
        wt: Weight (optional, default is 1).

    Returns:
        KS statistic.
    '''
    temp_dat = pd.DataFrame({'Actual_Val': np.array(actual_val), 'Pred_Val': np.array(pred_val)})
    
    if isinstance(wt, int):
        temp_dat['wt'] = wt
    else:
        temp_dat['wt'] = wt.values
    
    temp_dat = temp_dat.sample(frac=1)
    temp_dat.sort_values(by=['Pred_Val'], inplace=True, ascending=True)
    
    temp_dat['1sWt'] = temp_dat['Actual_Val'] * temp_dat['wt']
    cnt_1 = temp_dat.groupby(['Pred_Val'])['1sWt'].sum()
    
    temp_dat['0sWt'] = (1 - temp_dat['Actual_Val']) * temp_dat['wt']
    cnt_0 = temp_dat.groupby(['Pred_Val'])['0sWt'].sum()  
    
    sum_1 = np.cumsum(cnt_1 / sum(cnt_1))
    sum_0 = np.cumsum(cnt_0 / sum(cnt_0))
    
    ks = max(abs(sum_1 - sum_0))
    
    return ks

2. Канзас Дециль,

ks_decile – это альтернативная версия показателя KS, которая разбивает данные на 10 групп (децилей) одинакового размера на основе предсказанных вероятностей. Он измеряет максимальное значение KS среди этих децилей, предоставляя представление о том, насколько хорошо модель работает в разных сегментах данных.

def KS_decile(actual_val, pred_val, wt=1):
    '''
    Calculates KS (Kolmogorov-Smirnov) statistic based on 10 deciles.

    Args:
        actual_val: Actual values.
        pred_val: Predicted values.
        wt: Weight (optional, default is 1).

    Returns:
        KS statistic.
    '''
    temp_dat_s = modelEvaluation.RankOrderBinary_V2(d_samp=actual_val, dpred=pred_val, nquantiles=10)
    ks = np.max(temp_dat_s['KS'])
    return ks

3. qKS (квантиль KS):

qKS — это вариант метрики KS, который идентифицирует квантиль с максимальным значением KS. Он вычисляет KS для различных квантилей прогнозируемых вероятностей и помогает определить конкретный квантиль, в котором производительность модели является самой сильной.

import pandas as pd
import numpy as np

def qKS(actual_val, pred_val, wt=1, q=10):
    '''
    Calculates the quantile in which KS is max.

    Args:
        actual_val: Actual values.
        pred_val: Predicted values.
        wt: Weight (optional, default is 1).
        q: Number of quantiles (optional, default is 10).

    Returns:
        DataFrame with KS values for each quantile and the maximum KS value.
    '''
    temp_dat = pd.DataFrame({'Actual_Val': np.array(actual_val), 'Pred_Val': np.array(pred_val)})
    dfKS = pd.DataFrame()

    if isinstance(wt, int):  # or len(wt)==1
        temp_dat['Actual_Val'] = temp_dat['Actual_Val'] * wt
        dfKS['cnt_1'] = temp_dat.groupby(['Pred_Val']).sum()['Actual_Val']
        temp_dat['Actual_Val'] = wt - temp_dat['Actual_Val']
        dfKS['cnt_2'] = temp_dat.groupby(['Pred_Val']).sum()['Actual_Val']
    else:
        temp_dat['wt'] = wt
        temp_dat['Actual_Val'] = temp_dat['Actual_Val'] * temp_dat['wt']
        dfKS['cnt_1'] = temp_dat.groupby(['Pred_Val']).sum()['Actual_Val']
        temp_dat['Actual_Val'] = temp_dat['wt'] - temp_dat['Actual_Val']
        dfKS['cnt_2'] = temp_dat.groupby(['Pred_Val']).sum()['Actual_Val']
    
    dfKS['cumsum1'] = np.cumsum(dfKS['cnt_1'] / sum(dfKS['cnt_1']))
    dfKS['cumsum2'] = np.cumsum(dfKS['cnt_2'] / sum(dfKS['cnt_2']))
    dfKS['finalm'] = abs(dfKS['cumsum1'] - dfKS['cumsum2'])
    
    dfKS.reset_index(inplace=True)
    dfKS['label'] = pd.qcut(dfKS['Pred_Val'].rank(method='first'), q=q, labels=False)
    dfKSbin = dfKS.groupby('label').max()['finalm']
    
    return dfKSbin, max(dfKSbin)

Расчет статистики KS в каждом квантиле помогает определить, есть ли существенные различия между прогнозируемыми и фактическими значениями в каждом сегменте. Более высокое значение KS в квантиле указывает на лучшее различение положительных и отрицательных случаев, предполагая, что модель хорошо работает в этом конкретном диапазоне прогнозируемых вероятностей.

4. Джини:

Джини — еще одна метрика, обычно используемая в задачах бинарной классификации. Он измеряет неравенство в предсказанных вероятностях положительного класса. Более высокий коэффициент Джини указывает на модель с лучшей предсказательной силой. Значения Джини варьируются от 0 до 1, где 1 соответствует идеальному прогнозу.

def gini(actual_val, pred_val, wt=1):
    '''Calculate Gini coefficient.
    
    Args:
        actual_val (array-like): Array of actual values.
        pred_val (array-like): Array of predicted values.
        wt (int or array-like, optional): Weight for each observation. Default is 1.
        
    Returns:
        float: Gini coefficient.
    '''
    temp_dat = pd.DataFrame({'Actual_Val': np.array(actual_val), 'Pred_Val': np.array(pred_val)})
    
    if isinstance(wt, int):
        temp_dat['wt'] = wt
    else:
        temp_dat['wt'] = wt.values
    
    temp_dat = temp_dat.sample(frac=1)
    temp_dat['Actual_Val'] = temp_dat['Actual_Val'] * temp_dat['wt']
    cnt_1 = temp_dat.groupby(['Pred_Val'], sort=True).sum()
    
    temp_dat['Actual_Val'] = wt - temp_dat['Actual_Val']
    cnt_2 = temp_dat.groupby(['Pred_Val']).sum()
    
    cnt_1_cum = np.cumsum(cnt_1.Actual_Val / sum(cnt_1.Actual_Val))
    Gini_y = 2 * cnt_1_cum - cnt_1.Actual_Val / sum(cnt_1.Actual_Val)
    Gini_x = cnt_2.Actual_Val / sum(cnt_2.Actual_Val)
    
    return 1 - sum(Gini_y * Gini_x)


def gini_evaluation(df, linear=0):
    '''Evaluate Gini coefficient.
    
    Args:
        df (DataFrame): Input dataframe containing relevant columns.
        linear (int, optional): Flag indicating linear calculation. Default is 0.
        
    Returns:
        float: Gini coefficient evaluation.
    '''
    cumacct = list(df['Cum_Pct_Cust'])[:-1]
    cumacct2 = [0] + cumacct[:-1]
    ginniVec = [i + j for i, j in zip(cumacct, cumacct2)]
    
    if linear == 1:
        ginniDist = list(df['Pct_Actual'])
    else:
        ginniDist = list(df['Pct_1'])
    
    ginniMetric = 1 - sum([i * j for i, j in zip(ginniVec, ginniDist)])
    return ginniMetric

Оценка производительности модели машинного обучения имеет решающее значение для обеспечения точных прогнозов и надежной информации. Понимая и вычисляя важные показатели, такие как KS, Gini может получить ценную информацию об эффективности своих моделей. Эти показатели обеспечивают количественную оценку производительности модели и помогают определить области для улучшения. Реализуя эти показатели в Python, вы можете легко оценивать свои модели и принимать обоснованные решения на основе их производительности.

В следующий раз мы поговорим о Log Loss, linscore, RMSE и о том, как рисовать графики проверки производительности в python.

Помните, что оценка модели — это повторяющийся процесс, и важно учитывать несколько показателей, чтобы получить полное представление о сильных и слабых сторонах модели. Экспериментируйте с различными метриками, интерпретируйте результаты и используйте их для уточнения и оптимизации моделей машинного обучения.

Удачного моделирования!