DoWhy에 의한 통계적 인과 추론

DoWhy에 의한 인과 추론



DoWhy의 방향과 방법의 메모 (비망록)

목차



소개
필요성
도입 환경
도입법
움직였다.
- 준비
- 데이터 생성
- Model(가정)
- Identification(변수 식별)
- Estimation (수식에서 추정)
- Check(Sensitivity Analysis)
참조

소개 DoWhy는 Microsoft가 발표한 인과추론 라이브러리(Python). 이 라이브러리는 Judea Pearl의 "do-calculus"의 생각이 근본적으로 있다. 그래서 분석자 자신이 데이터의 요소에 대해 어떻게 교락하고 있는지를 미리 검토하고 DAG를 그릴 필요가 있다. 사적으로는 추정에 무게를 두는 기존의 다른 패키지 또는 라이브러리와는 달리, DoWhy는 설정한 가정에 무게를 두고 있는 인상이 있다. 어떤 인과효과에 대해 검증하고 싶은 경우, 추정에 필요한 수식을 도입하여 추정하면 끝나지 않고, 그 후에 그 가정이 얼마나 적당한가를 검토하는 공정이 있다. 야미쿠모에게 단지 추정할 뿐만 아니라 체크 단계를 강조하는 본 라이브러리는 통계적 인과추론을 학습하는데 있어서, 사고방식의 축이 굵어지는 것이라고 생각된다. 필요성 예측 모델은 관측 데이터의 Input과 Outcome을 연결하는 패턴을 나타냅니다. 그러나, 개입을 실시하고 그 효과를 보고 싶은 경우에는, 데이터가 존재하지 않는 현재의 값으로부터, Input를 변경했을 경우의 영향을 추정할 필요가 있다. 이것은 다음과 같은 반 사실을 추정하는 것입니다. ·Will it work? 시스템 변경이 결과를 개선할 수 있는가? ·Why did it work? 결과에 변화를 가져온 것은 무엇인가? ・What should we do? 시스템을 변경하면 결과가 개선됩니까? ·What are the overall effects? 시스템은 어떻게 다른 요인과 작용하고 그 요인에 영향을 미치는가? 이러한 질문에 대답하려면 인과 추론이 필요하며 많은 방법이 있지만 가정과 결과의 견고성을 비교하는 것은 어렵습니다. 따라서 DoWhy에서는 주어진 질문을 인과 그래프로 모델링하는 원칙적인 방법을 사용하여 모든 가정이 명확해진다. 그런 다음 모델과 잠재적 인 결과 프레임 워크를 결합하여 일반적인 인과 추론으로 돌아갑니다. 그리고 가능하면 가정의 타당성을 자동으로 테스트하여 실수에 대한 추정치의 견고성을 평가합니다. 도입 환경 OS: Mojave (version; 10.14.6) Python: 3.7.6 JupyterLab: 1.2.6 Graphviz: 2.40.1 도입법 다음과 같이 설치했다. $pip install dowhy 그것과 PyGraphviz를 넣지 않았기 때문에 그것도 넣었다. $ sudo pip install --install-option="--include-path=/usr/local/include/" --install-option="--library-path=/usr/local/lib/" pygraphviz 움직였다. DoWhy의 주요 흐름은 다음과 같습니다.

기본적으로 그림을 따라 실행됩니다.

준비 import numpy as np import pandas as pd import dowhy from dowhy import CausalModel import dowhy.datasets import pygraphviz 데이터 생성 data = dowhy.datasets.linear_dataset(beta=10, # 진정한 인과 효과 num_common_causes=5, # 관측된 공통 원인 num_instruments=2, # 원인에 대한 변수 num_samples=10000, # 샘플 수 treatment_is_binary=True) df = data["df"] print(df.head()) print(data["dot_graph"]) print("\n") print(data["gml_graph"]) # 결과가 다음과 같습니다. Z0 Z1 W0 W1 W2 W3 W4 v0\ 0 0.0 0.697077 0.145565 -1.297894 2.226496 1.645846 -0.385215 True 1 0.0 0.427846 0.356681 1.331070 0.740072 0.265514 -1.838137 True 2 1.0 0.525590 0.383658 0.535433 0.795982 1.743974 -1.554143 True 3 0.0 0.135632 -0.002793 -0.607062 1.111112 0.558599 -1.201494 True 4 1.0 0.966809 -0.613649 2.351279 0.746445 -1.000265 -0.700003 True y 0 11.272817 1 13.219180 2 12.116330 3 7.008058 4 18.573009 digraph { U[label="Unobserved Confounders"]; U->y;v0->y; U->v0;W0->v0; W1->v0; W2->v0; W3->v0; W4-> v0; Z0-> v0; Z1-> v0; W0-> y; W1-> y; W2-> y; W3-> y; W4-> y;} 조치 (원인)는 "v0"이고 결과는 "y"입니다. 미관측 공통 원인은 "U"로, "W"(0-4)는 관측되고 있는 공통 원인, 그리고 "Z"(0-1)는 "v0"의 관측된 변수. 상기가 알려진 것으로, 효과를 추정한다(진정한 인과 효과 10에 얼마나 가까워지는지를 살펴본다). Model(가정) model = CausalModel ( data=df, treatment=data["treatment_name"], outcome=data["outcome_name"], graph=data["gml_graph"]) # 결과 INFO:dowhy.causal_model:Model to find the causal effect of treatment ['v0'] on outcome ['y'] DAG 그리기 model.view_model() from IPython.display import Image, display display(Image(filename="causal_model.png"))

Identification(변수 식별) 방금 그린 DAG에서 추정에 사용되는 변수를 추정한다. identified_estimand = model.identify_effect() print (identified_estimand) # 결과 INFO:dowhy.causal_identifier:Common causes of treatment and outcome:['W4', 'W2', 'W1', 'W3', 'W0', 'U'] WARNING:dowhy.causal_identifier:If this is observed data (not from a randomized experiment), there might always be missing confounders. Causal effect cannot be identified perfectly. WARN: Do you want to continue by ignoring any unobserved confounders? (use proceed_when_unidentifiable=True to disable this prompt) [y/n] y INFO:dowhy.causal_identifier:Instrumental variables for treatment and outcome:[] Estimand type: nonparametric-ate ### Estimand : 1 Estimand name: backdoor Estimand expression: d ─────(Expectation(y|W4,W2,W1,W3,W0)) d[v₀] Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W4,W2,W1,W3,W0,U) = P(y|v0,W4,W2,W1,W3, W0) ### Estimand : 2 Estimand name: iv No such variable found! 방금 전의 DAG가 정확하고 Conditional Exchangeability가 성립하는 경우(즉 가정이 올바른 경우)의 견적 결과가 되고 있다. Backdoor 기준에서 "v0"을 변화시켰을 때의 "W"로 조건부된 "y"의 변화량을 구하고 싶은 ATE가 되고 있다. Estimation (수식에서 추정) 여기서는 방정식을 사용하여 이전의 결과를 실제로 적용하여 계산합니다. DoWhy에서는 다음을 사용할 수 있습니다. 회귀 층별 매칭 IPW IV RDD 또, CATE(conditional ATE)의 추정에 이용되는 Python 라이브러리인 EconML(microsoft)과 병용하는 것으로, CATE도 이용 가능. (아직 읽혀지지 않았다. EconML 이용할 수 있다는 것은 Meta-Leaner나 ORF 등을 관찰 데이터로부터 추정에 이용할 수 있는 것인가?) 이번에는 층별을 실행했다. causal_estimate = model.estimate_effect(identified_estimand, method_name="backdoor.propensity_score_stratification") # backdoor.xxx의 끝에서 변경 print(causal_estimate) print("Causal Estimate is" + str(causal_estimate.value)) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~v0+W4+W2+W1+W3+W0 *** Causal Estimate *** ## Target estimand Estimand type: nonparametric-ate ### Estimand : 1 Estimand name: backdoor Estimand expression: d ─────(Expectation(y|W4,W2,W1,W3,W0)) d[v₀] Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W4,W2,W1,W3,W0,U) = P(y|v0,W4,W2,W1,W3, W0) ### Estimand : 2 Estimand name: iv Estimand expression: Expectation(Derivative(y, [Z1, Z0])*Derivative([v0], [Z1, Z0])**(-1)) Estimand assumption 1, As-if-random: If U→→y then ¬(U →→{Z1,Z0}) Estimand assumption 2, Exclusion: If we remove {Z1,Z0}→{v0}, then ¬({Z1,Z0}→y) ## Realized estimand b: y~v0+W4+W2+W1+W3+W0 ## Estimate Value: 10.074645926227818 Causal Estimate is10.074645926227818 마지막 Estimate가 추정한 값이다(덧붙여서 데이터 생성 단계에서는 인과 효과를 10으로 설정하고 있다). Check(Sensitivity Analysis) 소지의 데이터에는 포함되지 않는 변수가 바이어스가 될 가능성은 항상 존재한다. 그리고 이번이라면 가정을 세우고 Backdoor 기준을 채용하여 이를 바탕으로 인과효과를 추정했다. 그러나 이 가정이 정확하다는 보장은 없다. 따라서, 분석가가 중요하다고 인식하는 공변량 이외의 변수를 모델로부터 변경함으로써, 효과의 추정치가 크게 변동하지 않는지를 확인하는 작업이다. 임의의 공통 원인 변수 추가 res_random=model.refute_estimate(identified_estimand, estimate, method_name="random_common_cause") print(res_random) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~v0+W4+W2+W1+W3+W0+w_random Refute: Add a Random Common Cause Estimated effect:(10.074645926227818,) 새로운 효과 : (9.950638858187622,) 미관측 공통 원인 추가 res_unobserved=model.refute_estimate(identified_estimand, estimate, method_name="add_unobserved_common_cause", confounders_effect_on_treatment="binary_flip", confounders_effect_on_outcome="linear", effect_strength_on_treatment=0.01, effect_strength_on_outcome=0.02) print(res_unobserved) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~v0+W4+W2+W1+W3+W0 Refute: Add an Unobserved Common Cause Estimated effect:(10.074645926227818,) 새로운 효과 : (9.189776632922118,) 원인 (v0)을 임의의 변수로 바꾸기 res_placebo=model.refute_estimate(identified_estimand, estimate, method_name="placebo_treatment_refuter", placebo_type="permute") print(res_placebo) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~placebo+W4+W2+W1+W3+W0 Refute: Use a Placebo Treatment Estimated effect:(10.074645926227818,) 새로운 효과 : (0.07317739755853733,) 기본 데이터의 하위 집합으로 추정 res_subset=model.refute_estimate(identified_estimand, estimate, method_name="data_subset_refuter", subset_fraction = 0.9) # 기본 데이터에서 추출 할 데이터의 비율 print(res_subset) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~v0+W4+W2+W1+W3+W0 Refute: Use a subset of data Estimated effect:(10.074645926227818,) 새로운 효과 : (10.125793210348078,) 또한 재현성을 위해 random.seed를 설정할 수도 있습니다. res_subset=model.refute_estimate(identified_estimand, estimate, method_name="data_subset_refuter", subset_fraction=0.9, random_seed=1) # 서브세트 비율 및 시드 값 설정 print(res_subset) # 결과 INFO:dowhy.causal_estimator:INFO: Using Propensity Score Stratification Estimator INFO:dowhy.causal_estimator:b: y~v0+W4+W2+W1+W3+W0 Refute: Use a subset of data Estimated effect:(10.074645926227818,) 새로운 효과 : (10.068276205100556,) 참조
  • "통계적 인과추론을 위한 Python 라이브러리 DoWhy에 대해 해설
  • microsoft/dowhy(GitHub)
    htps //w w. krsk-phs. 코m/엔트리/2018/08/22/060844
  • DoWhy의 Docs
    htps : // 기주 b. 코 m / 미 c 로소 ft / why
  • 좋은 웹페이지 즐겨찾기