{"id":22273511,"url":"https://github.com/dfleta/hidden-markov-models","last_synced_at":"2025-03-25T16:41:50.204Z","repository":{"id":235535180,"uuid":"790828457","full_name":"dfleta/hidden-markov-models","owner":"dfleta","description":"Código curso Artificial Intelligence with Python sobre cadenas de Markov y hidden Markov models para el módulo de Modelos de Inteligencia Artificial del curso de especialización en IA y Big Data del IES de Teis","archived":false,"fork":false,"pushed_at":"2025-01-10T00:15:47.000Z","size":11325,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-30T14:44:55.246Z","etag":null,"topics":["ai","hidden-markov-model","markov-chain","markov-models","maximum-likelihood-estimation","rock-paper-scissors","stationary-distributions"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dfleta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-23T15:51:28.000Z","updated_at":"2025-01-10T00:15:51.000Z","dependencies_parsed_at":"2024-05-09T13:34:39.418Z","dependency_job_id":"9836342f-99ca-4c0e-82de-f114e1e855a5","html_url":"https://github.com/dfleta/hidden-markov-models","commit_stats":null,"previous_names":["dfleta/hidden-markov-models"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fhidden-markov-models","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fhidden-markov-models/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fhidden-markov-models/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fhidden-markov-models/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dfleta","download_url":"https://codeload.github.com/dfleta/hidden-markov-models/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245501805,"owners_count":20625855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","hidden-markov-model","markov-chain","markov-models","maximum-likelihood-estimation","rock-paper-scissors","stationary-distributions"],"created_at":"2024-12-03T13:12:58.292Z","updated_at":"2025-03-25T16:41:50.185Z","avatar_url":"https://github.com/dfleta.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Markov Chains - Hidden Markov Models\n====================================\n\nCódigo del curso [CS50’s Introduction to Artificial Intelligence with Python](https://cs50.harvard.edu/ai/2024/), _lecture 2 \"uncertainty\"_, refactorizado a la nueva api de pomegranate v1.0.4 [jmschrei](https://pomegranate.readthedocs.io/en/latest/tutorials/B_Model_Tutorial_4_Hidden_Markov_Models.html)\n\n## Instalación\n\nEs necesario el uso del paquete [Pomegranate](https://pomegranate.readthedocs.io/en/stable/index.html):\n\n\u003e Pomegranate is a python package which implements fast, efficient, and extremely flexible probabilistic models ranging from probability distributions to Bayesian networks to mixtures of hidden Markov models.\n\n`python -m venv venv`\n\n`source venv/bin/activate`\n\nInstalar la versión estricta de pomegranate `v1.0.4`:\n\n`pip install -r requirements.txt`\n\no\n\n`pip install pomegranate`\n\n## Uso\n\n### Markov Chain\n\nVamos a construir una cadena de Markov donde las variables aleatorias siguen la suposición de Markov: el estado actual depende sólo de un número finito de estados previos.\n\nSupongamos que podemos definir la probabilidad de que mañana sea un dia soleado o llueva en función de cómo está el tiempo hoy. \n\nDefinimos el modelo de transición de nuestro ejemplo de este modo:\n\nProbabilidades iniciales de lluvia (R) y sol (S) en el primer día de la serie:\n\n$$ P(R_0) = 0.5 $$\n$$ P(S_0) = 0.5 $$\n\nEl modelo de transiciones es este:\n\n|  Hoy  | Mañana|       |\n| :---: | :---: | :---: |\n|       |  sol  | lluvia|\n| sol   |  0.8\t|  0.2  |\n| lluvia|  0.3  |   0.7 |\n\nCalculamos un posible serie de predicciones sobre el estado del tiempo dadas la probabilidades iniciales y el modelo de transiciones:\n\n```python\n$ python markov_chain/model.py\n\nNumero de muestras: 50\nrain -\u003e rain -\u003e rain -\u003e sun -\u003e rain -\u003e sun -\u003e rain -\u003e sun -\u003e\nrain -\u003erain -\u003e rain -\u003e rain -\u003e rain -\u003e sun -\u003e sun -\u003e sun -\u003e\nsun -\u003e sun -\u003e sun -\u003e sun -\u003e sun -\u003e rain -\u003e rain -\u003e sun -\u003e \nsun -\u003e sun -\u003e sun -\u003e rain -\u003e rain -\u003e rain -\u003e sun -\u003e sun -\u003e \nsun -\u003e sun -\u003e rain -\u003e rain -\u003e rain -\u003e rain -\u003e rain -\u003e sun -\u003e\nsun -\u003e rain -\u003e sun -\u003e sun -\u003e sun -\u003e rain -\u003e rain -\u003e rain -\u003e sun -\u003e sun\n```\n\n### Hidden Markov Model\n\nEn muchas ocasiones el estado del mundo es desconocido, pero de algún modo el agente inteligente es capaz de percibir información sobre el mundo mediante sus sensores. A partir de estas observaciones podemos inferir determinados aspectos del estado oculto, ya que dicho estado oculto influencia las observaciones.\n\nVamos a construir un modelo oculto de Markov en el que deduciremos el estado del tiempo en función de las observaciones que realiza nuestro agente inteligente sobre si las personas que entran en un edificio portan paragüas.\n\n\nLas probabilidades de emisión son las siguientes:\n\n| Estado| Observación|       |\n| :---: | :---------:| :---: |\n|       |  paraguas ![](./doc/paraguas.png)  | sin paraguas ![](./doc/no_paraguas.png) |\n| sol   |  0.2\t     |  0.8  |\n| lluvia|  0.9       |  0.1  |\n\nEstas probabilidades de emisión dependen únicamente del estado del tiempo hoy. \n\nProporcionamos al modelo una serie de observaciones y nos devuelve la secuencia de estados más probable (la explicación más probable).\n\n```python\n$ python hmm/model.py\n\nDimensiones del array de observaciones: (1, 9, 1)\numbrella -\u003e rain\numbrella -\u003e rain\nno_umbrella -\u003e sun\numbrella -\u003e rain\numbrella -\u003e rain\numbrella -\u003e rain\numbrella -\u003e rain\nno_umbrella -\u003e sun\nno_umbrella -\u003e sun\n```\n\n## Matemática de los Hidden Markov Models\n\nSi $X_i$ son los estados ocultos y $Z_i$ son las emisiones, las expresiones de la teoría de probabilidad que conforman los parámetros de entrada de nuestro modelo son:\n\n[1] **Regla de Bayes**:\n\n$$ P(X_1 | Z_1) = \\frac {P(Z_1 | X_1) P(X_1)} {P(Z_1)} = \\alpha P(Z_1 | X_1) P(X_1) $$\n\n[2] **Probabilidad total**:\n\n$$ P(X_2) = \\sum_{X_1} P(X_1)P(X_2|X_1) $$\n\ndonde $P(X_2|X_1)$ es la distribución de probabilidad del siguiente estado.\n\n[3] La(s) distribuciones de **probabilidad**(es) del(os) estado(s) **inicial**(es):\n\n$$ P(X_0) $$\n\n### Ejercicio HMM\n\nAplicando las expresiones [1], [2] y [3] del epígrafe anterior, resuelve el siguiente problema.\n\nSe trata de uno de los problemas propuestos en el MOCC sobre IA por Sebastian Thrun para explicar cómo se calculan las probabilidades de los estados ocultos dadas las observaciones.\n\nSupongamos que queremos construir un modelo oculto de Markov para calcular el estado del tiempo en función del estado de humor de la población. En función de las observaciones sobre si la gente está feliz o gruñona deduciremos las probabilidades de que el día esté soleado o lluvioso.\n\nEn la figura se describen las probabilidades de transición entre los estados _Rainy_ $R$ y _Sunny_ $S$. Se proporcionan también las probabilidades de las emisiones _Happy_ $H$ y _Grumpy_ $G$. \n\n![modelo de transicion y de emisiones](./doc/HMM_ejercicio.png \"modelo de transicion y de emisiones\")\n\nSe pide calcular la probabilidad de que el día 1 sea lluvioso $R_1$ en función de que la observación arroje que la gente está contenta ese día $H_1$:\n\n$$ P(R_1|H_1)  $$\n\ndadas las probabilidades iniciales de los estados:\n\n$$ P(R_0) = 1/2 $$\n$$ P(S_0) = 1/2 $$\n\nDispones de este ejercicio resuelto en este vídeo, \ncomo se indica en la figura:\n\n[![\"Ejercicio probabilidades enunciado\"](./doc/HMM_ejercicio_probabilidades_enunciado.png \"Ejercicio probabilidades enunciado\")](https://drive.google.com/file/d/1b_URIpShIw3ta1TGi5a6VJa2A9dZXeTn/view?usp=drive_link)\n\n#### Solución\n\nEn la regla de Bayes [1] sustituímos el estado oculto $X_i$ por el estado $R_1$ y la emisión u observación $Z_i$ por $H_1$:\n\n$$ P(X_1 | Z_1) = \\frac {P(Z_1 | X_1) P(X_1)} {P(Z_1)} $$\n\n\n$$ P(R_1|H_1) = \\frac {P(H_1 | R_1) P(R_1)} {P(H_1)} $$\n\nDebemos calcular, por tanto, las probalidades:\n\n* $P(H_1 | R_1)$\n* $P(R_1)$\n* $P(H_1)$\n\n##### $P(H_1 | R_1)$\n\nLa probabilidad de que la gente sea feliz si el día es lluvioso, o $P(H_1 | R_1)$, se lee directamente en la figura: $0.4$\n\n##### $P(R_1)$\n\nPara el cálculo de la probabilidad de que el día 1 sea lluvioso $P(R_1)$ usamos el teorema de la probilidad total [2]:\n\n$$ P(X_2) = \\sum_{X_1} P(X_1) P(X_2|X_1) $$\n\n$$ P(R_1) = P(R_1|R_0) P(R_0) + P(R_1|S_0) P(S_0) = 0.6 \\times 0.5 + 0.2 \\times 0.5 = 0.4 $$\n\nextrayendo las probabilidades de transición entre los estados $R$ y $S$ directamente de la figura, y sustituyendo las probabilidades iniciales por los valores proporcionados $P(R_0) = 1$, \n$P(S_0) = 0$, que corresponden al parámetro de entrada [3] de nuestro modelo.\n\n##### $P(H_1)$\n\nLa probablidad de que en el día 1 la gente esté feliz $H_1$ se calcula a través de la probabilidad total [2]:\n\n$$ P(H_1) = P(H_1|R_1) P(R_1) + P(H_1|S_1) P(S_1) = 0.4 \\times P(R_1) + 0.9 \\times P(S_1) $$\n\nLa probabilidad $P(R_1)$ la hemos calculado anteriormente: $P(R_1)=0.4$\n\nNecesitamos calcular la probabilidad total de que el día 1 sea soleado $P(S_1)$:\n\n$$ P(S_1) = P(S_1|S_0) P(S_0) + P(S_1|R_0) P(R_0) = 0.8 \\times 0.5 + 0.4 \\times 0.5 = 0.6 $$\n\nque introducida en la expresión $P(H_1)$ ofrece:\n\n$$ P(H_1) = 0.4 \\times 0.4 + 0.9 \\times 0.6 = 0.7 $$\n\nDisponemos ya de todos las probabilidades para sustituir en la expresión:\n\n$$ P(R_1|H_1) = \\frac {P(H_1 | R_1) P(R_1)} {P(H_1)} =   \\frac {0.4 \\times 0.4} {0.7} = 0.229 $$\n\nObserva los números en la figura:\n\n![\"Ejercicio probabilidades resuelto\"](./doc/HMM_ejercicio_probabilidades_solucion.png \"Ejercicio probabilidades resuelto\")\n\n## Matemática de las Cadenas de Markov\n\nUn proceso de Markov es un proceso aleatorio con la propiedad de que dado el valor actual del proceso $X_t$, los valores futuros $X_s$ para $s \u003e t$ son independientes de los valores pasados $X_u$ para $u \u003c t$. Si disponemos de la información presente del proceso, conocer cómo ha llegado  al estado actual no afecta las probabilidades de pasar a otro estado en el futuro. \n\nAsí, una secuencia de variables aleatorias $X_n$ es una cadena de Markov si posee la propiedad de que:\n\n$$ P(X_n = j | valores \\ de \\ los \\ estados \\ previos) = P(X_n | X_{n-1}) $$\n\nque expresada de otro modo:\n\n$$ [1] \\quad P(X_{n+1} = j|X_0 = i_0 , ..., X_{n−1} = i_{n−1},X_n = i_n) = P(X_{n+1} = j|X_n = i_n) $$\n\npara todo $n$ y cualesquiera estados $i_0, i_1, . . . , i_n, j$ en $\\varepsilon$. La propiedad [1] se conoce como la propiedad de Markov.\n\nEs decir, sólo el último estado determina la probabilidad del estado actual. \n\nLas probabilidades $P(X_n | X_{n-1})$ son las **probabilidades de transición**. Las variables serán siempre **discretas** y asumiremos que toman valores en un **conjunto finito** o numerable $\\varepsilon$, conocido como **espacio de estados**.\n\n### Cadenas de Markov estacionarias\n\nCuando estas probabilidades son independientes del tiempo (de $n$) la cadena posee **probabilidades de transición estacionarias** (homogéneas) en el tiempo.\n\nAsí, si la probabilidad de que $X_{n+1}$ esté en el estado $j$ dado que $X_n$ está en el estado $i$ es la **probabilidad de transición** en un paso de $i$ a $j$ y la denotamos por $P^{nn+1}_{ij}$.\n\n$$ P^{nn+1}_{ij} = P(X_{n+1} = j | X_n = i) $$\n\nEn este caso, $P^{nn+1}_{ij}=P_{ij}$, no depende de $n$ y $P_{ij}$ es la probabilidad de que la cadena pase del estado $i$ al estado $j$ en un paso.\n\n\n### Ejercicio Cadenas de Markov\n\nSupongamos que en nuestro ejercicio del clima hemos observado la siguiente secuencia de observaciones:\n\nNumero de muestras: 10\n\nrain -\u003e rain -\u003e sun -\u003e sun -\u003e rain -\u003e sun -\u003e rain -\u003e sun -\u003e rain -\u003e rain\n\nAbrevianos la notación de la forma: $R \\ R \\ S \\ S \\ R \\ S \\ R \\ S \\ R \\ R$\n\n**Recuerda que se cumple la propiedad de Markov.**\n\nEn el mundo de la ciencia de datos, existe una tendencia a emplear aproximaciones a este tipo de problemas de entradas secuenciales usando técnicas de _machine learning_ para encontrar las relaciones en el conjunto de datos -por ejemplo las _Long Short Term Memory Networks_ (LSTM), que son un tipo de redes neuronales recurrentes (RNN)- pero en muchos casos no disponemos de una cantidad de muestras significativas o las secuencias son demasiado largas para entrenar una RNN de manera efectiva. \n\nEn estos casos, podemos recurrir a los _Hidden Markov Models_ (HMM) y a las Cadenas de Markov. Ambos métodos proveen de una aproximación \"ligera\" pero robusta que utiliza estadística y distribuciones usando la **maximización de la probabilidad**. \n\n¿Qué es la maximización de la probabilidad?\n\nIntentarmos calcular la probabilidad de cada posible transición:\n\n```\n    Rain -\u003e Sun\n    Rain -\u003e Rain \n    Sun -\u003e Rain\n    Sun -\u003e Sun\n```\n\nPara calcular estas probabilidades, muestreamos una secuencia de transiciones y calculamos la probabilidad de la transición entre cada estado basándonos en los datos muestreados. Esta es la **matriz de transiciones**.\n\nRealizamos el cálculo \"a mano\" y luego usaremos el código en [model_probabilities.py](./markov_chain/model_probabilities.py).\n\n#### A mano\n\nDispones del enunciado de este ejercicio en este vídeo:\n\n[![enunciado ejercicio](./doc/Cadena_Markov_enunciado.png \"vídeo enunciado ejercicio\")](https://drive.google.com/file/d/1Ze-y2KeyyyyijBohNtaecglp7s7As249/view?usp=drive_link) \n\ny de la solución en este otro:\n\n[![solución ejercicio](./doc/Cadena_Markov_solucion.png \"vídeo solución ejercicio\")](https://drive.google.com/file/d/1AQRgthFL3KpLKfa5LKqEjEq_zy1JDS06/view?usp=drive_link) \n\nsi estás logueado con la cuenta del módulo de MIA.\n\nLa secuencia de observaciones es:\n\n$R \\ R \\ S \\ S \\ R \\ S \\ R \\ S \\ R \\ R$\n\nContamos \"a mano\" el número de transiciones que se presentan en las observaciones y las expresamos en términos de probabilidad condicionada $P(A|B)$ que, en las cadenas de Markov es la probabilidad de transición $P(X_n | X_{n-1})$.\n\nProbabilidad inicial:\n\n- $P(R_0) = 1$ pues la secuencia de observaciones comienza en $R$.\n\nLas probabilidades de transición desde $S$ son:\n\n- $P(S|S) = 1/4 = 0.25$ pues observamos 4 dias soleados y sólo 1 en el que el siguiente es soleado.\n\n- $P(R|S) = 3/4 = 0.75$ pues observamos 4 dias soleados y 3 en el que el siguiente es lluvioso.\n\nLas probabilidades de transición desde $R$ son:\n\n- $P(S|R) = 3/6 = 0.5$ pues observamos 6 dias lluviosos y 3 transiciones a día soleado.\n\n- $P(R|R) = 3/6 = 0.5$ pues observamos 6 dias lluviosos y 3 transiciones a día lluvioso.\n\nLa matriz de transiciones sería, por tanto:\n\n$$\nP = \n\\begin{bmatrix}\n0.25 \u0026 0.75\\\\\n0.5 \u0026 0.5 \\\\\n\\end{bmatrix}\n$$\n\no lo que es lo mismo:\n\n|  Hoy  | Mañana|       |\n| :---: | :---: | :---: |\n|       |  sol  | lluvia|\n| sol   |  0.25\t| 0.75 |\n| lluvia|  0.5  | 0.5   |\n\n\n#### model_probabilites.py\n\nConsulta el código en [model_probabilities.py](./markov_chain/model_probabilities.py).\n\nExpresamos las observaciones: \n\n`R R S S R S R S R R`\n\ncomo un tensor:\n\n```python\nsamples = [ [[1], [1]],\n            [[1], [1]],\n            [[1], [0]],\n            [[0], [0]],\n            [[0], [1]],\n            [[1], [0]],\n            [[0], [1]],\n            [[1], [0]],\n            [[0], [1]],\n            [[1], [1]]]\nX = torch.tensor(samples)\n```\n\nEstablecemos la dependencia únicamente al estado anterior `k=1`:\n\n```python\nmodel_ejercicio = MarkovChain(k=1)\nmodel_ejercicio.fit(X)\n```\n\nLas probabilidades iniciales o Categorical son:\n\n```python\nmodel_ejercicio.distributions[0].probs[0]\n\n\u003e\u003e\u003e tensor([0.4000, 0.6000])\n```\n\ny la matriz de transición o probabilidades condicionadas son:\n\n```python\nmodel_ejercicio.distributions[1].probs[0]\n\n\u003e\u003e\u003e tensor([[0.2500, 0.7500],\n            [0.5000, 0.5000]])\n```\nque coincide con la matriz de transiciones calculada anteriormente \"a mano\":\n\n$$ \nP = \n\\begin{bmatrix}\n0.25 \u0026 0.75\\\\\n0.5 \u0026 0.5 \\\\\n\\end{bmatrix}\n$$\n\n\n### Ejercicio cadena estacionaria con probabilidades iniciales\n\nDado el vector $w = (w_1, ..., w_k)$ se llama vector de probabilidades si:\n\n$$ w_i \\ge 0 \\quad para \\quad i = 1, ..., k $$\n$$ \\sum_{i=1}^{k} w_i = 1 $$\n\nConsideremos una cadena de Markov con $ s_1, ..., s_k $ posibles estados en los que la cadena puede estar en el tiempo de observación inicial $n = 1$.\n\nPara $i = 1,...,k$, la probabilidad de que en el instante $X_1$ el estado sea $s_i$ es el vector de probabilidades $v_i$:\n\n$P(X_1 = s_i) = v_i$, con $v_i \\ge 0$ y $v_1+ ... + v_k = 1$\n\nSupongamos que en nuestro ejemplo del clima, disponemos de las probabilidades de que el primer día de la serie sea soleado o nublado. Podemos expresarlas en un **vector de probailidades iniciales** de la forma:\n\n$$ v = (v_1, ..., vk) $$\n\nEn nuestro caso:\n\n$$ v = (0.5, 0.5) $$\n\nEl vector de probabilidades iniciales $\\vec v$ y la matriz de transición $P$ determinan la probabilidad para el estado de la cadena en el segundo instante de tiempo, dada por el vector $\\vec vP$.\n\nSi las probabilidades de los diversos estados en el instante $n$ se especifican por el vector de probabilidades $w$, entonces las probabilidades en el instante $n + 1$ se especifican por el vector de probabilidades $\\vec wP$.\n\nVamos a calcular estas probabilidades en nuestro ejemplo.\n\n#### Probabilidades en el segundo día\n\nDado el vector de probailidades iniciales:\n\n$$ \\vec{v} = \u003c0.5, 0.5\u003e $$\n\ny la matriz de transición:\n\n$$ \nP = \n\\begin{bmatrix}\n0.8 \u0026 0.2\\\\\n0.4 \u0026 0.6 \\\\\n\\end{bmatrix}\n$$\n\nlas probabilidades del segundo día de la serie son:\n\n$$ \\vec w = \\vec v  P = \u003c0.5, 0.5\u003e \\times \n\\begin{bmatrix}\n0.8 \u0026 0.2\\\\\n0.4 \u0026 0.6 \\\\\n\\end{bmatrix} = \u003c0.6, 0.4\u003e $$\n\nPara este cálculo podemos hacer uso de la librería pytorch según vemos en el script [`model_stationary.py`](./markov_chain/model_stationary.py) o en [`model_stationary_markov_chain`](./markov_chain/model_stationary_markov_chain.py).\n\n```python\n# vector de probabilidades iniciales\nv = torch.tensor([[0.5, 0.5]])\n\n# matriz de transicion\nP = torch.tensor([\n    [0.8, 0.2],\n    [0.4, 0.6]\n])\n\n# Probabilidades en el segundo dia de la serie\nw = torch.matmul(v, P)\n# w = tensor([[0.6000, 0.4000]])\n```\n\nLa probabilidad de que el segundo dia de la serie sea soleado es $0.6$ y de que sea lluvioso $0.4$. \n\nObserva cómo se satisface el axioma de la teoría de la probabilidad que establece que la probabilidad total del conjunto de los posibles estados es $1$.\n\n#### Probabilidades en el tercer día\n\n$$ \\vec u = \\vec v  P \\times P = \\vec w \\times P = \u003c0.6, 0.4\u003e \\times \n\\begin{bmatrix}\n0.8 \u0026 0.2\\\\\n0.4 \u0026 0.6 \\\\\n\\end{bmatrix} = \u003c0.6400, 0.3600\u003e $$\n\n```python\n# Probabilidades en el tercer dia de la serie\nu = torch.matmul(w, P)\n# tensor([[0.6400, 0.3600]])\n```\n\n#### Probabilidades en el cuarto día\n\n$$ \\vec t = \\vec v \\times P^3 = \\vec v P \\times P^2 = \\vec w \\times P^2 = \\vec u \\times P = \u003c0.6400, 0.3600\u003e \\times \n\\begin{bmatrix}\n0.8 \u0026 0.2\\\\\n0.4 \u0026 0.6 \\\\\n\\end{bmatrix} = \u003c0.6560, 0.3440\u003e $$\n\n```python\n# Probabilidades en el cuarto dia de la serie\nt = torch.matmul(u, P)\n# t = tensor([[0.6560, 0.3440]])\n```\n\n### Ejercicio robot aspirador\n\nEn los _scripts_ [`model_robot_0x.py`](./markov_chain/model_robot_01.py) encontrarás el código correspondiente a una cadena de Markov estacionaria que modela el posible movimiento de un robot aspirador en una vivienda como la siguiente:\n\n![\"mapa vivienda\"](./doc/mapa_vivienda.png)\n\nSe plantean 6 diferentes supuestos en función de la distribución de la probabilidad inicial y de las probabilidades de transición entre las habitaciones (estados).\n\nDescribimos el caso [model_robot_06](./markov_chain/model_robot_06.py)\n\nDisponemos de una vivienda en la que hay 6 habitaciones. El espacio de estados es, por tanto, $\\epsilon = \\{1,2,3,4,5,6\\}$.\n\n$X_n$ es la habitación ocupada por el robot en el instante $n$.\n\nSe cumple la condición de Markov, pues el estado en $n+1$ depende únicamente del estado actual $n$, sin importar el pasado.\n\nLa probabilidad de transición del estado $i$ al $j$ es:\n\n$$ p_{ij} = P(X_{n+1} = j | X_n = i) $$\n\ny la matriz de transición es de la forma:\n\n$$ \nP = \n\\begin{bmatrix}\np_{11} \u0026 p_{12} \u0026 ... \u0026 p_{16} \\\\\np_{21} \u0026 p_{22} \u0026 ... \u0026 p_{26} \\\\\n... \\\\\np_{61} \u0026 p_{62} \u0026 ... \u0026 p_{66} \\\\\n\\end{bmatrix}\n$$\n\nDado el mapa de la vivienda, las probabilidades de transición quedan determinadas por los movimientos posibles entre las habitaciones comunicadas y la distribución de probabilidad que programemos en nuestro agente inteligente.\n\n* La probabilidad de transición entre habitaciones que no están directamente comunicadas es $0$.\n\n* Supongamos que indicamos al robot que la probabilidad de permanecer en la misma habitación es de un 20% respecto al total de los posibles movimientos a las habitaciones adyacentes para abandonar esa habitación.\n\nRealizamos los cálculos para la habitación 1. Distribuímos la probabilidad entre los posibles $k$-estados del mundo que pueden alcanzarse (las habitaciones adyacentes a la habitación 1) para satisfacer los axiomas de la teoría de la probabilidad. Si $w_i$ es la probabilidad del estado $i$:\n\n$$ w_i \\ge 0 \\quad para \\quad i = 1, ..., k $$\n$$ \\sum_{i=1}^{k} w_i = 1 $$\n\nCálculo de las probabilidades de la matriz de transición:\n\n$$ p_{11} = P(X_{n+1} = 1 | X_n = 1) = 1/5 $$\n\n$$ p_{12} = P(X_{n+1} = 2 | X_n = 1) = 2/5 $$\n\n$$ p_{13} = P(X_{n+1} = 3 | X_n = 1) = 0 $$\n\n$$ p_{14} = P(X_{n+1} = 4 | X_n = 1) = 2/5 $$\n\n$$ p_{15} = P(X_{n+1} = 5 | X_n = 1) = 0 $$\n\n$$ p_{16} = P(X_{n+1} = 6 | X_n = 1) = 0 $$\n\nProcediendo de igual modo con el resto de transiciones entre los estados $p_{2j}, p_{3j}, p_{4j}, p_{5j}, p_{6j}$ obtenemos la matriz de transición:\n\n```python\nP = [[1/5, 2/5, 0,   2/5, 0,   0],\n     [2/5, 1/5, 2/5, 0,   0,   0],\n     [0,   2/5, 1/5, 0,   0,   2/5],\n     [2/5, 0,   0,   1/5, 2/5, 0],\n     [0,   0,   0,   4/5, 1/5, 0],\n     [0,   0,   4/5, 0,   0,   1/5]]\n```\n\nEl vector de probabilidades en el instante inicial es el siguiente:\n\n$$ \\vec{v} = \u003c1/6, \\ 1/6, \\ 1/6, \\ 1/6, \\ 1/6, \\ 1/6\u003e $$\n\nComo las probabilidades de transición son estacionarias, podemos calcular las probabilidades en el instante de tiempo $n+1$ aplicando:\n\n$$ \\vec w = \\vec v  P = \u003c1/6, \\ 1/6, \\ 1/6, \\ 1/6, \\ 1/6, \\ 1/6\u003e \\times \nP = \u003c0.1667, 0.1667, 0.2333, 0.2333, 0.1000, 0.1000\u003e$$\n\nRepetimos este cálculo para calcular las probabilidades en los siguientes instantes.\n\nEn los _scripts_ `model_robot_0x.py` dispones de distintos ejemplos cambiando las distribuciones de probabilidades iniciales y de transición, y estableciendo el mapa de modo que las habitaciones adyacentes sean 1 - 2 - 4 y 3 - 5 - 6:\n\n![\"mapa vivienda\"](./doc/mapa_vivienda_tabiques.png)\n\n## Bibliografia\n\n[Forsyth, David. _Probability and Statistics for Computer Science_. Springer International Publishing AG, 2018](https://github.com/clementinojr/Springer-s-Books)\n\n\"A brief primer on Hidden Markov Models\", _Berkeley D-Lab_, 3 de mayo de 2024. https://dlab.berkeley.edu/news/brief-primer-hidden-markov-models","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfleta%2Fhidden-markov-models","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdfleta%2Fhidden-markov-models","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfleta%2Fhidden-markov-models/lists"}