メインコンテンツへスキップ
見出し画像

書記が数学やるだけ#601 ロジスティック回帰,プロビット回帰

    ロジスティック回帰,プロビット回帰について実装例を示す。


    問題

    スクリーンショット 2022-10-22 13.36.09


    説明

    目的変数が2値変数の場合,ロジスティック回帰を用いることができる。これもGLMの一種として説明できる。なお,ロジット関数の代わりにプロビット関数を連結関数としたプロビットモデルも用いることができる。

    スクリーンショット 2022-10-22 13.39.04


    多カテゴリーの場合,順序があるかどうかでモデルが変わってくる。

    スクリーンショット 2022-10-22 13.39.47


    解答

    breast_cancerデータセットは,569データ,30の説明変数からなり,陰性か陽性かを目的変数とする。

    import math
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    from sklearn.datasets import load_breast_cancer
    from scipy.stats import logistic, norm, chi2
    import statsmodels.api as sm
    import statsmodels.formula.api as smf
    from statsmodels.formula.api import logit, probit
    from py4etrics.hetero_test import *
    %matplotlib inline
    
    data_breast_cancer = load_breast_cancer()
    df_target = pd.DataFrame(data_breast_cancer["target"], columns=["target"])
    df_data = pd.DataFrame(data_breast_cancer["data"], columns=data_breast_cancer["feature_names"])
    df = pd.concat([df_target, df_data], axis=1)
    df
    スクリーンショット 2022-10-22 13.42.28


    今回は「mean radius」から予測してみる。

    df1 = df[["mean radius","target"]]
    df1 = df1.rename(columns={'mean radius': 'mean_radius'})
    df1


    大体15を境に陰性と陽性が入れ替わっているように見える。

    sns.distplot(df1[df1["target"]==0]["mean_radius"],kde=False,rug=False)
    sns.distplot(df1[df1["target"]==1]["mean_radius"],kde=False,rug=False)
    画像5


    statsmodelsでは,glmのfamilyに2項分布を指定することでロジスティック回帰ができる。

    model_log = smf.glm(formula = " target ~ mean_radius ",
                    data = df1,
                    family = sm.families.Binomial()).fit()
    model_log.summary()
    スクリーンショット 2022-10-22 13.47.45


    なお,Logitを用いてfitを行なっても同様の結果が得られる。

    formula = 'target ~ mean_radius'
    model_logit = logit(formula, data=df1).fit()
    model_logit.summary()
    スクリーンショット 2022-10-22 13.48.55


    logitの代わりにprobitを指定することでプロビット回帰ができる。

    model_probit = probit(formula, data=df1).fit()
    model_probit.summary()
    スクリーンショット 2022-10-22 13.50.52


    予測結果をグラフに示すと,2つのモデルはよく似ていることがわかる。

    x_data=df1["mean_radius"]
    y_data=df1["target"]
    plt.scatter(x_data, y_data, s=5)
    x = np.linspace(5,30,100)
    y_logistic = logistic.cdf(-(1.0336)*x + 15.2459)
    y_norm = norm.cdf(-(1.0336)*x + 15.2459)
    plt.plot(x, y_logistic,label='Logistic')
    plt.plot(x, y_norm, label='Normal')
    plt.legend()
    plt.grid()
    画像9


    どちらのモデルを採用するか,対数尤度が一つの基準となる。

    model_logit.llf, model_probit.llf

    (-165.00542199378242, -165.425352019296)

    プロビットモデルの方が少し高いが,あまり差はないように見える。医療系であればオッズ比があるロジスティック回帰の方が馴染みやすいだろう。


    本記事のもくじはこちら:


    あなたへのおすすめ