ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

argparseのパラメータの補完をPythonスクリプトから行う

docs.python.org

便利です。通常こいつを利用する場合はコマンドから引数を指定して値をわたしますが、とある事情からプログラムからも指定したい場合どうやって渡すのかな?と調べてたらありました。

stackoverflow.com

へー。試してみる

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--dataset-dir', help='set dataset directory name',
...                         type=str, default=None, required=True)
_StoreAction(option_strings=['--dataset-dir'], dest='dataset_dir', nargs=None, const=None, default=None, type=<class 'str'>, choices=None, help='set dataset directory name', metavar=None)
>>>
>>> import sys
>>> sys.argv.extend(['--dataset-dir', '.'])
>>> parser.parse_args()
Namespace(dataset_dir='.')

naruhodo...

Kedroのチュートリアルが動かない

Kedro?なにそれ?おいしいの???

僕もはじめてさわるのでよくわかりません。

kedro.readthedocs.io

zenn.dev

よくわからないので、ドキュメントやらぐぐってでてきた記事を参考にチュートリアルしてたけど動かない。

$ kedro run
2020-11-24 12:23:27,840 - root - INFO - ** Kedro project get_started
Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/site-packages/kedro/io/core.py", line 417, in parse_dataset_definition
    class_obj = next(obj for obj in trials if obj is not None)
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/site-packages/kedro/io/core.py", line 149, in from_config
    config, load_version, save_version
  File "/opt/conda/lib/python3.7/site-packages/kedro/io/core.py", line 419, in parse_dataset_definition
    raise DataSetError("Class `{}` not found.".format(class_obj))
kedro.io.core.DataSetError: Class `pandas.CSVDataSet` not found.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/conda/bin/kedro", line 10, in <module>
    sys.exit(main())
  File "/opt/conda/lib/python3.7/site-packages/kedro/cli/cli.py", line 638, in main
    ("Project specific commands", project_groups),
  File "/opt/conda/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/opt/conda/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/opt/conda/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/conda/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/conda/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/app/get_started/kedro_cli.py", line 278, in run
    pipeline_name=pipeline,
  File "/opt/conda/lib/python3.7/site-packages/kedro/context/context.py", line 482, in run
    save_version=save_version, journal=journal, load_versions=load_versions
  File "/opt/conda/lib/python3.7/site-packages/kedro/context/context.py", line 245, in _get_catalog
    conf_catalog, conf_creds, save_version, journal, load_versions
  File "/opt/conda/lib/python3.7/site-packages/kedro/context/context.py", line 269, in _create_catalog
    load_versions=load_versions,
  File "/opt/conda/lib/python3.7/site-packages/kedro/io/data_catalog.py", line 300, in from_config
    ds_name, ds_config, load_versions.get(ds_name), save_version
  File "/opt/conda/lib/python3.7/site-packages/kedro/io/core.py", line 154, in from_config
    "for DataSet `{}`:\n{}".format(name, str(ex))
kedro.io.core.DataSetError: An exception occurred when parsing config for DataSet `example_iris_data`:
Class `pandas.CSVDataSet` not found.

エラーでググってみたけど、よくわからず。

意味わからんので、とりあえずインタラクティブモードで動くかなーとか思って確認しようとした。

$ python
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from kedro.io import DataCatalog
>>> from kedro.extras.datasets.pandas import (
...     CSVDataSet,
...     SQLTableDataSet,
...     SQLQueryDataSet,
...     ParquetDataSet,
... )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/conda/lib/python3.7/site-packages/kedro/extras/datasets/pandas/__init__.py", line 35, in <module>
    from .gbq_dataset import GBQTableDataSet  # NOQA
  File "/opt/conda/lib/python3.7/site-packages/kedro/extras/datasets/pandas/gbq_dataset.py", line 37, in <module>
    from google.cloud import bigquery
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/__init__.py", line 35, in <module>
    from google.cloud.bigquery.client import Client
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/client.py", line 57, in <module>
    from google.cloud.bigquery import _pandas_helpers
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/_pandas_helpers.py", line 25, in <module>
    from google.cloud import bigquery_storage_v1beta1
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/__init__.py", line 25, in <module>
    from google.cloud.bigquery_storage_v1beta1 import types
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/types.py", line 23, in <module>
    from google.cloud.bigquery_storage_v1beta1.proto import arrow_pb2
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/proto/arrow_pb2.py", line 20, in <module>
    create_key=_descriptor._internal_create_key,
AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'
>>> from kedro.extras.datasets.pandas import CSVDataSet
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/conda/lib/python3.7/site-packages/kedro/extras/datasets/pandas/__init__.py", line 35, in <module>
    from .gbq_dataset import GBQTableDataSet  # NOQA
  File "/opt/conda/lib/python3.7/site-packages/kedro/extras/datasets/pandas/gbq_dataset.py", line 37, in <module>
    from google.cloud import bigquery
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/__init__.py", line 35, in <module>
    from google.cloud.bigquery.client import Client
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/client.py", line 57, in <module>
    from google.cloud.bigquery import _pandas_helpers
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery/_pandas_helpers.py", line 25, in <module>
    from google.cloud import bigquery_storage_v1beta1
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/__init__.py", line 25, in <module>
    from google.cloud.bigquery_storage_v1beta1 import types
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/types.py", line 23, in <module>
    from google.cloud.bigquery_storage_v1beta1.proto import arrow_pb2
  File "/opt/conda/lib/python3.7/site-packages/google/cloud/bigquery_storage_v1beta1/proto/arrow_pb2.py", line 20, in <module>
    create_key=_descriptor._internal_create_key,
AttributeError: module 'google.protobuf.descriptor' has no attribute '_internal_create_key'
>>>

違うエラーがでてきた???はて???

ぐぐったら下記記事が

stackoverflow.com

試す

$ pip install --upgrade protobuf

もう一度試す

$ python
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from kedro.extras.datasets.pandas import CSVDataSet
>>> df = CSVDataSet(filepath="./data/01_raw/iris.csv"),
>>> df
(<kedro.extras.datasets.pandas.csv_dataset.CSVDataSet object at 0x7f791f4371d0>,)

はて?エラーはでなくなった

$ kedro run
2020-11-24 12:40:35,101 - root - INFO - ** Kedro project get_started
2020-11-24 12:40:35,337 - kedro.io.data_catalog - INFO - Loading data from `example_iris_data` (CSVDataSet)...
2020-11-24 12:40:35,347 - kedro.io.data_catalog - INFO - Loading data from `params:example_test_data_ratio` (MemoryDataSet)...
2020-11-24 12:40:35,350 - kedro.pipeline.node - INFO - Running node: split_data([example_iris_data,params:example_test_data_ratio]) -> [example_test_x,example_test_y,example_train_x,example_train_y]
2020-11-24 12:40:35,374 - kedro.io.data_catalog - INFO - Saving data to `example_train_x` (MemoryDataSet)...
2020-11-24 12:40:35,376 - kedro.io.data_catalog - INFO - Saving data to `example_train_y` (MemoryDataSet)...
2020-11-24 12:40:35,378 - kedro.io.data_catalog - INFO - Saving data to `example_test_x` (MemoryDataSet)...
2020-11-24 12:40:35,381 - kedro.io.data_catalog - INFO - Saving data to `example_test_y` (MemoryDataSet)...
2020-11-24 12:40:35,383 - kedro.runner.sequential_runner - INFO - Completed 1 out of 4 tasks
2020-11-24 12:40:35,386 - kedro.io.data_catalog - INFO - Loading data from `example_train_x` (MemoryDataSet)...
2020-11-24 12:40:35,388 - kedro.io.data_catalog - INFO - Loading data from `example_train_y` (MemoryDataSet)...
2020-11-24 12:40:35,391 - kedro.io.data_catalog - INFO - Loading data from `parameters` (MemoryDataSet)...
2020-11-24 12:40:35,393 - kedro.pipeline.node - INFO - Running node: train_model([example_train_x,example_train_y,parameters]) -> [example_model]
2020-11-24 12:40:36,164 - kedro.io.data_catalog - INFO - Saving data to `example_model` (MemoryDataSet)...
2020-11-24 12:40:36,169 - kedro.runner.sequential_runner - INFO - Completed 2 out of 4 tasks
2020-11-24 12:40:36,172 - kedro.io.data_catalog - INFO - Loading data from `example_model` (MemoryDataSet)...
2020-11-24 12:40:36,175 - kedro.io.data_catalog - INFO - Loading data from `example_test_x` (MemoryDataSet)...
2020-11-24 12:40:36,178 - kedro.pipeline.node - INFO - Running node: predict([example_model,example_test_x]) -> [example_predictions]
2020-11-24 12:40:36,197 - kedro.io.data_catalog - INFO - Saving data to `example_predictions` (MemoryDataSet)...
2020-11-24 12:40:36,200 - kedro.runner.sequential_runner - INFO - Completed 3 out of 4 tasks
2020-11-24 12:40:36,204 - kedro.io.data_catalog - INFO - Loading data from `example_predictions` (MemoryDataSet)...
2020-11-24 12:40:36,206 - kedro.io.data_catalog - INFO - Loading data from `example_test_y` (MemoryDataSet)...
2020-11-24 12:40:36,208 - kedro.pipeline.node - INFO - Running node: report_accuracy([example_predictions,example_test_y]) -> None
2020-11-24 12:40:36,210 - iris_test.pipelines.data_science.nodes - INFO - Model accuracy on test set: 96.67%
2020-11-24 12:40:36,213 - kedro.runner.sequential_runner - INFO - Completed 4 out of 4 tasks
2020-11-24 12:40:36,214 - kedro.runner.sequential_runner - INFO - Pipeline execution completed successfully.

こっちもうまくいった。なんだったんじゃ

embulkでs3→mysqlを試したときにlockがかかって死んだときのメモ

メモリ1GBという制限があり、タイトル通りの構成で転送したところ、ひたすら失敗することを確認したが、mysqlのログを確認してみるとどうやらlockされていたことがわかった。

qiita.com

ちなみに中々メモリ1GBで検証するのは大変だと思うので(クラウドならいけると思うけど)、Dockerでやりました。

ichirin2501.hatenablog.com

で、個人的にはlockがなんなのかちゃんと理解してないのですが、なんでこうなったのかを色々調べていると、どうやらembulkが複数スレッドを起動して書き込んでいることがわかった。弱小マシンだと複数スレッドで書き込まれると1つのクエリ遅延中にさらにinsertされてlockされて死ぬっぽい(ちゃんと理解してい(ry

じゃあ、複数起動しないようにすればええんじゃないかということでググってたらこんなtweet

そこから下記にたどり着き

qiita.com

結局ドキュメントをよみにいき

www.embulk.org

「Local executor plugin」なるものにたどり着きました。

で、embulk config.ymlの設定にexec: {max_threads: 1}を追加

in:
    type: s3
    # 省略...
out:
    type: mysql
    # 省略...
exec:
    max_threads: 1

いざかまくら!!!で実行したところ、数十分かかってやっとこさlockもされずout of memoryも発生せず無事msyqlへinsertすることができましたとさ

lockがよくわかっていないのでちゃんと勉強します。

状態空間モデル勉強メモ

同僚からお借りして読んでいます(というか僕も持っていたんだけどどこいった)

  • 状態空間モデルのイメージ
    • 湖で釣りしている人がいる
    • 毎日釣った魚の数を観測する
    • つれた数で湖の魚の数を推測することができる
      • ただそれだけじゃ難しいよね
      • たまたまエサの食いつきがわるかったとか
      • とても暑い日だったからいつもいるところにいなかったとか
      • こういう観測誤差がある
    • というのを状態空間モデルで解決しましょう
      • 湖の中の魚の数を見えないけども状態として取り扱うことができる
      • 本当に湖の中の魚の数が変わったのか、感想誤差の範疇なのかを判断できる(らしい)
      • 状態と観測値を分けて考えることで対応可能(らしい)
    • 状態の変化を記述する方程式を状態方程式
    • 状態から観測値が得られるプロセスを記述する方程式を観測方程式
  • メリット
    • 過去の知見や直感を自由に表現できる(モデル化できる)
    • ARIMAなどの古典的なモデルも状態空間モデルで表現可能
    • 推定されたモデルの解釈が容易
    • 差分を取るといった前処理が不要
    • 欠損があってもそのまま分析に利用できるし、補完もできる
  • デメリット
    • 分析のルールがない(自由なのねなるほど)
  • 雑メモ
    • モデル選択はAICを用いた機械的な選択は行いにくいらしい
      • 状態空間モデルを用いてデータを表現する方法とパラメタ推定の方法は別物なのでわけて考えてね!!!
  • 状態
    • 前時点の状態を用いた予測値 + 過程誤差
  • 観測値
    • 状態 + 観測誤差
  • パラメタ推定
    • ほげほげフィルタ
      • カルマンフィルタ
        • 目に見えない「状態」を効率よく推定するためのアルゴリズム
        • 最尤法はパラメタの推定方法
        • こいつらのメリット
          • パラメタ推定と状態の推定をわけることで、一度パラメタが決まってしまえば、データが手に入るたび、逐次的に状態の推定や予測を行える
          • MCMCと比べると楽
        • デメリット
          • 正規分布に従い、かつ線形なデータにしか適用できない
          • この制約があるので、「線形ガウス状態空間モデル」「動的線形モデル(DLM)」と呼ばれる
    • MCMC
      • HMC法
      • ベイズ推論
      • ↑2つを組み合わせて状態とパラメタ推定を同時に行う
        • メリット
          • 正規分布非線形のデータにも対応可能
          • Stanというソフトウェアを扱うことでデータ生成過程をコードに起こすことができる(?)
        • デメリット
          • 分析に時間と手間がかかる
          • 状態とパラメタの推定を同時に行うので逐次的な処理が苦手
          • Stanがやばい
  • 線形ガウス状態空間モデル
    • 状態方程式 x_t = T_t x{t-1} + R_t ζt` ζ_t~N(0, Q_t)
    • 観測方程式 y_t = Ζt x{t-1} + εt` εt~N(0, H_t)
      • x_tはt時点の状態
      • 状態はk次元のベクトル(kってどこ?)
      • y_tはt時点の観測値
      • T_t, R_t, Ζ_tはモデルの表現形式をきめる行列
    • 状態推定
      • フィルタリングとは、手に入った観測値を用いて、予測された状態の値を補正すること
      • 手順
        • step1: 予測. 予測値と実際の観測値が異なる値になる場合があるので、step2で補正する
          • 状態
            • 過去の状態 → 未来の状態※1(予測)
          • 観測
            • ※1 → 未来の観測値(予測)
        • step2: フィルタリング(状態の補正). 状態の補正を行ってstep3で再度予測する
          • 状態
            • 過去の状態 → 未来の状態※1(補正後)
          • 観測
            • 未来の観測値(実測値) → ※1を補正
        • step3: 予測(?). 最新の観測値を使って、即座に誤りを補正して次の予測を行う
          • 状態
            • 過去の状態 → 未来の状態※1(補正後) → 未来の状態※2(予測)
          • 観測
            • ※1 ← 未来の観測値(実測値)、未来の観測値(予測) ← ※2
      • カルマンフィルタを使うと、↑の手順を効率よく行える
        • 散漫カルマンフィルタもほとんど変わらない。カルマンフィルタが持つ欠点を補った認識でおk
      • 平滑化
        • 平滑化とは、すべてのデータが手に入ったそのあとに、状態の補正を行う計算のことを指します
        • 過去の観測値、未来の観測値を使って過去の状態を補正する
        • 予測の精度をあげるものではなく、ノイズの影響を軽減することができる
        • 知識発見という意味合いで使用されることが多い技術(なんのこっちゃ)
        • 最も新しい時点においては、フィルタリングの結果と平滑化の結果は一致する
    • パラメタ推定: 最尤法
      • 状態推定を実際に行うには、観測値以外に情報が必要
        • 過程誤差の分散の大きさ
          • こいつが大きいということは、Step1の予測を行った際に、予測が当たり難いということを意味する
          • 予測された未来の状態の精度が悪いということは「観測値を用いた状態の補正」を行うべきー
        • 観測誤差の分散の大きさ
          • 観測誤差が大きいということは、観測値をあまり信用できないということを意味する
          • 「観測値を用いた状態の補正」はあまり行わないほうが良いといえる
        • このふたつを最尤法で推定しまぁーす
      • 手順
        • 適当にパラメタを決める
        • てきとーな状態の補正が行われる
        • ↑の結果を逐一評価していく → パラメタの微修正を繰り返す
        • これで最適なパラメタを探す。このときの評価指標を尤度とよび、尤度を最大にするパラメタを最尤法と呼ぶ
      • 例えば
        • 過程誤差も観測誤差もともに小さな値を設定するとする
        • 観測データが手に入れば
          • 状態は補正される(観測誤差が小さい → 観測値は信用できる → 状態を補正する)
          • 過程誤差が小さい → 予測はあたっている → 精度良く予測できている
        • しかし、正しく補正されている上に精度よく予測された予測結果が、実データと間違っている。ということはパラメタが間違っているということが言える
        • なので、想定される予測誤差と実際の予測誤差を比較すればパラメタの設定が正しいか否かを判断することができる
    • 流れ復習
      • 状態方程式・観測方程式を用いて、モデル構造を表現する
      • 「とりあえず」のパラメタを使ってフィルタリングする
      • カルマンフィルタの結果を援用し、最尤法を用いてパラメタを推定する
      • 推定されたパラメタを用いて、再度フィルタリングを行う
      • (必要であれば)推定されたパラメタを用いて、平滑化を行う
    • 補足
      • 誤差が正規分布にしたがったモデルなので、場合によっては対数系列に対してモデル化を行ったほうがよい場合もある
      • ただ、階差系列にする必要はない(らしい。何故?)
  • カルマンフィルタとカルマンゲイン
    • ローカルレベルモデルだけに絞って計算してみる
      • 状態の1期先予測は簡単 → 1時点前と同じ値になると予測するだけ
      • 観測値を用いた状態の補正は以下の要領で行われる
        • 補正後の状態 = 補正前の状態 + カルマンゲイン × (実際の観測値 - 予測された観測値)
        • 「補正後の状態」のことは「フィルタ化推定量」と呼ばれる
        • 残差がそのまま影響するのではなく、カルマンゲインが間をもっている
        • カルマンゲインは常に1以下の値を取る
          • 外れた分より少なめに補正する
            • なぜ? → そんなシンプルな話じゃないから
            • カルマンゲイン = 状態の予測誤差の分散 / (状態の予測誤差の分散 + 観測誤差の分散)
              • 状態の予測誤差が大きいなら補正しましょう!
              • 観測誤差が大きい場合は、補正量を小さくすべき
    • 計算の流れ
      • 過程誤差と観測誤差は誤差の増分を表すパラメタのこと
      • ↑2つを使って、実際の状態の予測誤差と観測値の予測誤差を求めます
      • 手順
        • Step1 予測
          • 状態の予測値 = 前期の状態
          • 状態の予測誤差の分散 = 前期の状態の予測誤差の分散 + 過程誤差の分散
          • 観測値の予測値 = 状態の予測値
          • 観測値の予測誤差の分散 = 状態の予測誤差の分散 + 観測誤差の分散
        • Step2 フィルタリング(状態の補正)
          • カルマンゲイン = 状態の予測誤差の分散 / (状態の予測誤差の分散 + 観測誤差の分散)
            • 分母は観測値の予測誤差の分散としても同じ
          • 観測値の予測残差 = 実際の観測値 - 観測値の予測値
          • フィルタ化推定量 = 補正前の状態 + カルマンゲイン × 観測値の予測残差
          • フィルタ化推定量の分散 = (1 - カルマンゲイン) × 補正前の状態の予測誤差の分散
    • 散漫カルマンフィルタ
      • 前時点がない場合、前時点の情報が必要なパラメタはてきとーに値を設定しておく
      • ただ、初期値を適当に決めてもいいけども、AICの情報量基準の値も変化するので注意したい
      • そこで散漫初期化というアプローチ
        • 状態の初期値はわからないので諦める
        • そのかわり、状態の予測誤差の分散の初期値を無限大まで大きくする
  • 平滑化
    • 今日の観測値を使って、今日の状態を補正するのがフィルタリング
    • 今日の観測値を使って、昨日の状態を補正するのが平滑化
    • アイディア
      • ①実際の観測値と観測値の予測値の残差が大きい。これは昨日に推定された状態の値が間違っているので、昨日の状態を大きく補正しよう
      • ②昨日の状態の不確かさ(昨日のフィルタ化推定量の分散)が大きいまま残っているのであれば、昨日の状態を大きく補正するべき
      • ③今日の予測誤差の大きさ(観測値の予測誤差の分散)が大きいのであれば、昨日の状態を補正する必要はあまりないだろう(観測値が信頼できないため)
      • まとめる
        • 昨日のフィルタ化推定量 + 昨日のフィルタ化推定量の分散 / 今日の観測値の予測誤差の分散 × 今日の予測残差

いい加減ちゃんと覚えたい統計学 幹葉図

bellcurve.jp

人生で初めて出会いました(統計学の問題集で)

↑のリンクの通り、概要把握すればそんなに難しくないですが、平均や四分位数を求めるときがとてもめんどくさく、序盤にでてくるくせに電卓うちなれていないと無限に時間を消費してしまう中ボス的な存在です。問題自体は愚直に計算すれば解は求まるので、一旦チェックいれて時間が余れば解く or 点数少しでも稼ぎたいから残り5分になったらチェックした問題に戻って解くでもいいのかなって思いました。

ただ、仕事では使わなそうな雰囲気を感じているのでこいつ得意になったところで「で?」ってなりそうな気はしている。(わからないけどね)