[PYTHON] [Lineare Regression] Über die Anzahl der erklärenden Variablen und den (angepassten Freiheitsgrad) Bestimmungskoeffizienten

zunaechst

Der Autor beschreibt die erklärenden Variablen der linearen Regression. "Es ist besser, keine Variablen zu verwenden, die nicht mit der Zielvariablen zusammenhängen, um zu lernen" (* 1) Ich habe das Bild. Während des Studiums der linearen Regressionsanalyse Ich habe gelernt, dass der Bestimmungskoeffizient die folgenden Eigenschaften hat.

"Wenn eine erklärende Variable hinzugefügt wird, ist es unwahrscheinlich, dass der Bestimmungskoeffizient niedriger ist als vor der Hinzufügung. (Daher verwendet der Genauigkeitsvergleich von Modellen mit unterschiedlicher Anzahl erklärender Variablen den" freiheitsangepassten Bestimmungskoeffizienten ". ) ”(* 2)

In Kenntnis seiner Eigenschaften wollte der Autor Folgendes überprüfen [Zusammenfassung].

Überblick

In Bezug auf die Annahme des Autors (* 1) und die Art des Bestimmungskoeffizienten (* 2) habe ich versucht, die folgenden zwei Punkte (①, ②) zu verifizieren (indem ich tatsächlich ein Modell erstellt habe). Dieser Artikel beschreibt die Überprüfungsmethode und die Ergebnisse.

① Vergleich der Entscheidungskoeffizienten → Wenn eine erklärende Variable hinzugefügt wird, die nicht mit der Zielvariablen zusammenhängt, fällt ihr Bestimmungskoeffizient vor der Addition nicht unter den Bestimmungskoeffizienten.

(2) Vergleich freiheitsangepasster Entscheidungskoeffizienten → Ist beim gradbereinigten Bestimmungskoeffizienten der Wert nicht "vor dem Hinzufügen" einer Variablen höher, die nicht mit der Zielvariablen zusammenhängt?

Annahme

[Lineare Regression] Ein Verfahren zum Ausdrücken der Zielvariablen durch "Verbindung erster Ordnung (lineare Verbindung) der erklärenden Variablen" in Bezug auf die vorhandenen erklärenden Variablen und Zielvariablen. Da es durch eine lineare Verbindung ausgedrückt wird, ist das ausgedrückte Ergebnis (geschätzter Wert) ein gerader Graph. Normdist_regression.png

[Entscheidungsfaktor] Das erstellte lineare Regressionsmodell ist ein Index, der zeigt, "wie gut die Anpassung für die Daten ist" und durch die folgende Formel ausgedrückt wird.  $ R^{2}=1-\dfrac {\sum e^{2}}{\sum \left( y-\overline {y}\right) ^{2}} $

$ {\ sum e ^ {2}}: Restvariation (Summe der Differenzquadrate zwischen Zielvariable und Schätzwert) $ $ {\ sum \ left (y- \ override {y} \ right) ^ {2}}: Gesamtvariation (Summe der Differenzquadrate zwischen der Zielvariablen und ihrem Mittelwert) $

[Entscheidungsfaktor angepasst an die Freiheit] Ein Index, der die Anzahl der erklärenden Variablen (k) zum Bestimmungskoeffizienten addiert. Wie beim Entscheidungskoeffizienten gibt es an, "wie gut die Anpassung für die Daten ist".  $ {\widehat {R}^{2}}=1-\dfrac {n-1}{n-k}\left( 1-R^{2}\right) $

$ {n}: Anzahl der Daten $ $ {k}: Anzahl der erklärenden Variablen $

Details zur Überprüfung

Die beiden in der obigen [Zusammenfassung] beschriebenen Verifizierungspunkte (① und ②) werden mit den folgenden Methoden verifiziert.

[Daten vorzubereiten] (1) Erklärende Variable (bezogen auf die Zielvariable) → Mit Zufallszahlen erstellt. Die Zielvariable wird durch die lineare Kombination dieser Variablen erstellt. (2) Erklärungsvariable (unabhängig von der Zielvariablen) → Mit Zufallszahlen erstellt. (3) Zielvariable → Erstellen Sie eine Kombination der erklärenden Variablen in (1) oben erster Ordnung.

① Vergleich der Entscheidungskoeffizienten → Überprüfen Sie die Differenz zwischen den Bestimmungskoeffizienten von <Modell 1> und <Modell 2> unten (Modell 2 - Modell 1). <Modell 1> (n) Modell erstellt mit Variablen (1 bis n) der obigen Variablen (1) <Modell 2> (n x m) Für ein [Modell 1] oben Modell erstellt mit "erklärenden Variablen für das Modell" und "über Variablen (2) (1 bis m)"

(2) Vergleich freiheitsangepasster Entscheidungskoeffizienten → Stellen Sie für die obige Überprüfung (1) den "Entscheidungskoeffizienten" auf den "freiheitsgradangepassten Entscheidungskoeffizienten" ein und bestätigen Sie.

Überprüfungsverfahren

(1) Erklärende Variable (bezogen auf die Zielvariable)   → col_rel_[n](n=0〜10) (2) Erklärungsvariable (unabhängig von der Zielvariablen)   → col_no_rel_[m](m=0〜10) (3) Zielvariable   → target

[2] Modellerstellung → Erstellen Sie oben <Modell 1> und <Modell 2>.

<Modell 1> (n)   → nothing_ [n] _ [m]

[3] Berechnung des Entscheidungskoeffizienten und des an den Freiheitsgrad angepassten Entscheidungskoeffizienten → Halten Sie beide Werte als Diktattyp (als Wert). Jeder Diktatname lautet wie folgt.

Entscheidungsfaktor: dict_R2 Freiheitsgrad angepasster Entscheidungskoeffizient: dict_adjusted_R2

[4] Kombinieren Sie die aggregierten Ergebnisse in einem Datenrahmen [5] Erstellen Sie zwei Falzliniendiagramme → Die vertikale Achse ist der Bestimmungskoeffizient (angepasst an die Freiheit), Die horizontale Achse ist "die Anzahl der oben genannten Variablen (2), die für das Modelltraining verwendet werden".

Verifizierungs-Schlüssel

experiment.jpynb


import random

import numpy as np
import pandas as pd

import matplotlib.pyplot as  plt

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

#[Parameter]
#Startwert
random.seed(10)

#Anzahl der Daten
data_num = 10 ** 4

#Anzahl der Teile(rel:Bezogen auf die Zielvariable Nr_rel:Nicht in Bezug auf die Zielvariable)
group_num = 10

dict_group_num = dict()
dict_group_num["rel"] = group_num #Bezogen auf die Zielvariable
dict_group_num["no_rel"] = group_num #Nicht in Bezug auf die Zielvariable

#[Datenerstellung]
#Erklärende Variable
col_format = 'col_{group}_{index}'

all_data = pd.DataFrame({
    col_format.format(
        group = key
        , index = i
    ):[random.randint(0 , 1000) for _ in range(10 ** 4)] 
    for key , val in dict_group_num.items()
    for i in range(val)
})

#Objektive Variable
w_list = [random.randint(1 , 10) for i in range(dict_group_num["rel"])]
target_series = pd.Series(np.zeros(data_num))
for i in range(dict_group_num["rel"]):
    w = w_list[i]
    col = col_format.format(
        group = "rel"
        , index = i
    )
    
    #Bestätigung
    print('-' * 50)
    print(target_series.head())
    print("w=" , w)
    print(all_data[col].head())
    print(w * all_data[col].head())    
    
    target_series = target_series + w * all_data[col]

    #Bestätigung
    display(target_series.head())
    
all_data['target'] = target_series

#[Modellerstellung]
#Alle Kombinationen erklärender Variablen
dict_features = {}
key_format = "{type_}_{n}_{m}"

#1.「col_rel_x」(n)
type_ = "nothing"
for n in range(dict_group_num["rel"]):
    cols = [col_format.format(
                group = "rel"
                , index = i
            ) for i in range(n+1)]
    
    key = key_format.format(
        type_ = type_
        , n = n + 1
        , m = 0
    )
    dict_features[key] = cols

#2.「col_rel_x」(n)Und "col_no_rel_x」(m)
type_ = "contain"
for n in range(dict_group_num["rel"]):
    cols_rel = [col_format.format(
                group = "rel"
                , index = i
            ) for i in range(n+1)]
    for m in range(dict_group_num["no_rel"]):
        cols_no_rel = [col_format.format(
                    group = "no_rel"
                    , index = i
                ) for i in range(m+1)]
        cols = cols_rel + cols_no_rel
        key = key_format.format(
            type_ = type_
            , n = n + 1
            , m = m + 1
        )
        dict_features[key] = cols

#Bestätigung
type_ = "nothing"
print("-" * 50 , type_)
_dict = {key:val for key , val in dict_features.items() if key[:len(type_)] == type_}
print(list(_dict.items())[:5])

type_ = "contain"
print("-" * 50 , type_)
_dict = {key:val for key , val in dict_features.items() if key[:len(type_)] == type_}
print(list(_dict.items())[:5])

#Modellieren
dict_models = {}
for key , feature_cols in dict_features.items():
    #Teilen Sie in erklärende Variablen und objektive Variablen
    train_X = all_data[feature_cols] 
    train_y = all_data['target']
    #Modellieren
    model = LinearRegression()
    model.fit(train_X , train_y)
    
    dict_models[key] = model
    
    #Bestätigung
    print("-" * 50)
    print("key={}".format(key))
    print(model.intercept_)
    print(model.coef_)

#Bestätigung
list(dict_models.keys())[:5]

#Entscheidungskoeffizient, Freiheitsgrad angepasster Entscheidungskoeffizient
dict_R2 = {}
dict_adjusted_R2 = {}

for key , feature_cols in dict_models.items():
    #Modellakquisition
    model = dict_models[key]
    
    #Extrahieren Sie alle Daten(numpy)
    feature_cols = dict_features[key]
    X = np.array(all_data[feature_cols])
    y = np.array(all_data["target"])
    
    #Entscheidungskoeffizient
    R2 = model.score(X , y)
    dict_R2[key] = R2
    
    #Freiheitsgrad angepasster Entscheidungskoeffizient
    n = data_num
    k = int(key.split("_")[1]) + int(key.split("_")[2])
    adjusted_R2 = 1 - ((n-1)/(n-k)) * (1 - R2)
    dict_adjusted_R2[key] = adjusted_R2

#【Prüfergebnis】
R2_df = pd.DataFrame({
    "key":list(dict_R2.keys())
    , "R2":list(dict_R2.values())
})
adjusted_R2_df = pd.DataFrame({
    "key":list(dict_adjusted_R2.keys())
    , "adjusted_R2":list(dict_adjusted_R2.values())
})
result_df = pd.merge(R2_df , adjusted_R2_df , on="key" , how='outer')
result_df['rel_num'] = result_df["key"].str.split("_" , expand=True)[1].astype(int)
result_df['no_rel_num'] = result_df["key"].str.split("_" , expand=True)[2].astype(int)

#Bestätigung
print(len(R2_df))
print(len(adjusted_R2_df))
print(len(result_df))
display(R2_df.head())
display(adjusted_R2_df.head())
display(result_df.head())

#[Grafikerstellung]
#Entscheidungskoeffizient
value = "R2"
fig = plt.figure(figsize=(10,10))

for i in range(dict_group_num["rel"]):
    rel_num = i + 1
    df = result_df.query("rel_num == {}".format(rel_num))
    base = df.query("no_rel_num == 0")[value]
    x = df["no_rel_num"]
    y = df[value].apply(lambda x:x - base)
    
    #Bestätigung
#     print("-" * 50)
#     print("base={}".format(base))
#     print("x={}".format(x))
#     print("y={}".format(y))
    
    plt.plot(x, y, marker = 'o' 
             , label="rel_num={}".format(rel_num))

plt.title("Diff of {}".format(value))
plt.legend(loc="upper left" , bbox_to_anchor=(1, 1))
plt.xlabel("no_rel_num")
plt.ylabel(value)
plt.grid()
plt.show()

#Grafik speichern
fig.savefig("plot_R2.png ")

#Freiheitsgrad angepasster Entscheidungskoeffizient
value = "adjusted_R2"
fig = plt.figure(figsize=(10,10))

for i in range(dict_group_num["rel"]):
    rel_num = i + 1
    df = result_df.query("rel_num == {}".format(rel_num))
    base = df.query("no_rel_num == 0")[value]
    x = df["no_rel_num"]
    y = df[value].apply(lambda x:x - base)
    
    #Bestätigung
#     print("-" * 50)
#     print("base={}".format(base))
#     print("x={}".format(x))
#     print("y={}".format(y))
    
    plt.plot(x, y, marker = 'o' 
             , label="rel_num={}".format(rel_num))

plt.title("Diff of {}".format(value))
plt.legend(loc="upper left" , bbox_to_anchor=(1, 1))
plt.xlabel("no_rel_num")
plt.ylabel(value)
plt.grid()
plt.show()

#Grafik speichern
fig.savefig("plot_adjusted_R2.png ")

Prüfergebnis

[Grafik 1] Entscheidungskoeffizient Unabhängig von der Anzahl der erklärenden Variablen (rel_num) von "bezogen auf die Zielvariable" steigt der Entscheidungskoeffizient monoton an, wenn die Anzahl der hinzuzufügenden erklärenden Variablen "unabhängig von der Zielvariablen" zunimmt. Mit anderen Worten wurde bestätigt, dass es mit der Theorie übereinstimmte. plot_R2.png [Grafik 2] Freiheitsbereinigter Entscheidungskoeffizient Über die Anzahl der erklärenden Variablen von "bezogen auf die Zielvariable" Bei 1 bis 4 ist es besser, die erklärende Variable "nicht mit der Zielvariablen verbunden" hinzuzufügen. (1 bis 4 reichen nicht aus, um es zu erklären, und es scheint besser, auch nur ein paar Informationen hinzuzufügen.) Wenn es 9 bis 10 ist, ist es fast das gleiche. (Es scheint, dass 9 bis 10 ausreichen, um die Zielvariable zu erklären.) Andererseits ist im Fall von 5 bis 8 der Entscheidungskoeffizient höher, wenn die erklärende Variable "für die Zielvariable irrelevant" nicht hinzugefügt wird. Es wurde bestätigt, dass es wie vom Autor erwartet war. plot_adjusted_R2.png

Zusammenfassung

Beim Vergleich von Modellen mit Entscheidungskoeffizienten muss auf die Anzahl der für das Training verwendeten erklärenden Variablen geachtet werden. Wie aus den Überprüfungsergebnissen bestätigt werden kann, ist der Entscheidungskoeffizient im Entscheidungskoeffizienten hoch, wenn die erklärenden Variablen "einschließlich des anderen Teils eine große Anzahl" aufweisen (selbst wenn Variablen hinzugefügt werden, die nicht zur Verwendung geeignet sind). Oder gleich. Um in diesem Fall einen angemesseneren Vergleich zu ermöglichen, erscheint es daher besser, den "an den Freiheitsgrad angepassten Bestimmungskoeffizienten" zu verwenden.

Recommended Posts

[Lineare Regression] Über die Anzahl der erklärenden Variablen und den (angepassten Freiheitsgrad) Bestimmungskoeffizienten
Über die Normalgleichung der linearen Regression
Überprüfen Sie das Konzept und die Terminologie der Regression
Bewertungsmethode des Regressionsproblems des maschinellen Lernens (mittlerer quadratischer Fehler und Entscheidungskoeffizient)
Über das Verhalten von copy, deepcopy und numpy.copy
"Lineare Regression" und "Probabilistische Version der linearen Regression" in Python "Bayes lineare Regression"
Beziehung der Fibonacci-Zahlenreihe und des Goldenen Schnitts
Python-Implementierung der Bayes'schen linearen Regressionsklasse
Denken Sie an das Rack und WSGI der nächsten Generation
Persönliche Hinweise zur Integration von vscode und anaconda