Skip to main content

Markov Tensor Module

Project description

FXTensor

Numpy を利用してマルコフ・テンソルを効率的に計算するための FXTensor クラスです。

インストール

pip install fxtensor-salmon

このクラスは、確率的な事象の連鎖をテンソルとして表現し、それらの結合や周辺化といった操作を可能にします。これにより、複雑な確率モデルを体系的に扱うことができます。

テンソル計算

  • 結合演算 (composition): 2つのテンソルを結合します(行列積の一般化)。
  • テンソル積 (tensor_product): 2つのテンソルを並列に組み合わせます。
  • 部分結合 (partial_composition): テンソルの一部だけを結合します。
  • 同時化 (jointification): 2つの状態から同時確率分布を生成します。
  • 条件化 (conditionalization): 同時確率分布から条件付き確率分布を求めます。
  • 第一・第二周辺化 (first_marginalization, second_marginalization): 特定の確率変数を消去(積分)します。

テンソル生成(クラスメソッド)

  • 恒等射/単位テンソル (unit_tensor): 何も変化させないテンソルを作成します。
  • マルコフ・テンソル Δ (delta): 状態を複製(コピー)するテンソルを作成します。
  • マルコフ・テンソル ! (exclamation): 状態を破棄(無視)するテンソルを作成します。
  • マルコフ・テンソル Xa,b (スワップ) (swap): 2つの状態を入れ替えるテンソルを作成します。

はじめに

本スクリプトにおける計算の基本

次のような行と列にインデックスを持つ確率の表(行列)を考えます。各列の合計は1になるものとします。これは、ある列のインデックスで表現される事象が起きたという条件下で、ある行のインデックスで表現される事象が起きる条件付き確率を表します。

例として、次のような表1と表2を示します。

表1. 黒、または白のボールが混在した容器からボールを1個選んだ後、その色に応じて赤、緑、青のランプがランダムに発光する確率。

  黒 白
-----------
赤  0.1 0.2
緑  0.2 0.3
青  0.7 0.5

表2. 赤、緑、青のランプが発光した際に、別の白色ランプが光るかどうかの確率。

            赤 緑 青
-----------------------------------------
白色のランプが光る    0.8 0.9 0.9
白色のランプが光らない  0.2 0.1 0.1

ここで、表1と表2の結合を考えます。これは、ボールを選んでから最終的に白色ランプがどうなるかまでの一連の確率を計算することに対応します。

例えば、「黒ボールを選び」→「赤いランプが光り (確率0.1)」→「その結果、白色ランプが光る (確率0.8)」という一連の事象が起きる確率は 0.1 * 0.8 = 0.08 です。

同様に、ランプが緑、青の場合も計算し、全て足し合わせると、「黒ボールを選んだ場合に、最終的に白色ランプが光る確率」が求まります。 (0.1 * 0.8) + (0.2 * 0.9) + (0.7 * 0.9) = 0.08 + 0.18 + 0.63 = 0.89

この計算をすべての組み合わせで行うと、次の表3が得られます。

表3. ボールの色を条件として、最終的に白色ランプが光るかどうかの確率。

            黒  白
-----------------------------------------
白色のランプが光る    0.89   0.88 (22/25)
白色のランプが光らない  0.11   0.12 (3/25)

本スクリプト FXTensor クラスを用いると、この計算は composition メソッドで直感的に実行できます。

import numpy as np
from fxtensor_salmon import FXTensor # FXTensor クラスをインポート

# -- ラベルとインデックスの対応 --
# 状態空間の定義
ball_domain = ['黒', '白']
lamp_colors = ['赤', '緑', '青']
white_lamp_codomain = ['白色のランプが光る', '白色のランプが光らない']

def main():
    # --- 表1をFXTensorで表現 ---
    # profileは[入力の次元], [出力の次元]
    # 入力: ボールの色 (2種類)、出力: ランプの色 (3種類)
    profile_a = [[len(ball_domain)], [len(lamp_colors)]]
    # データはNumpy配列で表現。P(出力|入力)の形
    # data[入力インデックス, 出力インデックス]
    data_a = np.array([
        # 入力が'黒' (インデックス0) の場合
        [0.1, 0.2, 0.7],  # 出力: [P(赤|黒), P(緑|黒), P(青|黒)]
        # 入力が'白' (インデックス1) の場合
        [0.2, 0.3, 0.5]   # 出力: [P(赤|白), P(緑|白), P(青|白)]
    ])
    tensor_a = FXTensor(profile_a, data=data_a)

    # --- 表2をFXTensorで表現 ---
    # 入力: ランプの色 (3種類)、出力: 白色ランプの状態 (2種類)
    profile_b = [[len(lamp_colors)], [len(white_lamp_codomain)]]
    data_b = np.array([
        # 入力が'赤' (インデックス0) の場合
        [0.8, 0.2],  # 出力: [P(光る|赤), P(光らない|赤)]
        # 入力が'緑' (インデックス1) の場合
        [0.9, 0.1],  # 出力: [P(光る|緑), P(光らない|緑)]
        # 入力が'青' (インデックス2) の場合
        [0.9, 0.1]   # 出力: [P(光る|青), P(光らない|青)]
    ])
    tensor_b = FXTensor(profile_b, data=data_b)

    # --- テンソルの結合 ---
    # tensor_a の出力と tensor_b の入力が接続される
    result_tensor = tensor_a.composition(tensor_b)

    # --- 結果の表示 ---
    print("結合後のプロファイル:", result_tensor.profile)
    print("結合後のデータ (Numpy配列):\n", result_tensor.data)
    print("\n--- 結果の解釈 ---")
    for i, ball_color in enumerate(ball_domain):
        for j, lamp_status in enumerate(white_lamp_codomain):
            prob = result_tensor.data[i, j]
            print(f"P({lamp_status} | {ball_color}) = {prob:.2f}")

if __name__ == "__main__":
    main()

上記のコードを実行すると、composition によって2つの確率過程が結合され、次のような実行結果を得ます。

結合後のプロファイル: [[2], [2]]
結合後のデータ (Numpy配列):
 [[0.89 0.11]
 [0.88 0.12]]

--- 結果の解釈 ---
P(白色のランプが光る | 黒) = 0.89
P(白色のランプが光らない | 黒) = 0.11
P(白色のランプが光る | 白) = 0.88
P(白色のランプが光らない | 白) = 0.12

行と列のラベルがそれぞれ複数ある場合

この考え方は、入出力が複数の要素の組(タプル)で表される、より高次元のテンソルにも拡張できます。

例えば、「(ボールの色, カードの色)」という入力に対して、「(ランプ1の色, ランプ2の色)」という出力が得られるような、より複雑な確率過程も同様に扱うことができます。この場合、データは2次元の行列ではなく、4次元以上の numpy 配列で表現されます。composition などの演算は、これらの高次元配列に対しても同様に機能します。

以下の表4、5、6はそのような例です。

表4. (ボール, カード) → (ランプ色1, ランプ色2) の確率

    (黒, 金) (黒, 銀)(白, 金)(白, 銀)
--------------------------------------------
(赤, 桃)  0.1    0.1   0.1   0.1 
(赤, 紫)  0.1    0.1   0.1   0.1
(緑, 桃)  0.1    0.1   0.1   0.5
(緑, 紫)  0.1    0.1   0.5   0.1
(青, 桃)  0.1    0.5   0.1   0.1
(青, 紫)  0.5    0.1   0.1   0.1
--------------------------------------------

表5. (ランプ色1, ランプ色2) → (白色ランプ1の状態, 白色ランプ2の状態) の確率

                            (赤, 桃) (赤, 紫)(緑, 桃) (緑, 紫)(青, 桃) (青, 紫)
-----------------------------------------------------------------------------------------------------------
(白色のランプ 1 が光る, 白色のランプ 2 が光る)      0.1   0.4   0.3   0.2   0.1   0.2 
(白色のランプ 1 が光る, 白色のランプ 2 が光らない)    0.2   0.1   0.4   0.3   0.1   0.6
(白色のランプ 1 が光らない, 白色のランプ 2 が光る)    0.3   0.2   0.1   0.4   0.2   0.1
(白色のランプ 1 が光らない, 白色のランプ 2 が光らない)  0.4   0.3   0.2   0.1   0.6   0.1
-----------------------------------------------------------------------------------------------------------

これらのテンソルを FXTensor クラスで表現し、composition を用いて結合することで、最終的な結果である表6を導出できます。

表6. (ボール, カード) → (白色ランプ1の状態, 白色ランプ2の状態) の確率

                            (黒, 金) (黒, 銀)(白, 金)(白, 銀)
------------------------------------------------------------------------------------------------
(白色のランプ 1 が光る, 白色のランプ 2 が光る)      21/100  17/100  21/100  1/4
(白色のランプ 1 が光る, 白色のランプ 2 が光らない)    41/100  21/100  29/100  33/100
(白色のランプ 1 が光らない, 白色のランプ 2 が光る)    17/100  21/100  29/100  17/100
(白色のランプ 1 が光らない, 白色のランプ 2 が光らない)  21/100  41/100  21/100  1/4
------------------------------------------------------------------------------------------------

この計算は、FXTensorprofile[[2, 2], [3, 2]] のように複数の次元を指定し、data に4階のテンソル(4次元のNumpy配列)を渡すことで実現されます。

JSON ファイルの入出力例

import numpy as np
from fxtensor import FXTensor

json_data = {
  "profile": [[2], [2]],
  "strands": [
    {"from": [0], "to": [0], "weight": 0.3},
    {"from": [0], "to": [1], "weight": 0.7},
    {"from": [1], "to": [0], "weight": 0.5},
    {"from": [1], "to": [1], "weight": 0.5}
  ]
}

# JSONデータからテンソルを作成
stochastic_map = FXTensor.from_json(json_data)

print(stochastic_map)
# 出力予測: FXTensor(profile=[[2], [2]], shape=(2, 2))

print(stochastic_map.data)
# 出力予測:
# [[0.3 0.7]
#  [0.5 0.5]]

参考文献

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fxtensor_salmon-0.1.1.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fxtensor_salmon-0.1.1-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file fxtensor_salmon-0.1.1.tar.gz.

File metadata

  • Download URL: fxtensor_salmon-0.1.1.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for fxtensor_salmon-0.1.1.tar.gz
Algorithm Hash digest
SHA256 47789eacf78d19631f181436cd494a4c0c3729608286310aa3804df6625390f2
MD5 ff767946b51a9051e04d8036203a8516
BLAKE2b-256 775ed48b18552617d3c8dfafea683d58882afde48f3e793805c8a6668bf49ba3

See more details on using hashes here.

File details

Details for the file fxtensor_salmon-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fxtensor_salmon-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 41c8ecb2ae809516928ce55486754b0a5be8402c9806f66d9c2168d9e1285739
MD5 b6eb6d1a8049b8d0fb2b6a60f6c468ae
BLAKE2b-256 ba3e4f1e1f59f3361677ef49b474933335122280eadd1a6afaf7571544a2d385

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page