LiNGAMを活用して因果関係を明確に視覚化する非常に実践的な例

今回はNetworkXを使ってDAGを描画する方法をご紹介します。以下のコードは、NetworkXを直接利用して因果関係をグラフとして描画する例です。

import numpy as np

import pandas as pd

import networkx as nx

import matplotlib.pyplot as plt

 

# データ生成

np.random.seed(42)

n_samples = 300

temperature = np.random.uniform(20, 40, n_samples)

ice_cream_sales = temperature + np.random.normal(0, 2, n_samples)

swimming_accidents = temperature + np.random.normal(0, 1, n_samples)

data = pd.DataFrame({

    'Temperature': temperature,

    'IceCreamSales': ice_cream_sales,

    'SwimmingAccidents': swimming_accidents

})

 

# DAGのエッジを直接指定

edges = [

    ("Temperature", "IceCreamSales"),

    ("Temperature", "SwimmingAccidents")

]

 

# NetworkXグラフの作成

G = nx.DiGraph()

G.add_edges_from(edges)

 

# グラフの描画

plt.figure(figsize=(8, 6))

pos = nx.spring_layout(G, seed=42)  # ノードの位置を決定

nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, font_weight='bold', arrowsize=20)

 

plt.title("Causal DAG")

plt.show()

出力結果




次のコードは、DirectLiNGAMを活用して因果関係を明確に視覚化する非常に実践的な例です。

import numpy as np

import pandas as pd

import networkx as nx

import matplotlib.pyplot as plt

from lingam import DirectLiNGAM

 

# データ生成

np.random.seed(42)

n_samples = 300

temperature = np.random.uniform(20, 40, n_samples)

ice_cream_sales = temperature + np.random.normal(0, 2, n_samples)

swimming_accidents = temperature + np.random.normal(0, 1, n_samples)

data = pd.DataFrame({

    'Temperature': temperature,

    'IceCreamSales': ice_cream_sales,

    'SwimmingAccidents': swimming_accidents

})

 

# DirectLiNGAMで因果探索

model = DirectLiNGAM()

model.fit(data)

 

# 隣接行列の取得

adj_matrix = model.adjacency_matrix_

var_names = data.columns

 

# DAGのエッジとスコアを抽出

edges = []

edge_scores = {}

for i, row in enumerate(adj_matrix):

    for j, weight in enumerate(row):

        if weight != 0:

            edges.append((var_names[j], var_names[i]))

            edge_scores[(var_names[j], var_names[i])] = weight

 

# グラフの描画

plt.figure(figsize=(8, 6))

G = nx.DiGraph(edges)

pos = nx.spring_layout(G, seed=42)

edge_labels = {(u, v): f"{edge_scores[(u, v)]:.2f}" for u, v in G.edges()}

 

# DAGの描画

nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, font_weight='bold', arrowsize=20)

nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_color='red', font_size=8)

 

plt.title("Causal DAG with Causal Effect Scores")

plt.show()

出力結果



このコードでは、DirectLiNGAMを用いてデータから因果構造を推定し、その構造を有向非巡回グラフ(DAG)として可視化しています。以下にコードの主要部分と関連する因果探索手法の解説を示します。


### 1. データ生成

temperature = np.random.uniform(20, 40, n_samples)

ice_cream_sales = temperature + np.random.normal(0, 2, n_samples)

swimming_accidents = temperature + np.random.normal(0, 1, n_samples)


Temperature(気温)が共通の原因となり、IceCreamSales(アイスクリーム売上)とSwimmingAccidents(水泳事故件数)の両方に影響を与えるデータを生成。

ランダムノイズを加えることで、現実のデータに近い状況を模擬しています。


### 2. DirectLiNGAMによる因果探索

model = DirectLiNGAM()

model.fit(data)

adj_matrix = model.adjacency_matrix_


DirectLiNGAMは、線形非ガウスモデル(LiNGAM)に基づく因果探索手法です。

  線形仮定: 変数間の因果関係が線形であると仮定。

  非ガウス性仮定: 観測変数の分布が非ガウス性を持つことを仮定。

  独立成分分析(ICA): 非ガウス性を活用し、因果順序を特定。

model.adjacency_matrix_から因果関係の隣接行列を取得します。この行列は、各変数間の因果効果の強さを示します。


### 3. 隣接行列からDAG(グラフ)の作成

edges = []

edge_scores = {}

for i, row in enumerate(adj_matrix):

    for j, weight in enumerate(row):

        if weight != 0:  # 因果関係が存在する場合

            edges.append((var_names[j], var_names[i]))

            edge_scores[(var_names[j], var_names[i])] = weight


隣接行列に基づき、因果関係を持つペア(エッジ)を抽出します。

非ゼロの重み(因果効果スコア)がある場合、それをエッジとして登録。

エッジスコアは因果効果の強さを数値化しており、結果の解釈に役立ちます。


### 4. DAGの可視化

G = nx.DiGraph(edges)

nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, font_weight='bold', arrowsize=20)

nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_color='red', font_size=8)


NetworkXのDiGraphを使用して有向グラフを構築。

nx.drawを用いてノード(変数)とエッジ(因果関係)を描画。

エッジにはスコア(因果効果の強さ)がラベルとして表示されます。


### 因果探索手法に関連する理論的背景

1. 制約ベース手法との比較

   制約ベース手法(例: PCアルゴリズム)は条件付き独立性を仮定しますが、DirectLiNGAMは非ガウス性に依存して因果関係を推定します。


2. スコアベース手法との比較

   スコアベース手法(例: GES)はデータ全体への適合性を最適化しますが、DirectLiNGAMでは線形かつ非ガウス性に特化したアプローチを取ります。


3. 関数型因果モデルの役割

   DirectLiNGAMは線形因果モデルを利用しますが、これを非線形に拡張する方法も存在します(例: カーネル法やニューラルネットワーク)。


### 出力結果の解釈

DAGのノード: 各変数(Temperature, IceCreamSales, SwimmingAccidents)を表す。

DAGのエッジ: 因果関係を示し、矢印の方向が因果の向きを表します(例: Temperature → IceCreamSales)。

エッジスコア: 因果効果の強さを表現(スコアが大きいほど影響が強い)。


このコードは、LiNGAMを活用して因果関係を明確に視覚化する非常に実践的な例です。

このブログの人気の投稿

片貝の四尺玉は世界一を連呼する『片貝賛歌~希望の花~』を作詞しました!!

小論文 統計的因果推論の現場適用による排泄ケアの展望

論文 排泄ケアにおける尊厳の保持と社会システムの課題 ~「おむつ」をめぐる心理的・文化的考察~