Regressione binomiale negativa: A Step by Step Guide

Come fare la Regressione Binomiale Negativa in Python

Iniziamo importando tutti i pacchetti necessari.

import pandas as pd
from patsy import dmatrices
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt

In seguito, creiamo un DataFrame pandas per l’insieme di dati dei conteggi.

df = pd.read_csv('nyc_bb_bicyclist_counts.csv', header=0, infer_datetime_format=True, parse_dates=, index_col=)

Aggiungiamo alcune variabili di regressione derivate alla matrice X.

ds = df.index.to_series()
df = ds.dt.month
df = ds.dt.dayofweek
df = ds.dt.day

Non useremo la variabile Date come regressore poiché contiene un valore assoluto di data ma non abbiamo bisogno di fare nulla di speciale per eliminare Date poiché è già consumata come indice del DataFrame di pandas. Quindi non sarà disponibile per noi nella matrice X.

Creiamo i set di dati di allenamento e di test.

mask = np.random.rand(len(df)) < 0.8
df_train = df
df_test = df
print('Training data set length='+str(len(df_train)))
print('Testing data set length='+str(len(df_test)))

Passo 1: Ora configureremo e adatteremo il modello di regressione Poisson sul set di dati di allenamento.

Impostare l’espressione di regressione in notazione patsy. Stiamo dicendo a patsy che BB_COUNT è la nostra variabile dipendente e dipende dalle variabili di regressione: DAY, DAY_OF_WEEK, MONTH, HIGH_T, LOW_T e PRECIP.

expr = """BB_COUNT ~ DAY + DAY_OF_WEEK + MONTH + HIGH_T + LOW_T + PRECIP"""

Impostare le matrici X e y per i set di dati di allenamento e di test. patsy rende questo molto semplice.

y_train, X_train = dmatrices(expr, df_train, return_type='dataframe')
y_test, X_test = dmatrices(expr, df_test, return_type='dataframe')

Utilizzando la classe GLM di statsmodels, addestrate il modello di regressione di Poisson sul set di dati di allenamento.

poisson_training_results = sm.GLM(y_train, X_train, family=sm.families.Poisson()).fit()

Questo finisce l’addestramento del modello di regressione di Poisson. Per vedere il risultato dell’addestramento, è possibile stampare il riepilogo dell’addestramento.

print(poisson_training_results.summary())

Questo stampa quanto segue:

Riassunto dell’addestramento per il modello di regressione di Poisson (Immagine dell’autore)

Il nostro vero interesse è il vettore dei tassi montati λ prodotto dall’addestramento. Questo vettore di tassi è contenuto nel parametro poisson_training_results.mu.

print(poisson_training_results.mu)
print(len(poisson_training_results.mu))

Il seguente output mostra i primi e gli ultimi valori del vettore λ montato:


Questo completa lo STEP1: adattare il modello di regressione Poisson.

STEP 2: Ora adatteremo il modello ausiliario di regressione OLS sul set di dati e useremo il modello montato per ottenere il valore di α.

Importiamo il pacchetto api.

import statsmodels.formula.api as smf

Aggiungiamo il vettore λ come una nuova colonna chiamata ‘BB_LAMBDA’ al Data Frame del set di dati di allenamento. Ricordate che le dimensioni di λ sono (n x 1). Nel nostro esempio sarà (161 x 1). Ricordiamo anche che il vettore λ è disponibile in poisson_training_results.mu :

df_train = poisson_training_results.mu

In seguito, aggiungiamo una colonna derivata chiamata ‘AUX_OLS_DEP’ al Data Frame di pandas. Questa nuova colonna memorizzerà i valori della variabile dipendente della regressione OLS. È il lato sinistro dell’equazione di regressione OLS qui sotto:

Regressione OLS ausiliaria per trovare α per il modello NB2 (Immagine dell’autore)
df_train = df_train.apply(lambda x: ((x - x)**2 - x) / x, axis=1)

Nello snippet di codice qui sopra, la parte in grassetto è il lato sinistro dell’equazione aux OLSR qui sopra.

Utilizziamo patsy per formare la specifica del modello per l’OLSR. Vogliamo dire a patsy che AUX_OLS_DEP è la variabile dipendente ed è spiegata da BB_LAMBDA (che è il vettore dei tassi λ). Il ‘-1’ alla fine dell’espressione è la sintassi di patsy per dire: non usare un’intercetta di regressione; cioè basta adattare una linea retta passante per l’origine, come suggerito dai signori Cameron e Trivedi.

ols_expr = """AUX_OLS_DEP ~ BB_LAMBDA - 1"""

Siamo ora pronti per adattare un modello OLSR.

Configura e adatta il modello OLSR:

aux_olsr_results = smf.ols(ols_expr, df_train).fit()

Stampa i parametri di regressione:

print(aux_olsr_results.params)

Vedrai il seguente coefficiente singolo stampato corrispondente alla singola variabile di regressione BB_LAMBDA. Questo coefficiente è l’α che stavamo cercando:

BB_LAMBDA 0.037343

È α statisticamente significativo?

Ora dobbiamo rispondere a una domanda molto importante. Questo valore di α (0,037343) è statisticamente significativo? O può essere considerato zero a tutti gli effetti?

Perché è così importante scoprirlo? Ricordiamo che se α è zero, allora la seguente equazione:

La funzione di varianza del modello NB2 (Image by Author)

…si riduce a Varianza = media. Questa è la funzione di varianza del modello di regressione Poisson.

Se il valore di α non è statisticamente significativo, allora il modello di regressione binomiale negativa non può fare un lavoro migliore di un modello di regressione Poisson per adattare il set di dati di allenamento.

L’oggetto OLSResults contiene il t-score del coefficiente di regressione α. Stampiamolo:

aux_olsr_results.tvalues

Questo stampa:

BB_LAMBDA 4.814096

Da un calcolatore di valori t, possiamo vedere che il valore t critico ad un livello di confidenza del 99% (coda destra), e gradi di libertà=(172 osservazioni) -( 6 variabili di regressione)- (1 parametro di dispersione α)=165 è 2.34916. Questo è comodamente inferiore alla statistica t di α che era 4,814096. Concludiamo che,

α=0,037343 è statisticamente significativo.

Questo completa lo STEP 2: La determinazione di α.

STEP 3: Forniamo il valore di alfa trovato nello STEP 2 nella classe statsmodels.genmod.families.family.NegativeBinomial, e addestriamo il modello NB2 sul set di dati di allenamento.

Questa è un’operazione di un solo passo in statsmodels:

nb2_training_results = sm.GLM(y_train, X_train,family=sm.families.NegativeBinomial(alpha=aux_olsr_results.params)).fit()

Come prima, stamperemo il riassunto dell’allenamento:

print(nb2_training_results.summary())

Che stampa il seguente riassunto:

Riepilogo dell’allenamento del modello NB2 (Immagine dell’autore)

PASSO 4: Facciamo qualche previsione usando il nostro modello NB2 allenato.

La previsione è di nuovo una procedura a passo singolo in statsmodels:

nb2_predictions = nb2_training_results.get_prediction(X_test)

Stampiamo le previsioni:

predictions_summary_frame = nb2_predictions.summary_frame()
print(predictions_summary_frame)

Seguono le prime righe dell’output:

Prime righe di output da nb2_predictions.summary_frame() (Image by Author)

Tracciamo anche i conteggi previsti rispetto a quelli reali per i dati di test.

predicted_counts=predictions_summary_frameactual_counts = y_testfig = plt.figure()fig.suptitle('Predicted versus actual bicyclist counts on the Brooklyn bridge')predicted, = plt.plot(X_test.index, predicted_counts, 'go-', label='Predicted counts')actual, = plt.plot(X_test.index, actual_counts, 'ro-', label='Actual counts')plt.legend(handles=)plt.show()

Ecco il risultato:

Conteggio previsto rispetto a quello effettivo dei ciclisti sul ponte di Brooklyn utilizzando il modello NB2

Non male! Il modello NB2 sembra seguire più o meno la tendenza dei conteggi delle biciclette. E proprio come per le prestazioni del modello di regressione di Poisson, in alcuni casi le sue previsioni sono molto lontane dai valori reali.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.