Calcolare la statistica KS con Python

La statistica Kolmogorov-Smirnov (KS) è una delle metriche più importanti utilizzate per la convalida dei modelli predittivi. È ampiamente utilizzato nel dominio BFSI. Se fai parte di un team di analisi di rischio o di marketing che lavora su un progetto nel settore bancario, devi aver sentito parlare di questa metrica.

Che cos’è la statistica KS?

Sta per Kolmogorov-Smirnov che prende il nome da Andrey Kolmogorov e Nikolai Smirnov. Confronta le due distribuzioni cumulative e restituisce la massima differenza tra di esse. È un test non parametrico, il che significa che non è necessario testare alcuna ipotesi relativa alla distribuzione dei dati. Nel test KS, l’ipotesi nulla afferma che entrambe le distribuzioni cumulative sono simili. Rifiutare l’ipotesi nulla significa che le distribuzioni cumulative sono diverse.

Nella scienza dei dati, confronta la distribuzione cumulativa di eventi e non eventi e KS è dove c’è una differenza massima tra le due distribuzioni. In parole semplici, ci aiuta a capire quanto bene il nostro modello predittivo è in grado di discriminare tra eventi e non-eventi.

Supponiamo che stiate costruendo un modello di propensione in cui l’obiettivo è quello di identificare i potenziali acquirenti di un particolare prodotto. In questo caso, la variabile dipendente (obiettivo) è in forma binaria che ha solo due risultati: 0 (non evento) o 1 (evento). “Evento” significa persone che hanno acquistato il prodotto. “Non evento” si riferisce alle persone che non hanno acquistato il prodotto. La statistica KS misura se il modello è in grado di distinguere tra prospect e non prospect.

Due modi per misurare la statistica KS

Metodo 1: Metodo dei decili

Questo metodo è il modo più comune per calcolare la statistica KS per validare il modello predittivo binario. Vedere i passi qui sotto.

  1. È necessario avere due variabili prima di calcolare KS. Una è la variabile dipendente che dovrebbe essere binaria. La seconda è il punteggio di probabilità previsto che è generato dal modello statistico.
  2. Creare decili basati sulle colonne di probabilità previste che significa dividere la probabilità in 10 parti. Il primo decile dovrebbe contenere il punteggio di probabilità più alto.
  3. Calcolare la % cumulativa di eventi e non eventi in ogni decile e poi calcolare la differenza tra queste due distribuzioni cumulative.
  4. KS è dove la differenza è massima
  5. Se KS è nel primo 3 decile e il punteggio è superiore a 40, è considerato un buon modello predittivo. Allo stesso tempo è importante convalidare il modello controllando anche altre metriche di performance per confermare che il modello non soffre di un problema di overfitting.

KS Python

Python : KS Statistics Decile Method

Importa dati e librerie richieste

Ho preparato un esempio di dati. Il set di dati contiene due colonne chiamate y e p.yè una variabile dipendente.psi riferisce alla probabilità prevista.

import pandas as pdimport numpy as npdf = pd.read_csv("https://raw.githubusercontent.com/deepanshu88/data/master/data.csv")
Funzione Python per la statistica KS
def ks(data=None,target=None, prob=None): data = 1 - data data = pd.qcut(data, 10) grouped = data.groupby('bucket', as_index = False) kstable = pd.DataFrame() kstable = grouped.min() kstable = grouped.max() kstable = grouped.sum() kstable = grouped.sum() kstable = kstable.sort_values(by="min_prob", ascending=False).reset_index(drop = True) kstable = (kstable.events / data.sum()).apply('{0:.2%}'.format) kstable = (kstable.nonevents / data.sum()).apply('{0:.2%}'.format) kstable=(kstable.events / data.sum()).cumsum() kstable=(kstable.nonevents / data.sum()).cumsum() kstable = np.round(kstable-kstable, 3) * 100 #Formating kstable= kstable.apply('{0:.2%}'.format) kstable= kstable.apply('{0:.2%}'.format) kstable.index = range(1,11) kstable.index.rename('Decile', inplace=True) pd.set_option('display.max_columns', 9) print(kstable) #Display KS from colorama import Fore print(Fore.RED + "KS is " + str(max(kstable))+"%"+ " at decile " + str((kstable.index==max(kstable)]))) return(kstable)
Come usare la funzione
mydf = ks(data=df,target="y", prob="p")
  1. data si riferisce al dataframe pandas che contiene sia la variabile dipendente che i punteggi di probabilità.
  2. target si riferisce al nome della colonna della variabile dipendente
  3. prob si riferisce al nome della colonna della probabilità prevista
Output

Restituisce le informazioni di ogni decile in formato tabulare e stampa anche il punteggio KS sotto la tabella. Genera anche la tabella in un nuovo dataframe.

 min_prob max_prob events nonevents event_rate nonevent_rate \Decile 1 0.298894 0.975404 49 51 49.00% 5.67% 2 0.135598 0.298687 19 81 19.00% 9.00% 3 0.082170 0.135089 14 86 14.00% 9.56% 4 0.050369 0.082003 10 90 10.00% 10.00% 5 0.029415 0.050337 5 95 5.00% 10.56% 6 0.018343 0.029384 1 99 1.00% 11.00% 7 0.011504 0.018291 1 99 1.00% 11.00% 8 0.006976 0.011364 1 99 1.00% 11.00% 9 0.002929 0.006964 0 100 0.00% 11.11% 10 0.000073 0.002918 0 100 0.00% 11.11% cum_eventrate cum_noneventrate KS Decile 1 49.00% 5.67% 43.3 2 68.00% 14.67% 53.3 3 82.00% 24.22% 57.8 4 92.00% 34.22% 57.8 5 97.00% 44.78% 52.2 6 98.00% 55.78% 42.2 7 99.00% 66.78% 32.2 8 100.00% 77.78% 22.2 9 100.00% 88.89% 11.1 10 100.00% 100.00% 0.0 KS is 57.8% at decile 3
Metodo 2: KS Two Sample Test

Utilizzando la libreriascipypython, possiamo calcolare la statistica KS a due campioni. Ha due parametri – data1 e data2. In data1, inseriremo tutti i punteggi di probabilità corrispondenti ai non-eventi. In dati2, prenderà i punteggi di probabilità contro gli eventi.

from scipy.stats import ks_2sampdf = pd.read_csv("https://raw.githubusercontent.com/deepanshu88/data/master/data.csv")ks_2samp(df.loc, df.loc)

Ritorna il punteggio KS 0,6033 e il p-value inferiore a 0,01 che significa che possiamo rifiutare l’ipotesi nulla e concludere che la distribuzione degli eventi e dei non eventi è diversa.

OutputKs_2sampResult(statistic=0.6033333333333333, pvalue=1.1227180680661939e-29)
Nota importante

Il punteggio KS del metodo 2 è leggermente diverso dal metodo 1 poiché il secondo è calcolato a livello di riga e il primo è calcolato dopo la conversione dei dati in dieci parti.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.