default eye-catch image.

postgresユーザのホームディレクトリ

ubuntuの場合、postgresユーザのホームディレクトリは /var/lib/postgresql 。 例えば .pgpass をここに置くと、postgres ユーザで psql を実行した場合でも読んでくれる。 ホームディレクトリが無い理由 プログラムを実行するために作成されたユーザとコンソールログインするユーザは扱いが違う。 例えば nginx、mysql のように PostgreSQL の実行ユーザである postgres のホームディレクトリは、 PostgreSQL の maintainer が決める。 /home/postgres というディレクトリは作られない。 PostgreSQLは, root の代わりに postgres ユーザを使ってり様々な処理をおこなう. ホームディレクトリはどこ? PostgreSQLのインストールディレクトリがホームディレクトリ。 ubuntuの場合、PostgreSQLは /var/lib/postgresql にインストールされていて、 /var/lib/postgresql がホームディレクトリ。 データディレクトリの調べ方 PostgreSQLのデータベースファイルのレイアウトによると、 データディレクトリに全てのファイルが格納される。 postgres の起動パラメタとして データディレクトリ が指定されている。 (-D) 以下の例だと、/var/lib/postgresql/9.5/main。 $ ps ax | grep postgres | grep -v postgres: 1377 ? S 0:01 /usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/9.5/main -c config_file=/etc/postgresql/9.5/main/postgresql.conf 10600 pts/0 T 0:00 sudo -s -u postgres 11930 pts/0 S+ 0:00 grep --color=auto postgres 別の方法として、psql から SHOW data_directory を実行することで データディレクトリを得られる。 やはり、/var/lib/postgresql/9.5/main。 $ sudo -s -u postgres $ psql postgres=# SHOW data_directory; data_directory ------------------------------ /var/lib/postgresql/9.5/main (1 row) ホームディレクトリの下の階層にデータディレクトリが出来ている。 /home/以下が作られないユーザについて(Stackoverflow) Why Directory for postgres user does not appear inside the HOME directory in linux with other users? [closed] That there is a dedicated user for PostgreSQL is a security measure, so the DB processes can run with that user\'s (limited) priviledges instead of running as root. Whether or not you can actually log on with that user, and what that user\'s home directory should be, is the decision of the package maintainer / the Linux distribution in question. Since the postgresql user should not be (ab-) used as just another user (with own desktop settings, user data etc.), I wouldn\'t question the wisdom of not giving it a home, but rather why he is enabled to log in in the first place. Edit: Being ignorant of the fine print of PostgreSQL, and a bit confused by the wording of your question, I argued the general case. Ignacio pointed out that you had to actually break the system (unlock the user\'s password with root priviledges) to even be able to log in as postgresql user. So the answer can be phrased even simpler: The user does not have a directory in /home because you are not supposed to ever log in as that user. It\'s for running the database processes without root priviledges, nothing else. (Note that you could, using the same technique, log in as user man, or user lp, or user mail. You could, but it wouldn\'t make sense, and unlocking those user\'s passwords actually weakens the security of your system.)

default eye-catch image.

接続中のセッションを全部切る方法

セッション毎にプロセスが動いている。 pg_terminate_backend()を使ってプロセスを落とせば良い。 動いているプロセスを落とせばセッションは切れる。 killで落とすと上手くいかないので注意。 基本形 基本形は以下の通り。 $ sudo -s -u postgres $ psql postgres=> select pg_terminate_backend({プロセスID}); 通常、セッションは複数存在するため、切りたいセッションのプロセスIDを選択して pg_terminate_backend()に渡す必要がある。 自分以外全部切る 生きているセッションをpg_terminate_backend()(後述)を使って探し、 pg_terminate_backend()に食わせて落とす。 自分自身のpidは pg_backend_pid() で得られる。 $ sudo -s -u postgres $ psql postgres=> SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = \'DB名\' AND pid pg_backend_pid(); datnameはTypoではない! 動的統計情報ビュー 上で使っているpg_stat_activityは動的統計情報ビューというビルトインのビューの一つ。 27.2.2. 統計情報の表示。 サーバ当たり1行の形式で、 状態や現在の問い合わせ等のプロセスの現在の活動状況に関連した情報を表示する。 取れるデータ達は以下の通り。PostgresSQLのバージョンによって異なるが、 よく使いそうなものは変わらなそう。使う場合には要注意。 postgres=> d pg_stat_activity; View \"pg_catalog.pg_stat_activity\" Column | Type | Modifiers ------------------+--------------------------+----------- datid | oid | ; バックエンドが接続するデータベースのOID datname | name | ; バックエンドが接続するデータベースの名前 pid | integer | ; バックエンドのプロセスID usesysid | oid | ; バックエンドにログインしたユーザの識別子 usename | name | ; バックエンドに接続したユーザの名前 application_name | text | ; バックエンドに接続したアプリケーションの名前 client_addr | inet | ; バックエンドに接続したクライアントのIPアドレス client_hostname | text | ; client_addrの逆引き検索により報告された、接続クライアントのホスト名 client_port | integer | ; クライアントがバックエンドとの通信に使用するTCPポート backend_start | timestamp with time zone | ; プロセスが開始、つまりクライアントがサーバに接続した時刻 xact_start | timestamp with time zone | ; プロセスの現在のトランザクションが開始した時刻 query_start | timestamp with time zone | ; 現在有効な問い合わせが開始した時刻 state_change | timestamp with time zone | ; stateの最終変更時刻 wait_event_type | text | ; he type of event for which the backend is waiting wait_event | text | ; Wait event name if backend is currently waiting, otherwise NULL. state | text | ; Current overall state of this backend backend_xid | xid | ; もしあれば、このバックエンドの最上位のトランザクション識別子 backend_xmin | xid | ; 現在のバックエンドのxmin query | text | ; バックエンドの最も最近の問い合わせテキスト backend_type | text | ; Type of current backend

default eye-catch image.

TableuServer認定資格

この記事 Tableau未経験者がTableauを扱う仕事をすることになったのと, 合わせてServer Certified Associate資格の取得が必要になったためいつものごとく学びの軌跡を記録していく. マルチノード高可用性のための設計を学ぶというモチベ 潰しが効く系ではないのだが, 実際にインストールして設定しようとすると知らなければならないことが並んでいる. 使わないけれど知識として並べてある, という一部のベンダー資格とは違う印象がある. 通常,いきなりマルチノードで高可用性が..とかにはならないはずだがどこかで入門レベルが存在しなければならない. 最小構成/シングルノード構成/マルチノード構成へとスケールできるアーキテクチャになっていることを理解することが結局のところスケールを前提とした入門になり得ると思う. あるシステムのシステム構成がここまで明らかになっているのも珍しい印象. マルチノードと高可用性実現のため, レイヤやコンポーネントが想像以上に分離していて, スケールさせる際の自由度の素になっている. スケールのための設計をゼロベースで学んだ経験がないため,自分が自作するレベルのシステムのアーキテクチャではここまで分解しないな,というのは当然あったが, 正直かなり設計の勉強になった. 対策 過去問が公開されていたり,公式参考書があったりはしないため,試験のための習得にはなりづらい. マルチノード化による高可用性を実現するためのアーキテクチャを学ぶ機会と捉えれば,結構モチベになると思う. (そんな人いるんでしょうか..w) 試験のシラバスが項目単位で並んでいる. この項目を自分の言葉で説明できることが当面のゴール. 言葉で説明する深さについては,暗記が不要という難易度調整が入っておりそれほど深くなくてよいと思う. 結果として「ロジックを自分の言葉で説明できること」がゴールになり得る. 個人的な感想を書くと,もはやかなり覚えてしまっている気はする. 当面は「学びの軌跡」。合格したときに「合格体験記」としてまとめなおす. この投稿を入り口として各詳細を別記事として書いていく予定. 1セクションを1記事として扱い合計4から5記事で詳細を完結する予定. 当面は合格体験記ではなく勉強の記録なので、資格試験合格のために ここに流入してしまった人は抜けて他読んだ方が学びになると思います. TableauDesktop TableauServerはTableauDesktopで作ったワークブック等をサーバ上で共有する仕組みであることから, 多くの記述においてTableauDesktopの知識が前提となる.TableauDesktopで一通り何ができるかを学んだ方が良い.ポチポチで全てやれちゃう範囲と深さがあればTableauServerの理解には不足ないと思う. 試験の概要 Server Certified Associate試験の概要は以下の通り。 合格基準が75%。ベンダー資格としてはこんなものか、若干高いかも。 択一だけでなく多肢選択も含まれるので、結構落とせない。 問題数80問に対して90分。問題多い。合格体験記を見る限り時間が不足しがちな試験。 試験範囲に以下みたいな記述がある。難易度の調整パラメータかな。 組織は、タスクを効果的かつ効率的に遂行することを、当然のように従業員に期待するようになりました。Tableau は、時間が成功に欠かせないコンピテンシーであると考えており、そのためこの試験にも時間制限が設けられています。 Tableau ServerはLinux,WindowsServerいずれのインストールも対応しているが試験はWindows。 個人的にはLinuxが良いのだけど仕方がない。OS違うのに試験同じにできるのかね..。 オンラインヘルプが参照可能。だが時間無いので記憶の照合くらいにしか使えなさそう。 どこに書いてあるかを記憶しておくことが必要。 Tableu資格の特徴は, 試験開始までの準備でリモート先の試験官と英会話が必要なこと。 提供言語として日本語が用意されているが,これは問題が日本語であるということ. 試験時間: 90 分 合格基準: 正答率 75% 問題数: 80 得点: 自動採点 設問形式: 択一、複数回答、正誤 提供言語: 英語、日本語、中国語 (簡体字)、ドイツ語、フランス語、ポルトガル語 (ブラジル)、スペイン語 (インターナショナル) プラットフォーム: Tableau Server がインストールされた Windows 仮想マシン オンラインヘルプ: 参照可能 Readingはそこそこ問題ないのでこっちは良いのだけど,試験官とSpeaking/Listeningとか不安。 試験本体までのやりとりは以下のような感じらしい。むー。 試験官にweb電話をかける ガイダンスが始まる web通話環境に問題ないことの確認が入る 本人確認:受ける試験が正しいか、パスポートをwebカメラに見せて欲しい,etc 環境確認:PCは充電器に接続されているか、部屋に一人でいるか、机の上を見せて欲しい、途中退出はダメ,etc リモートで指定されたPC環境にログインされ試験開始 なんとか試験本体までたどりつかないと。 ここから先は普通のベンダー試験。 試験範囲 記事執筆時点の試験範囲は以下。 評価するスキル 準備セクション。全体の20%。把握するためにペタペタ貼っていく。 ところどころ,当製品と関係ない一般的な知識が書かれているな..。 ユーザーエクスペリエンス - ユーザーインターフェイス - ナビゲーション トポロジ - クライアントコンポーネントを特定する - サーバーコンポーネントを特定する - 連動する仕組みを説明する バージョン - 以下を理解する: - Tableau Server の現行バージョンを特定する方法 - Tableau Server の最新リリースをどこで入手できるか - Tableau Server のリリースノートをどこで参照できるか ハードウェア最小要件 - 以下を理解する: - RAM 要件 - CPU 要件 - ハードディスク要件 ソフトウェア要件 - サポートされるオペレーティングシステムを列挙する - 以下を理解する: - ブラウザ要件 - メールアラートのオプション - ウィルス対策の懸念事項 - SMTP サーバーを特定する - 起こりうるポートの問題を知る - 専用サーバーの目的と利点を説明する - クラウドで稼働させる際の検討事項を特定する ライセンス発行 - ユーザーベースライセンスを理解する - 異なるライセンスタイプを説明する - ライセンスタイプがどのようにサイトロールにマップするか説明する サーバープロセス - Tableau サービスマネージャーとTableau Serverプロセスをそれぞれ説明する - 以下を理解する: - インストール直後の既定のプロセス数 - 複数インスタンスのプロセス - プロセス間のワークフロー - 分散環境と高可用性環境におけるプロセス - ロードバランサーの目的 データソースの特定 - 必要なポートを特定する - 必要なデータベースドライバーを特定する - 以下の相違点を理解する: - ファイル、リレーショナル、キューブ - 抽出とライブ接続 - パブリッシュされたデータソースの利点を説明する インフラストラクチャネットワーク - ネットワークレイテンシーの意味を理解する - 動的 IP アドレスのリスクを説明する インストールと構成というセクション。全体の25%。 ActiveDirectoryというワードだけで不安になる。 Linux構成が選べるけどWindowsServerを選んだ方が良い気がしてきた。 内容的には妥当な感じ。 インストール - インストールの手順とオプションを理解する: - インストールパス - ゲートウェイポート - アイデンティティストアと SSO のオプションを理解する: - 外部 (Active Directory) とローカル - 信頼できるチケット - SAML - Kerberos と OpenID Connect - 自動ログインオプションの影響を説明する - SSL の設定方法を理解する - 単一マシン環境のインストールに関する Tableau のベストプラクティスを理解する - サイレントインストールを理解する Tableau Server の構成 - キャッシュ設定を理解する - 以下の方法を理解する: - プロセス分散の適用 - メールアラート/サブスクリプションの設定 - オプションで行えるカスタマイズの設定 - 以下を説明する: - サイト構成オプション - ユーザー数 - ストレージ容量 - サイトサブスクリプションの有効化および編集の方法 - プロジェクト構成オプション - グループとユーザーの構成オプション - 誰がユーザーを追加できるかを理解する ユーザーの追加 - ライセンスタイプとサイトロール - 管理者レベル - パブリッシャーレベル - Active Directory またはローカルを介したインポート セキュリティ - 以下のセキュリティ構成を説明する: - サイトレベル - プロジェクトレベル - グループレベル - ユーザーレベル - データソースレベル - ワークブックレベル パーミッション - 以下を理解する: - システムパーミッションの構成 - パーミッション設計の細部 - Tableau のセキュリティモデル - 許可、拒否、なしの違いを説明する 管理というセクション。全体の36%。 たぶんここが本丸だろう。 以下の方法を理解する: - データ接続を維持する - スケジュールを作成する - サブスクリプションを作成、編集、削除する - サーバー分析を実行する - バックアップと復元を完了する - クリーンアップを実行する - ユーザーを追加、削除、非アクティブ化する - ライセンスを更新する - 起動、停止、再起動する - tsm と tabcmd を使用する - REST API を使用する - ログファイルを処理する - 埋め込みを理解する - Desktop ライセンスの使用状況を監視する - ワークブックとデータソースのリビジョン履歴を管理する 以下の方法を説明する: - 複数の方法でサーバーのステータスを確認する - メールアラートを確認する - データドリブンアラートを設定する - 組み込まれた管理ビューを利用する - カスタム管理ビューを作成する - パフォーマンスの記録を作成する - ネストされたプロジェクトを作成する - サイトおよびサイト管理者のオプションを扱う エンドユーザーとシステム管理者の機能の比較 エンドユーザー機能 以下を理解する: - 表の推奨 - ビューとデータソースをパブリッシュする - ワークブックの名前を変更する - Web でビューを操作する - Web 作成と編集 - ビューの共有方法 - データソースの認証 - 抽出のキャッシング トラブルシューティングというセクション。全体の13%。 ブラウザでのサードパーティ Cookie の要件を理解する 以下の方法を理解する: - Tableau ユーザーまたは Tableau 実行サービスアカウントのパスワードをリセットする - レポーティング用のログファイルをパッケージ化する - tsm を使用してサイトのリソースを検証する - 検索インデックスを再構築する - メンテナンス分析レポートを使用する - サポートリクエストを作成する/開く 移行とアップグレードというセクション。全体の6%。 - アップグレードプロセスを理解する - クリーン再インストールを実行する方法と理由を説明する - 異なるハードウェアに移行する方法を説明する - 後方互換性を理解する おわり 正直どんな風に聞かれるのかがわからないことが一番やっかい. オンラインヘルプを参照可能なので暗記する必要はないのだが, 時間を考慮すると覚えておいてオンラインヘルプで確認するというフローが現実的ではないか. 上から順に流していくと気づくことがある. 実際にインストール,セットアップしようとすると知らなければいけないことが並んでいる. 使わないけど知識として並べてある、という他資格とは印象が違う. あまり潰しが効く技術ではないので,良くも悪くも使い方のガイドとして使うべきだろうと思う.

default eye-catch image.

MacでDockerお砂場を作る

docker on vagrant Docker for Macが遅いので,Webのコード書くのはvagrant+ansibleで済ませていたのだけれども, vagrant上にdockerを立てることでLinux上で走らせるのと同レベルの速度を得られるようなので, docker on vagrantを立ててdockerに入門してみる。 Web開発していない人から見ると,なんでdocker使わないの? ってことなのだが, 気持ちは以下の通り. 工夫無しだと1度試したら2度とやりたくないレベルで使い物にならない. Docker For Macが遅い:対策の実験 Macのdockerが遅いストレスから解放されよう ansibleで自動化してたから手間に気づかなかったけど, 公式がイメージ配ってるんだから,手間なしなのはdocker. 本番環境と開発環境を揃えにくいかなとも思うけど, AWS ECS的なものもあって,そもそもdockerだけで完結する世界が主流になりそうな感. docker on vagrantで遅さを回避できるので, 言い訳してないでアップデートしていく.. なぜ遅いのか Docker for Macは, AlpineLinuxベースのHyperkitVMの上で透過的にContainerを扱う. Mac上でDockerコマンドを実行すると,透過的にHyperkitVM上に反映される. Macの上で直接Containerが動いているのではなくこのVMの上でContainerを動かしている. HostとGuestのファイルシステムをマウントする観点ではvagrantも同じで, 実際,VagrantfileでマウントオプションとしてNFSを指定したとしてもNativeよりかなり遅い. ファイルシステムの対称性がある分,vagrantはHostとGuestをSyncする方法に手を入れやすく, HostとGuestのファイルシステムをNativeと同等レベルの速度でSyncする手段を導入できる. この仕組みによると, vagrantの上でDockerを動かすパフォーマンスがNative並に速くなる. Mutagen HostとGuestのファイルシステムをSyncするためにMutagenを利用する. Overviewによると,Mutagenは双方向の同期ツールで,低レイテンシをうたっている. もともとHostToGuestというよりはLocalToCloudの統合を目指している感じ. キーボードを打ってから反映されるまでのラグが気になる, とかOSが違う場合のアレコレ(permissionとかシンボリックリンックとか),とか, そういうところの解消を目指している様子. エージェントレス,TCP,でリモートへの導入コストが少ないのが良い. VagrantにはMutagen over SSHの形を取る. インストール手順 こちらが参考になりました。わかりやすく,手順通りやれば10分かかりません. Vagrantを使う「Mac最速のDocker環境」を初心者向けに解説【遅いMac for Dockerを卒業】 とりあえず箱だけ作った.Laravelだと分かりづらいのでRailsで試したところ激しく速かった. 副次的な効果として、Macを汚さないのでお砂場にぴったり.

default eye-catch image.

微分フィルタだけで時系列データの過渡応答終了を検知したい

ある値の近傍を取る状態から別の値の近傍を取る状態へ遷移する時系列データについて、 どちらの状態でもない過渡状態を経て状態が遷移するみたい。 今回知りたいのは理論ではなく、定常状態に遷移したことをいかにして検知するかという物理。 まぁいかようにでも検知できなくもないけれども、非定常状態の継続時間は不明であるという。 なるべく遅れなしに定常状態への遷移を検知したい。 ARモデルとかMAモデルとかの出番ではない。 DeepLearningとかやってる暇はないw 過去の微小時間内に含まれるデータだけから次が定常状態なのかを検知したい。 前状態と後状態のベースラインがどんな値であっても、 それを考慮することなしに過渡応答の後にくる定常状態の先頭を検知できる、という特徴がほしい。 移動平均だとベースラインがケースごとに変わるので扱いづらい。 微分であればベースラインがゼロに揃うのが良いな、と思った。 結局、今度はゼロへの収束を検知する問題に差し代わるだけだけども、 前ラインと後ラインの2つも見ないでも、確実に楽にはなっている。 微分するとノイズが増えるが...。 微分値が上下の閾値を超えたラインから先、 ゼロ収束の判定条件が一定時間継続した最初のデータポイントがソコ。 これは過渡状態の終了検知なだけだから、それとRawデータの変化をみる。

default eye-catch image.

ansibleでaws-cliをインストールする (+S3)

やりたいことは以下の2つ。 ansibleでaws-cliをインストールする ansibleでインストールしたaws-cliでs3コマンドを打てるようにする なお、相手には既にpipがインストールがしてあるものとします。 ansibleを実行するために最小構成でPythonをインストールしたもののpipは入れていない、 という状況であれば、先にpipをインストールする必要があります。 リージョン、S3のkey,secretは仮に以下とします。 事前にAWSのコンソールで設定,取得してください。 region: ap-northeast-1 s3.key: AHJKOKODAJOIFAJDJDIOA s3.secret: AugioaiARJOIfjop20FJIOADOiFJAODA ファイル達 構成は以下の通りです。(※)のファイルが核心です。 stagingとかになってますが、もちろん成立する範囲で修正してください。 ├──provision.yml (※) ├──ansible.cfg ├──group_vars │ └───staging.yml (※) ├──hosts | └───staging ├──host_vars | └───default.yml └──roles └─awscli (※) ├─templates | └─config.conf.j2 | └─credentials.conf.j2 └─tasks └─main.yml group_vars/staging.ymlに設定を書きます。 user: ubuntu s3: region: ap-northeast-1 # S3.region key: AHJKOKODAJOIFAJDJDIOA # S3.key secret: AugioaiARJOIfjop20FJIOADOiFJAODA # S3.secret roles/awscli/templates/config.conf.j2にaws-cliの設定を書きます。 s3.regionが評価され値が入ります。相手の~/.aws/configに配置します。 [default] output = json region = {{s3.region}} roles/awscli/templates/credentials.conf.j2にs3の設定を書きます。 s3.keyとs3.secretが評価され値が入ります。相手の~/.aws/credentialsに配置します。 [default] aws_access_key_id = {{s3.key}} aws_secret_access_key = {{s3.secret}} rokes/awscli/tasks/main.ymlに状態を定義します。 内容は以下の通りです。 1) aws-cliがpip installされた状態 2) ~/.aws/以下に設定ファイルがコピーされた状態 --- - name: install aws-cli pip: name: awscli - name: create .aws dir file: dest: /home/{{user}}/.aws state: directory owner: \"{{user}}\" group: \"{{user}}\" - name: copy config template: src: config.conf.j2 dest: /home/{{user}}/.aws/config owner: \"{{user}}\" group: \"{{user}}\" - name: copy credential template: src: credential.conf.j2 dest: /home/{{user}}/.aws/credentials owner: \"{{user}}\" group: \"{{user}}\" ~ ~ Playbook(provision.yml)は以下の通りです。 - hosts: remote_machine remote_user: \"{{ user }}\" gather_facts: \"{{ check_env | default(True) }}\" become: yes become_method: sudo roles: - { role: awscli } 実行結果 Playbookを実行します。 $ ansible-playbook -i hosts/staging provisiong.yml 相手のユーザディレクトリに.awsというディレクトリが作られ、中にファイルが作られます。 ~/ └─.aws ├─config └─credentials 相手側でaws s3 lsコマンドを打って設定しろと言われなければ成功です。 $ aws s3 ls 2019-10-20 11:11:20 hogehoge おわり。

default eye-catch image.

やってみた Markov chain Monte Carlo methods, MCMC , gibbs sampling

[mathjax] マルコフ連鎖モンテカルロ法。2変量正規分布からGibbs Samplingする方法を考えてみました。 式を流してもよくわからないので、行間ゼロで理解できるまで細切れにして書いてみます。 Gibbs Sampling 無茶苦茶一般的に書かれている書籍だと以下みたいになっている。 ステップごとに(theta=(theta_1,theta_2,cdots,theta_n))の各要素を、 その要素以外の要素の条件付き確率でランダムに発生させる。 begin{eqnarray} theta^0 &=& (theta_1^0,theta_2^0,cdots,theta_n^0) \\ theta_i^{t+1} &sim& p(theta_i|theta_1^{t+1},cdots,theta_{i-1}^{t+1},theta_{i+1}^t,cdots,theta_n^t) end{eqnarray} 2次元空間であれば、ある点を決める際に、 片方の変数(theta_1)を固定して条件付き確率(P(theta_2|theta_1))を最大にするパラメタ(hat{theta_2})を決める。 その時点で((theta_1,hat{theta_2}))が決まる。 次は変数(hat{theta_2})を固定して条件付き確率(P(theta_1|hat{theta_2}))を最大にするパラメタ(hat{theta_1})を決める。 2次元正規分布であれば、片方の確率変数を固定したときの条件付き確率が1変数の正規分布になるから、 これがすごくやりやすい。 Gibbs Samplingは、このように条件付き確率を計算できる必要がある。 2変量正規分布の条件付き確率 2変量正規分布の片方の確率変数を固定すると1変数の正規分布が出てきます。 山の輪切りにして出てきた正規分布の母数を調べたいのですが、導出が無茶苦茶大変そうです。 出てきた正規分布の母数について式変形すると出てくるようです。こちらを参考にさせて頂きました。 この関係式を利用してひたすら式変形していきます。 begin{eqnarray} f(x|y) &=& frac{f(x,y)}{f(x)} end{eqnarray} 今、確率変数(y=y\')を固定し確率変数(x)の正規分布を考えます。 2変量正規分布の分散共分散行列が(sum)であるとします。 begin{eqnarray} sum &=& begin{pmatrix} sigma_{xx} & sigma_{xy} \\ sigma_{yx} & sigma_{yy} end{pmatrix} end{eqnarray} 出てくる正規分布の平均は以下となります。 確率変数が(x)なのに固定した(y)が出てくるのがポイント。 begin{eqnarray} mu\' = bar{x} + frac{sigma_{xy}}{sigma_{yy}} (y\'-bar{y}) end{eqnarray} また、出てくる正規分布の分散は以下となります。 begin{eqnarray} sigma\'^2 &=& sigma_{xx} - frac{sigma_{xy}}{sigma_{yy}} sigma_{yx} end{eqnarray} Python実装例 実際にPythonコードにしてみた図です。2変量正規分布の条件付き確率さえわかってしまえば あとはコードに落とすだけです。 import numpy as np import matplotlib.pyplot as plt import scipy.stats as stats n_dim = 2 def gibbs_sampling(mu, sigma, sample_size): samples = [] start = [0, 0] samples.append(start) search_dim = 0 for i in range(sample_size): search_dim = 0 if search_dim == n_dim-1 else search_dim + 1 prev_sample = samples[-1][:] s11 = sigma[search_dim][search_dim] s12 = sigma[search_dim][search_dim - 1] s21 = sigma[search_dim -1 ][search_dim] s22 = sigma[search_dim - 1][search_dim - 1] mu_x = mu[search_dim] mu_y = mu[search_dim-1] _y = prev_sample[search_dim - 1] new_mean = mu_x + s12/float(s22) * (_y - mu_y) new_sigma = s11 - s12/float(s22) * s21 sample_x = np.random.normal(loc=new_mean, scale=np.power(new_sigma, .5), size=1) prev_sample[search_dim] = sample_x[0] samples.append(prev_sample) return np.array(samples) nu = np.ones(2) covariance = np.array([[0.5, 0.5], [0.5, 3]]) samples = gibbs_sampling(nu, covariance, 1000) fig, ax1 = plt.subplots(figsize=(6, 6)) ax1.scatter(sample[:, 0], sample[:, 1], marker=\"o\", facecolor=\"none\", alpha=1., s=30., edgecolor=\"C0\", label=\"Samples\" ) 実行結果

default eye-catch image.

最尤推定とベイズの定理とMAP推定

[mathjax] 最尤推定とMAP推定とベイズの定理は繋がっていたので、 記憶が定かなうちに思いの丈を書き出してみるテスト。俯瞰してみると面白い。 あるデータ達(x)が観測されていて、それらは未知のパラメータを持つ確率分布から発生している。 観測されたデータ達(x)を使って、それらのデータを発生させたモデルのパラメータを推定したい。 確率密度関数の中に2つの変数があって。 片方を定数、片方を確率変数として扱うことで2通りの見方ができる。 例えば(n)回のコイントスで(k)回表が出る確率が(theta)だとしてベルヌイ分布の確率密度関数は (k)と(theta)のどちらが確率変数だとしても意味がある。 begin{eqnarray} f(k;theta)=theta^k (1-theta)^{n-k} end{eqnarray} 表が出る確率(theta)が定数だと思って、確率変数(x)の確率密度関数と思う。 単なる確率変数(x)の確率密度関数の中に(theta)という定数がある。尤度。 尤度は確率変数(x)の確率密度関数!。 begin{eqnarray} p(X=x|theta) end{eqnarray} 尤度(p(x|theta))を最大にする(theta)を推定するのが最尤推定。 begin{eqnarray} newcommand{argmax}{mathop{rm arg~max}limits} hat{theta} = argmax_{theta} p(X=x|theta) end{eqnarray} 事後確率と事前確率には関係があって以下のようになる。ベイズの定理。 begin{eqnarray} p(theta|x)=frac{p(x|theta) p(theta)}{p(x)} end{eqnarray} ちなみに、(p(x))は以下のようにしておくとわかりやすい。 同時確率と周辺確率の関係。表を書いて縦、横がクロスするところが同時確率だとして、 縦、横いずれかの方向に同時確率を足し合わせる操作にあたるらしい。 なにか確率変数が独立でなければならない、というのは気にしない。 begin{eqnarray} p(x) = int p(x,theta) dtheta end{eqnarray} なので以下みたいに書き直せる。最後の比例のところは...。 左辺は事後確率分布、右辺は尤度と事前確率分布の積!!。 begin{eqnarray} p(theta|x) &=& frac{p(x|theta) p(theta)}{p(x)} \\ &=& frac{p(x|theta) p(theta)}{int p(x,theta) dtheta} \\ &propto& p(x|theta) p(theta) end{eqnarray} (p(theta))は確率変数(theta)の確率分布。尤度(p(x|theta))は(theta)に対して定数。(x)に対して変数。 ということで、右辺は確率分布(p(theta))を尤度(p(x|theta))を使って変形した確率分布。 で、左辺の(p(theta|x))は右辺の(p(x|theta) p(theta))を定数倍した確率分布。 データを観測していない状態で立てた(p(theta))があって、 観測したデータを使って求めた尤度(p(x|theta))が得られたことで、 左辺の(p(theta|x))が得られた、という状況。 (p(theta|x))は確率変数(theta)の確率分布なので、 最尤推定とベイズの定理を俯瞰してみると、最尤推定が点推定である一方で、 ベイズの定理では確率分布が得られるという具合で異なる。 (観測値が極端なデータだったとき、最尤推定は極端な推定結果が得られるだけだけれども、 ベイズの定理で得られる事後確率分布は確率分布なので様子がわかる..??) 事後確率分布を最大化する(theta_{MAP})を求めるのがMAP推定。(点推定) begin{eqnarray} hat{theta_{MAP}} = argmax_{theta} p(theta|x) end{eqnarray} 尤度をかけて得られた事後分布と同じ形になる便利な分布があって、 観測データ達の分布と対応して決まっている(共役事前分布)。 ベルヌイ分布の共役事前分布はベータ分布。

default eye-catch image.

正規分布に従う確率変数の二乗和はカイ二乗分布に従うことを実際にデータを表示して確かめる

以前、\"正規分布に従う確率変数の二乗和はカイ二乗分布に従うことの証明\"という記事を書いた。 記事タイトルの通り、正規分布に従う確率変数の二乗和はカイ二乗分布に従う。 [clink url=\"https://ikuty.com/2018/08/01/chi-square-distribution\"] 実際にデータを生成して確かめてみる。 まずは、scipi.stats.chi2.pdfを使って各自由度と対応する確率密度関数を書いてみる。 \"pdf\" ってPortableDocumentFormatではなく、ProbabilityDensityFunction(確率密度関数)。 import numpy as np import matplotlib.pyplot as plt from scipy import stats # 0から8まで1000個のデータを等間隔で生成する x = np.linspace(0, 8, 1000) fig, ax = plt.subplots(1,1) linestyles = [\':\', \'--\', \'-.\', \'-\'] deg_of_freedom = [1, 2, 3, 4] for k in deg_of_freedom: linestyle = linestyles[k-1] ax.plot(x, stats.chi2.pdf(x, k), linestyle=linestyle, label=r\'$k=%i$\' % k) plt.xlim(0, 8) plt.ylim(0, 1.0) plt.legend() plt.show() 定義に従って各自由度ごとに2乗和を足し合わせてヒストグラムを作ってみる。 (ループのリストが自由度) cum = 0 for i in [1,2,3,4]: # 標準正規分布に従う乱数を1000個生成 x = np.random.normal(0, 1, 1000) # 2乗 x2 = x**2 cum += x2 plt.figure(figsize=(7,5)) plt.title(\"chi2 distribution.[k=1]\") plt.hist(cum, 80) 全部k=1ってなってしまった...。左上、右上、左下、右下の順に1,2,3,4。 頻度がこうなので、各階級の頻度の相対値を考えると上記の確率密度関数の形になりそう。 k=1,2が大きくことなるのがわかるし、3,4と進むにつれて変化が少なくなる。

default eye-catch image.

PHPで統計アプリを作れるか否か

LaravelをAPIサーバにして同期的にsklearnのPCAを実行するアプリを作ってみました。 jQyery/bootstrap/chart.jsがフロント、APIサーバはLaravel+MySQL。 Laravel製APIがGET/POSTに対してPythonコードを実行します(Shellで...)。 exec()でPythonを起動するため無茶苦茶重いし、 ろくにエラーハンドリングできません。 結論から書けば同期的なアプリをこの構造で作るのは無理があります。 バックエンドが無茶苦茶重くてどうせバッチ実行になるのであれば、 上記の問題は結構問題なくなって、これでも良いかなと思い始めます。 MS系のInteroperabilityで、多言語が動的に結合するやつがありますが、 あんな感じでLL言語をglueできれば楽なのになと思います。 PSRの多言語拡張みたいなやつで、PHPからPythonのクラスを使うとか...