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を活用して因果関係を明確に視覚化する非常に実践的な例です。