Test auf Normalverteilung | Mit Python-Skript testen

01/02/2023

ANNa-cropped

Bei einem Test auf die Normalverteilung der Residuen lässt sich erahnen, ob im vorliegenden Datensatz Ausreißer vorhanden sind. Bei einer linearen Regression nehmen wir an, dass die Residuen normalverteilt sind. Das spiegelt sich in zwei für den Test relevanten Größen wider:

(1) Schiefe = Maß der Symmetrie der Verteilung
(2) Kurtosis = Grad der Wölbung der Verteilung

Für den angewandten Jarque-Bera-Test wird es noch einen entsprechenden Theorie-Beitrag unter „Basics“ geben.

Für die Anwendung des Skripts wird eine Numpy-Matrix der OLS-Parameter sowie X und y benötigt (Theorie zur multiplen Regression).

Jarque-Bera-Test in Python

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2
from numpy.linalg import matrix_rank
import math
# Jarque-Bera-Test
# Test auf Normalverteilung der Residuen

def JB(type=0):
    
    # Gefittete Werte    
        
    fitted_values = X*OLS_parameters
    
    # Residuen
    
    residuals = y - fitted_values
    
    # Für die Darstellung in der Häufigkeitsverteilung
    
    residuals_in_array = numpyExtractor(residuals)
            
    # Für die Darstellung im Scatterplot 
    
    fitted_in_array = numpyExtractor(fitted_values)
    
    plt.hist(residuals_in_array,bins=10,density=True,edgecolor="#cccccc",color="#000000") 
    
    plt.title('Häufigkeitsverteilung der Residuen')
    
    plt.show()
            
    skewness = 0; 
    kurtosis = 0;
    
    for x in residuals: 
        
        skewness += (x**3)
        kurtosis += (x**4)
           
    estimated_variance_exp_3 = np.sqrt((np.transpose(residuals)*residuals)/(n-k))**3
    estimated_variance_exp_4 = np.sqrt((np.transpose(residuals)*residuals)/(n-k))**4
    
    S = skewness/estimated_variance_exp_3
    K = kurtosis/estimated_variance_exp_4
    
    print("Schiefe (S) beträgt " + str(S))
    print("Kurtosis (K) beträgt " + str(K))
    
    # Kompletter Test auf Symmetrie & Kurtosis
    
    TYPE0_JB_VALUE = (n-k)*((S**2/6)+((K-3)**2/24))
    
    # Ausschließlich Test auf breite Ränder
    
    TYPE1_JB_VALUE = (n-k)*((K-3)**2/24)
     
    # Kritischer Chi-Quadrat-Wert mit 2 Freiheitsgraden auf 5% Signifikanzniveau
    
    df2chi = chi2.isf(q=0.05, df=2)
    
    # Kritischer Chi-Quadrat-Wert mit 1 Freiheitsgrad auf 5% Signifikanzniveau
    
    df1chi = chi2.isf(q=0.05, df=1)
    
    # Kompletter JB-Test
    
    if (type==0):
        
        print("JB: " + str(TYPE0_JB_VALUE))
                      
        if (TYPE0_JB_VALUE > df2chi):
            print("Jarque-Bera-Wert ist größer als kritischer Wert. Hinweis auf Ausreißer!")
        
        if (TYPE0_JB_VALUE < df2chi):
            print("Jarque-Bera-Wert ist kleiner als kritischer Wert. Kein Hinweis auf Ausreißer!")
            
        return TYPE0_JB_VALUE
        
    # Ausschließlich Test auf breite Ränder

    if (type==1):
        
        print("JB (Breite Ränder): " + str(TYPE1_JB_VALUE))
                      
        if (TYPE1_JB_VALUE > df1chi):
            print("Jarque-Bera-Wert ist größer als kritischer Wert. Steilgipflig!")
        
        if (TYPE1_JB_VALUE < df1chi):
            print("Jarque-Bera-Wert ist kleiner als kritischer Wert. Flachgipflig!")
            
        return TYPE1_JB_VALUE