非線形の時系列因果関係を推定できるCross-mappingモデルのPython実装モジュール「pyDEM」をMacbookに入れる


以下の記事では、表形式のデータに対して、__表中のどの変数ペアの間に、線形関数で表現される因果関係が生じているのかを探索__できる__SAMモデル__を、Google Colaboratoryで動かしてみました。

- [GANを使った「統計的因果探索」モデル SAM（Structural Agnostic Modelling)をTitanicデータセットに適用してみた](https://qiita.com/Afo_guard_enthusiast/items/0470b030a6a52d24fc67)

__*LiNGAM*モデル__と__SAM（*Structural Agnostic Modelling*)モデル__は、変数間の因果関係として、__線形関数を想定__するモデルでした。

- [@YuyaOmoriさん 「【因果探索・因果推論】DeepLearningを用いた因果探索(SAM)を実行」](https://qiita.com/YuyaOmori/items/a9c5f9321f9387fe74e1)

そのため、LiNGAMとSAMは、変数間にもしも何らかの因果関係が存在する場合、その関係が必ず「線形」関係（線形関数でモデル化される）にあるという制約を持ちます。

この制約は、__変数間に、非線形の力学モデルで記述できる関係の存在を想定__する__*Cross-mapping algorithm*という方法__を用いることで、取り払うことができます。

（__非線形力学モデル__ということで、__カオス力学モデル__が登場します）

- [@kumalphaさん 時系列分析における因果推定(主にConvergent Cross Mapping)](https://qiita.com/kumalpha/items/8ab7eba15ed09e4d268f)

> __Convergent Cross Mapping (CCM)__
>
> Empirical Dynamic Modeling (EDM)の一種。EDMは時系列データを非線形力学系として捉え、変数間の作用や近未来予測を実行する手法。数式を仮定せず、観測値から系の状態空間を再構成してモデルフリーに解析をおこなう。Simplex projectionやS-mapの考え方を複数の変数の交互の予測に拡張した手法で、相互作用のある非線形力学系ならばTakens' theoremにより、お互いの時間遅れ埋め込みの情報を使って相手の時間遅れ埋め込みを再構成できる（自分の時系列のみから相手の時系列を予測できる）という特徴を利用している。

- [@nyanko-boxさん Empirical Dynamic Modelingについて学習したこと](https://qiita.com/nyanko-box/items/9ac15007a9e663c090c9)

> EDMは変数間の因果性を明らかにするためにも使用される．
>
> 因果性検定: Cross-mapping algorithm
> 単変数から再構成された系のマニフォールドはもともとの系への写像を得る，という考えに基づく手法
> 変数 M1,M2M1,M2 について，Cross-mappingの結果が "収束" すれば同じ系に属する (因果的に結びついている) と捉えられる (Cross-mapping Convergent: CCM) ．ここで言う > "収束" とは，ライブラリ長の増加に伴ってcross-mapping能力 (ρρ) が増加することを指す．
>
> 代表的な方法としては，下記2つの検定がともに有意だった場合，収束が有意であると判定される

1. __Kenddallの$ττ$検定__
2. __Fisherの$ΔρZΔρZ$検定__

##*pyEDM*モジュールを入れてみる

- [（GitHub）github.com/SugiharaLab/pyEDM](https://github.com/SugiharaLab/pyEDM)

####GitHubの説明にしたがって、次のコマンドで*pyEDM*モジュールを入れてみます。

> __OSX and Linux__
>
>```bash
> Download pyEDM: git clone https://github.com/SugiharaLab/pyEDM
> Build cppEDM library: cd pyEDM/cppEDM/src; make
> Build and install package: cd ../..; python -m pip install . --user --trusted-host pypi.org
>```
>

####*git clone*を実行

```bash:Terminal
ocean@AfoGuardMacBook-Pro Desktop % git clone https://github.com/SugiharaLab/pyEDM
Cloning into 'pyEDM'...
remote: Enumerating objects: 130, done.
remote: Counting objects: 100% (130/130), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 1524 (delta 72), reused 90 (delta 45), pack-reused 1394
Receiving objects: 100% (1524/1524), 22.60 MiB | 3.48 MiB/s, done.
Resolving deltas: 100% (911/911), done.
ocean@AfoGuardMacBook-Pro Desktop %
```

####*make*を実行

```bash:Terminal
ocean@AfoGuardMacBook-Pro Desktop % cd pyEDM/cppEDM/src; make
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c API.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c CCM.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c Common.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c DateTime.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c EDM.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c EDM_Formatting.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c EDM_Neighbors.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c Eval.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c Multiview.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c Parameter.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c Simplex.cc
g++ -std=c++11 -Wpedantic -Wall -Wextra -Wreorder -O3 -DCCM_THREADED -fPIC -c SMap.cc
ar -rcs libEDM.a API.o CCM.o Common.o DateTime.o EDM.o EDM_Formatting.o EDM_Neighbors.o Eval.o Multiview.o Parameter.o Simplex.o SMap.o
cp libEDM.a ../lib/
ocean@AfoGuardMacBook-Pro src %
```

####（*ls*で資源を確認）

```bash:Terminal
ocean@AfoGuardMacBook-Pro src % ls
API.cc			Common.h		EDM.h			Eval.cc			Parameter.o		Version.h
API.h			Common.o		EDM.o			Eval.o			SMap.cc			libEDM.a
API.o			DataFrame.h		EDM_Formatting.cc	Multiview.cc		SMap.h			makefile
CCM.cc			DateTime.cc		EDM_Formatting.o	Multiview.h		SMap.o			makefile.windows
CCM.h			DateTime.h		EDM_Neighbors.cc	Multiview.o		Simplex.cc
CCM.o			DateTime.o		EDM_Neighbors.h		Parameter.cc		Simplex.h
Common.cc		EDM.cc			EDM_Neighbors.o		Parameter.h		Simplex.o
ocean@AfoGuardMacBook-Pro src %
```

####*pip install*を実行して、*pyEDM*モジュールを入れる

```bash:Terminal 
ocean@AfoGuardMacBook-Pro src % cd ../..; python -m pip install . --user --trusted-host pypi.org
Processing /Users/ocean/Desktop/pyEDM
Requirement already satisfied: pandas>=0.20.3 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from pyEDM==1.7.3.0) (1.1.5)
Requirement already satisfied: matplotlib>=2.2 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from pyEDM==1.7.3.0) (3.3.3)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (2.4.7)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (1.3.1)
Requirement already satisfied: numpy>=1.15 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (1.19.4)
Requirement already satisfied: pillow>=6.2.0 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (8.0.1)
Requirement already satisfied: python-dateutil>=2.1 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (2.8.1)
Requirement already satisfied: cycler>=0.10 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from matplotlib>=2.2->pyEDM==1.7.3.0) (0.10.0)
Requirement already satisfied: six in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from cycler>=0.10->matplotlib>=2.2->pyEDM==1.7.3.0) (1.15.0)
Requirement already satisfied: pytz>=2017.2 in /Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages (from pandas>=0.20.3->pyEDM==1.7.3.0) (2020.4)
Collecting pybind11>=2.3
  Using cached pybind11-2.6.1-py2.py3-none-any.whl (188 kB)
Building wheels for collected packages: pyEDM
  Building wheel for pyEDM (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /Users/ocean/.pyenv/versions/3.6.3/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/setup.py'"'"'; __file__='"'"'/private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-wheel-nxydh55p
       cwd: /private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/
  Complete output (85 lines):
  cp libEDM.a ../lib/
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.15-x86_64-3.6
  creating build/lib.macosx-10.15-x86_64-3.6/pyEDM
  copying pyEDM/__init__.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM
  copying pyEDM/LoadData.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM
  copying pyEDM/CoreEDM.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM
  copying pyEDM/AuxFunc.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM
  creating build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Smap_embd_block_3sp_pyEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/sardine_anchovy_sst.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/TentMapNoise_rEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Multiview_combos_valid.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/circle_noise.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Smap_circle_pyEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/TentMap_rEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/CCM_anch_sst_cppEDM_valid.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/circle.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/block_3sp.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Multiview_pred_valid.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Smplx_embd_block_3sp_pyEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  copying pyEDM/data/Smplx_E3_block_3sp_pyEDM.csv -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/data
  creating build/lib.macosx-10.15-x86_64-3.6/pyEDM/tests
  copying pyEDM/tests/examples.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/tests
  copying pyEDM/tests/tests.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/tests
  copying pyEDM/tests/smapSolverTest.py -> build/lib.macosx-10.15-x86_64-3.6/pyEDM/tests
  running build_ext
  creating var
  creating var/folders
  creating var/folders/dw
  creating var/folders/dw/kq_8pwps5s771nklvc8krws40000gn
  creating var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Users/ocean/.pyenv/versions/3.6.3/include/python3.6m -c /var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/tmpta8u7un3.cpp -o var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/tmpta8u7un3.o -std=c++14
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Users/ocean/.pyenv/versions/3.6.3/include/python3.6m -c /var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/tmpq0p1f2cr.cpp -o var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/tmpq0p1f2cr.o -fvisibility=hidden
  building 'pyBindEDM' extension
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/setup.py", line 212, in <module>
      zip_safe         = False,
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages/setuptools/__init__.py", line 153, in setup
      return distutils.core.setup(**attrs)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/core.py", line 148, in setup
      dist.run_commands()
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/dist.py", line 955, in run_commands
      self.run_command(cmd)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/dist.py", line 974, in run_command
      cmd_obj.run()
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages/wheel/bdist_wheel.py", line 299, in run
      self.run_command('build')
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/dist.py", line 974, in run_command
      cmd_obj.run()
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/command/build.py", line 135, in run
      self.run_command(cmd_name)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/dist.py", line 974, in run_command
      cmd_obj.run()
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages/setuptools/command/build_ext.py", line 79, in run
      _build_ext.run(self)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/command/build_ext.py", line 339, in run
      self.build_extensions()
    File "/private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/setup.py", line 144, in build_extensions
      build_ext.build_extensions(self)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/command/build_ext.py", line 448, in build_extensions
      self._build_extensions_serial()
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/command/build_ext.py", line 473, in _build_extensions_serial
      self.build_extension(ext)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/site-packages/setuptools/command/build_ext.py", line 196, in build_extension
      _build_ext.build_extension(self, ext)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/command/build_ext.py", line 533, in build_extension
      depends=ext.depends)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/ccompiler.py", line 566, in compile
      depends, extra_postargs)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/ccompiler.py", line 341, in _setup_compile
      pp_opts = gen_preprocess_options(macros, incdirs)
    File "/Users/ocean/.pyenv/versions/3.6.3/lib/python3.6/distutils/ccompiler.py", line 1075, in gen_preprocess_options
      pp_opts.append("-I%s" % dir)
    File "/private/var/folders/dw/kq_8pwps5s771nklvc8krws40000gn/T/pip-req-build-3lmwjyj2/setup.py", line 73, in __str__
      import pybind11
  ModuleNotFoundError: No module named 'pybind11'
  ----------------------------------------
  ERROR: Failed building wheel for pyEDM
  Running setup.py clean for pyEDM
Failed to build pyEDM
Installing collected packages: pybind11, pyEDM
  WARNING: The script pybind11-config is installed in '/Users/ocean/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
    Running setup.py install for pyEDM ... done
  DEPRECATION: pyEDM was installed using the legacy 'setup.py install' method, because a wheel could not be built for it. pip 21.0 will remove support for this functionality. A possible replacement is to fix the wheel build issue reported above. You can find discussion regarding this at https://github.com/pypa/pip/issues/8368.
Successfully installed pyEDM-1.7.3.0 pybind11-2.6.1
ocean@AfoGuardMacBook-Pro pyEDM %
```

```bash:Terminal 
ocean@AfoGuardMacBook-Pro pyEDM % pwd
/Users/ocean/Desktop/pyEDM
ocean@AfoGuardMacBook-Pro pyEDM % 
```

#動作確認

> __Usage__
>
> Example usage at the python prompt:
>
>```python
>>>> import pyEDM
>>>> pyEDM.Examples()
>```
>

```python:Python3.6.3
ocean@AfoGuardMacBook-Pro Desktop % cd pyEDM
ocean@AfoGuardMacBook-Pro pyEDM % python
Python 3.6.3 (default, Dec 10 2020, 22:43:16) 
[GCC Apple LLVM 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyEDM
>>> pyEDM.Examples()

（ ・・・様々なグラフが小画面で表示される・・・　）

>>> quit() 
```

####上記の状態だと、カレントディレクトリが*pyDEM*の場合だけ、*import pyDEM*を実行できます。