0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

因果でも相関でもない分析「性質」

Last updated at Posted at 2024-05-04

注意 今までで一番駄記事かもしれません
因果推論では質的変数を使って介入別の目的となる変数の平均値を使って効果測定をします。
相関では二変数間の関係性の分析だったり見かけ上の相関を考察する疑似相関があります。
と、今回はそれらとも違う、それでいて因果推論や相関よりエビデンスレベルが高いわけではない、しかし無意味ではない分析として「性質」の分析をしてみようと思います。

内容としては、クラス別に重回帰分析を行い、その係数から目的変数において傾向がどう違うかを解釈するという内容とデータ構造そのものの違いを解釈するといった内容です。

コーディング

ライブラリのインポート

import statsmodels.api as sm
import pandas as pd
import numpy as np

データの読み込み

ここでは初めから標準化されている糖尿病データセットを使います。

df = pd.read_csv("diabetes.csv")
df.head()

image.png

多重共線性の確認

VIFを計算して10を超える項目を探し後に削除します。

y = df["y"]
x = df.drop("y", axis=1)
vif = np.diag(np.linalg.inv(x.corr().values))
df_vif = pd.DataFrame(vif)
df_vif.columns = ["VIF"]
df_vif.index = x.columns
df_vif.sort_values("VIF", ascending=False)

image.png

この結果から「s1」「s2」「s3」「s5」は削除します。

df = df.drop(["s1", "s2", "s3", "s5"], axis=1)

クラス別データを作る

ここでは男女によってデータに違いがあるかを考察します。

クラスの値を見る

標準化されているのでちゃんと値を確認します。

list(set(df["sex"].values))
[0.050680119, -0.044641637]

この値を基にクラス分けします。

クラス分け

df1 = df[df["sex"]==0.050680119]
df0 = df[df["sex"]==-0.044641637]

これによって男女を分ける事ができました。

説明変数と目的変数を分ける

注意点として性別で分けているので「sex」も排除します。

x1 = df1.drop(["y", "sex"], axis=1)
x0 = df0.drop(["y", "sex"], axis=1)
y1 = df1["y"]
y0 = df0["y"]

クラス1と思われるデータの重回帰分析

model1 = sm.OLS(y1, x1).fit()
model1.summary()

image.png

R2は低いですが、今回は係数が見たいので・・・

クラス0と思われるデータの重回帰分析

model0 = sm.OLS(y0, x0).fit()
model0.summary()

image.png

比較

ではここまで出た係数を比較します。

coef = []
for i in range(len(model0.params)):
    coef.append([x0.columns[i], model0.params[i], model1.params[i], abs(model0.params[i]-model1.params[i])])
df_coef = pd.DataFrame(coef)
df_coef.columns = ["coef_name", "class0", "class1", "diff"]
df_coef.sort_values("diff", ascending=False)

image.png

この結果から考えると糖尿病の進行に対して男女では特に年齢やs4とBMIに違いがある事が分かります。

各変数の男女差

図示

では実際変数はどんな違いがあるかを見てみます。

for col in x1.columns:
    plt.boxplot([x1[col], x0[col]], labels=[col+"1", col+"0"], positions=[0, 1])
    plt.plot([0, 1], [x1[col].mean(), x0[col].mean()], marker="x")
    plt.show()

Untitled.png
Untitled-2.png
Untitled.png

Untitled-2.png
Untitled.png

要約統計量

次に具体的な値を見てみます。

dcb = pd.concat([x1.describe(), x0.describe()], axis=1)
dcb

image.png
標準化しているというのもあると思いますが、違いは小さいです。しかし確実に違うところもあります。
元のデータだとどうなっているか気になる所です。
ただ全体的にクラス1の方が平均値が高い傾向にあるようです。

まとめ

というあまり意味が感じられない分析手法でした(こういうのは試してみないとわからない)。
因果より相関より弱いとのことですが、ただ確かに性質が違えばデータへの見方が変わるのでそこは一応記憶の片隅に置いておこう。
ただこれ、yの値にもよるから難しい(あくまで目的変数に与える影響なので)、確かにエビデンスレベルが低いのも納得。
でも機械学習をする上では効果があるかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?