データ分析における「交絡因子」

データサイエンスもとい統計学においてその学問の醍醐味は因果関係を見つけて最適なモデルを作る事だと私は考えているのですが、そこには避けて通れないものとして「交絡因子」という考えがあります。
# 交絡因子とは
原因と結果の関係に影響を与え、真の関係と異なった観察結果をもたらす第三の因子の事を指します。
## 相関と因果
<B>相関では因果関係は語れません</B>が、相関には2種類あります。
- 因果のある相関
- 因果のない相関

ここで因果のない相関を分析する際に偏相関係数を使い疑似相関についてを過去に計算して発生しているか考察する記事を書きました。

https://qiita.com/murasaki1994/items/4cc1ba22fc9393b2e907

疑似相関では見かけ上の相関に対して第三の因子を考慮した偏相関係数を計算する事で考察しましたが、この言葉がまさしく交絡因子に似ている訳です。
例えばですが、有名な例で「アイスクリームの売上」と「溺死者数」は強い相関はありますが、当たり前ですが因果関係はありません。
それは「温度」という共通の因子がありこれによって見かけ上の相関が発生し、これが今回で言う交絡因子になります。
実際温度と溺死者数は温度が高ければ泳ぐ人が増えて因果があり、温度が上がればアイスを買う人も増えるという因果関係がありますね(自分は冬でも食べますけど)。
こんな感じで交絡因子が元々因果のない疑似相関に対して双方に因果のある相関をもたらすということがあります。

## ボストン住宅価格のデータセットで見てみる
因果のない相関である疑似相関は裏を返せば因果関係がどっちかは分からずとも交絡因子を見つける事ができる状態である事が分かります。
### 相関係数を降順で表示する関数
```Python3
import pandas as pd
def corr_sort(df):
    corr = df.corr().values
    dst = []
    for i in range(0, len(df.corr().columns)):
        for j in range(0, i):
            if i != j:
                dst.append([df.corr().columns[i], df.corr().columns[j], corr[i][j]])
    df_corr = pd.DataFrame(dst)
    df_corr.columns = ["因子1", "因子2", "相関係数"]
    return df_corr.sort_values("相関係数", ascending=False)
```

### 偏相関係数を算出する関数
```Python3
import pandas as pd
import numpy as np
def pcorr(df):
    pcor = []
    corr = df.corr()
    columns = df.corr().columns
    for i in range(len(columns)):
        for j in range(i+1, len(columns)):
            for k in range(len(columns)):
                if columns[i] != columns[k] and columns[j] != columns[k]:
                    xy = corr.loc[columns[i], columns[j]]
                    yz = corr.loc[columns[j], columns[k]] 
                    zx = corr.loc[columns[k], columns[i]]
                    pc = (xy - yz * zx) / (np.sqrt(1-yz**2) * np.sqrt(1-zx**2))
                    pcor.append([columns[i], 
                                columns[j], 
                                columns[k], 
                                corr.loc[columns[i], columns[j]],
                                pc,
                                abs(corr.loc[columns[i], columns[j]]-pc)])
    df_pcor = pd.DataFrame(pcor)
    df_pcor.columns = ["因子1", "因子2", "第三の因子", "相関係数", "偏相関係数", "偏相関係数と相関係数の差"]
    return df_pcor.sort_values("偏相関係数と相関係数の差", ascending=False)
```

### 強い相関について着目
ここで目的変数との因果関係を考察するための最初の段階としてPRICEとの相関係数に着目します。
```Python3
import pandas as pd

df = pd.read_csv("boston.csv")

df_corr = corr_sort(df)
df_corr[df_corr["因子2"]=="PRICE"]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/7770a042-5a45-328d-9428-ff7b3dc1ada9.png)
ここで非常に強い相関が現れているのはRMとPTRATIOとLSTATになります。

次に交絡因子に着目するためPRICEに対してどうなっているかを見てみます。
```Python3
df_pcorr = pcorr(df)
df_pcorr[df_pcorr["因子1"]=="PRICE"]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/b5687b22-ee3d-b5a1-1302-4d49a3019bbc.png)
次にRMとPTRATIOとLSTATについて着目します。
```Python3
df_pcorr[(df_pcorr["因子1"]=="PRICE") & (df_pcorr["因子2"]=="RM")]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/8764a5db-7bd7-ab60-0943-ce6a72afc93d.png)

```Python3
df_pcorr[(df_pcorr["因子1"]=="PRICE") & (df_pcorr["因子2"]=="PTRATIO")]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/ce611966-a945-fb82-668b-632314f724d7.png)

```Python3
df_pcorr[(df_pcorr["因子1"]=="PRICE") & (df_pcorr["因子2"]=="LSTAT")]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/9c952f1a-cc69-726f-5a39-0ee5c6871021.png)
これらの数値を見てみると強い相関が若干弱い相関に変わるだけでこれといった交絡因子とは言えそうにないです。

### 弱い相関について着目
ちょっと思ったような交絡因子が見つからないので今度は弱い相関に着目してみようと思います。
```Python3
df_pcorr[(df_pcorr["因子1"]=="PRICE") & (df_pcorr["因子2"]=="DIS")]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/d22446c6-597e-4dd9-d39e-d12e8982bebf.png)
PRICEとDISは弱い相関ではありますが正の相関に元々なっていましたが、LSTATが交絡因子になって実際には弱い負の相関になっていることが分かります。
ここで、3つの相関係数に着目してみます。
```Python3
pd.concat([df_corr[(df_corr["因子2"]=="PRICE") & (df_corr["因子1"]=="LSTAT")], df_corr[(df_corr["因子2"]=="PRICE") & (df_corr["因子1"]=="DIS")], df_corr[(df_corr["因子2"]=="DIS") & (df_corr["因子1"]=="LSTAT")]], axis=0)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/db7bfeca-afe1-0557-563e-5f9c3d8511c4.png)

この時、相関の関係性はこのようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/fe9d4180-8f86-8ba3-872d-4198c7d0b0fb.png)
つまりLSTATが今回交絡して相関の正負が変わった事が分かります。なのでDISとPRICEの関係性は正ではなく負だったという事です(これだけ小さいと誤差だけどね)。
### 疑似相関が一番現れている物を見つける
ここまで疑似相関と呼べるほどの物が無かったので説明変数で探します。
```Python3
df_pcorr
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/f761dc11-c1e0-ae30-f249-7e8928ca9108.png)
目的変数以外で説明変数間だとINDUSとRADについてTAXが交絡因子で実際には負の相関になっている事が分かります。
つまりINDUSとRADは本来正の相関ではなく負の相関になっており、INDUSとTAXおよびTAXとRAD間で因果を考察していくのが妥当ではないかと考えます。

## ここまでのまとめ
ボストン住宅価格のデータセットについて強い相関については偏相関係数も変わらず因果があると考えられ、弱い相関については正負は変わるが因果があると言えるほどの相関はない。
<b>そもそも相関で因果は語れない</b>けど。

## 交絡因子の制御方法
交絡はデータが集まってからは制御不可能になるためデータを集める段階や解析段階で制御する方法があります。
<table>
    <tr><td>時期</td><td>制御方法</td><td>実際の制御</td><td>利点</td><td>欠点</td></tr>
    <tr><td rowspan="3">計画段階</td><td>無作為割付<br>無作為化</td><td>曝露・非曝露(介入・非介入)を無作為に割り付ける</td><td>既知の交絡因子だけでなく、未知の因子も制御できる</td><td>介入研究でしか用いる事が出来ない(コホート研究や症例対象研究では不可能)</td></tr>
    <tr><td>限定</td><td>交絡因子1つの状態のみを観察対象にする</td><td>・完全な制御ができる<br>・容易で経費も掛からない<br>・解析も容易</td><td>結果の一般かに問題が残る<br>交絡因子の影響が残る事もある</td></tr>
    <tr><td>マッチング</td><td>2群で交絡因子の分布が等しくなるように対象者の設定を行う</td><td>・限定よりもサンプル数を大きくできるので精度の高い悔過が得られる<br>・したがって観察研究では限定よりも良い方法とされる</td><td>限定と比較して経費が必要<br>対象者の抽出が時に困難<br>マッチした項目が危険因子と関連している場合に危険因子として観察されなくなることがある</td></tr>
    <tr><td rowspan="2">解析段階</td><td>層化</td><td>交絡因子の相互と二階席を行う。あるいは層ごとの解析を統括する。</td><td>・前提が少なくて済む<br>・直感的で理論的な方法。計算も比較的容易</td><td>・標本サイズの制限から制御できる交絡因子の数が限られる<br>・数量データはカテゴリ化しないと層化できないので、この過程で情報の一部が失われる<br>・交絡因子の相加方法が恣意的に行えるため、結果の解釈が困難になることもある</td></tr>
    <tr><td>数学的モデリング</td><td>多変量解析を用いて因子間の影響を除去する</td><td>・サンプル数が小さくても適用可能<br>・個人のリスクの予想が可能<br>・数量データをそのまま用いることができる<br>・複数の因子を同時に制御できる</td><td>・モデルへ組み込むための前提がある<br>・モデルの選択が難しい<br>・結果の解釈が難しい</td></tr>
</table>

といった制御方法があります。
特に数学的モデルについてはなじみ深いので解析段階で対応するのが無難かもしれません。

# まとめ
データそのものを色々疑ったり、データの集め方までデータ分析は非常に奥が深い学問だなあと思います。
あとScikit-Learnのトイデータはこういった交絡になる疑似相関がほとんど見られないため非常に優秀なデータだと思います。

# 参考文献
<a href="https://www.igaku-shoin.co.jp/book/detail/108378">基礎から学ぶ 楽しい疫学　第4版</a>
【テックコラム】データ活用！相関関係と因果関係の違いと擬似相関について | DataCurrent
https://www.datacurrent.co.jp/column/correlation_causation20211109/