noshot 7.0.0__py3-none-any.whl → 8.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. noshot/data/ML TS XAI/ML/CNN(Image_for_Folders_5).ipynb +201 -0
  2. noshot/data/ML TS XAI/ML/CNN(Image_form_Folder_2).ipynb +201 -0
  3. noshot/data/ML TS XAI/ML/ML 3 (Latest)/1. PCA EDA.ipynb +274 -0
  4. noshot/data/ML TS XAI/ML/ML 3 (Latest)/10. CNN.ipynb +170 -0
  5. noshot/data/ML TS XAI/ML/ML 3 (Latest)/11. HMM 2.ipynb +1087 -0
  6. noshot/data/ML TS XAI/ML/ML 3 (Latest)/11. HMM 3.ipynb +178 -0
  7. noshot/data/ML TS XAI/ML/ML 3 (Latest)/11. HMM 4.ipynb +185 -0
  8. noshot/data/ML TS XAI/ML/ML 3 (Latest)/11. HMM.ipynb +106 -0
  9. noshot/data/ML TS XAI/ML/ML 3 (Latest)/2. KNN.ipynb +177 -0
  10. noshot/data/ML TS XAI/ML/ML 3 (Latest)/3. LDA.ipynb +195 -0
  11. noshot/data/ML TS XAI/ML/ML 3 (Latest)/4. Linear Regression.ipynb +267 -0
  12. noshot/data/ML TS XAI/ML/ML 3 (Latest)/5. Logistic Regression.ipynb +104 -0
  13. noshot/data/ML TS XAI/ML/ML 3 (Latest)/6. Bayesian Classifier.ipynb +109 -0
  14. noshot/data/ML TS XAI/ML/ML 3 (Latest)/7. SVM.ipynb +220 -0
  15. noshot/data/ML TS XAI/ML/ML 3 (Latest)/8. MLP.ipynb +99 -0
  16. noshot/data/ML TS XAI/ML/ML 3 (Latest)/9. Ridge - Lasso.ipynb +211 -0
  17. noshot/data/ML TS XAI/ML/ML 3 (Latest)/9. Ridge Lasso 2.ipynb +99 -0
  18. noshot/data/ML TS XAI/ML/ML 3 (Latest)/Image Load Example.ipynb +118 -0
  19. noshot/data/ML TS XAI/ML/ML 3 (Latest)/Updated_Untitled.ipynb +603 -0
  20. {noshot-7.0.0.dist-info → noshot-8.0.0.dist-info}/METADATA +1 -1
  21. noshot-8.0.0.dist-info/RECORD +60 -0
  22. noshot-7.0.0.dist-info/RECORD +0 -41
  23. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/1. EDA-PCA (Balance Scale Dataset).ipynb +0 -0
  24. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/1. EDA-PCA (Rice Dataset).ipynb +0 -0
  25. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/10. HMM Veterbi.ipynb +0 -0
  26. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/2. KNN (Balance Scale Dataset).ipynb +0 -0
  27. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/2. KNN (Iris Dataset).ipynb +0 -0
  28. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/2. KNN (Sobar-72 Dataset).ipynb +0 -0
  29. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/3. LDA (Balance Scale Dataset).ipynb +0 -0
  30. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/3. LDA (NPHA Doctor Visits Dataset).ipynb +0 -0
  31. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/4. Linear Regression (Machine Dataset).ipynb +0 -0
  32. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/4. Linear Regression (Real Estate Dataset).ipynb +0 -0
  33. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/5. Logistic Regression (Magic04 Dataset).ipynb +0 -0
  34. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/5. Logistic Regression (Wine Dataset).ipynb +0 -0
  35. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/6. Naive Bayes Classifier (Agaricus Lepiota Dataset).ipynb +0 -0
  36. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/6. Naive Bayes Classifier (Wine Dataset).ipynb +0 -0
  37. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/7. SVM (Rice Dataset).ipynb +0 -0
  38. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/8. FeedForward NN (Sobar72 Dataset).ipynb +0 -0
  39. /noshot/data/ML TS XAI/ML/{Tamilan Code → ML 1}/9. CNN (Cifar10 Dataset).ipynb +0 -0
  40. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/1. PCA.ipynb +0 -0
  41. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/10. CNN.ipynb +0 -0
  42. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/11. HMM.ipynb +0 -0
  43. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/2. KNN.ipynb +0 -0
  44. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/3. LDA.ipynb +0 -0
  45. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/4. Linear Regression.ipynb +0 -0
  46. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/5. Logistic Regression.ipynb +0 -0
  47. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/6. Naive Bayes (Titanic).ipynb +0 -0
  48. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/6. Naive Bayes (Wine).ipynb +0 -0
  49. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/7. SVM Linear.ipynb +0 -0
  50. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/8. SVM Non-Linear.ipynb +0 -0
  51. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/9. FNN With Regularization.ipynb +0 -0
  52. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/9. FNN Without Regularization.ipynb +0 -0
  53. /noshot/data/ML TS XAI/ML/{Whitefang Code → ML 2}/All in One Lab CIA 1 Q.ipynb +0 -0
  54. {noshot-7.0.0.dist-info → noshot-8.0.0.dist-info}/WHEEL +0 -0
  55. {noshot-7.0.0.dist-info → noshot-8.0.0.dist-info}/licenses/LICENSE.txt +0 -0
  56. {noshot-7.0.0.dist-info → noshot-8.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1087 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "ebdffb71",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import numpy as np\n",
11
+ "import matplotlib.pyplot as plt\n",
12
+ "import networkx as nx\n",
13
+ "from hmmlearn.hmm import CategoricalHMM\n",
14
+ "\n",
15
+ "# --- Initial Parameters ---\n",
16
+ "start_prob = np.array([1.0, 0.0]) # Initial state probabilities (π)\n",
17
+ "trans_mat = np.array([ # Transition matrix (A)\n",
18
+ " [0.1, 0.9],\n",
19
+ " [0.5, 0.5]\n",
20
+ "])\n",
21
+ "emission_prob = np.array([ # Emission matrix (B)\n",
22
+ " [0.3, 0.5, 0.2],\n",
23
+ " [0.6, 0.2, 0.2]\n",
24
+ "])\n",
25
+ "\n",
26
+ "# Define states and observations\n",
27
+ "states = [\"s1\", \"s2\"]\n",
28
+ "observations = [\"v1\", \"v2\", \"v3\"]\n",
29
+ "\n",
30
+ "# --- Create and Configure HMM ---\n",
31
+ "# Observation sequence in numeric form (e.g., [v3, v2, v1] -> [2, 1, 0])\n",
32
+ "observed_sequence_numeric = np.array([[2], [1], [0]])\n",
33
+ "\n",
34
+ "# Number of states and features (possible observations)\n",
35
+ "n_states = len(states)\n",
36
+ "n_features = len(observations)\n",
37
+ "\n",
38
+ "# Create and configure the hmmlearn model\n",
39
+ "model = CategoricalHMM(n_components=n_states, n_features=n_features, n_iter=0, verbose=False)\n",
40
+ "\n",
41
+ "# Manually set the parameters after model creation\n",
42
+ "model.startprob_ = start_prob\n",
43
+ "model.transmat_ = trans_mat\n",
44
+ "model.emissionprob_ = emission_prob\n",
45
+ "\n",
46
+ "# --- 1. Forward Algorithm (Likelihood P(O|λ)) ---\n",
47
+ "log_likelihood = model.score(observed_sequence_numeric)\n",
48
+ "likelihood = np.exp(log_likelihood)\n",
49
+ "\n",
50
+ "# --- 2. Viterbi Algorithm (Most Likely Path) ---\n",
51
+ "logprob_viterbi, best_path_indices_viterbi = model.decode(observed_sequence_numeric, algorithm=\"viterbi\")\n",
52
+ "best_path_prob_viterbi = np.exp(logprob_viterbi)\n",
53
+ "best_path_labels_viterbi = [states[i] for i in best_path_indices_viterbi]\n",
54
+ "\n",
55
+ "# --- 3. MAP Algorithm (Most Likely State Sequence) ---\n",
56
+ "logprob_map, best_path_indices_map = model.decode(observed_sequence_numeric, algorithm=\"map\")\n",
57
+ "best_path_prob_map = np.exp(logprob_map)\n",
58
+ "best_path_labels_map = [states[i] for i in best_path_indices_map]\n",
59
+ "\n",
60
+ "# --- 4. Forward-Backward Algorithm (Posterior Probabilities) ---\n",
61
+ "posterior_probs = model.predict_proba(observed_sequence_numeric)\n",
62
+ "\n",
63
+ "# --- Display Results ---\n",
64
+ "print(\"--- HMM Model Parameters ---\")\n",
65
+ "print(f\"Start Probabilities (π): {model.startprob_}\")\n",
66
+ "print(f\"Transition Matrix (A):\\n{model.transmat_}\")\n",
67
+ "print(f\"Emission Matrix (B):\\n{model.emissionprob_}\")\n",
68
+ "print(f\"Observed Sequence (Numeric): {observed_sequence_numeric.flatten()}\")\n",
69
+ "print(\"-\" * 30)\n",
70
+ "\n",
71
+ "# --- 1. Forward Algorithm (Likelihood P(O|λ)) ---\n",
72
+ "print(f\"--- Forward Algorithm (Likelihood P(O|λ)) ---\")\n",
73
+ "print(f\"Log Likelihood: {log_likelihood:.6f}\")\n",
74
+ "print(f\"Likelihood: {likelihood:.6f}\")\n",
75
+ "print(f\"(This is the probability of observing the sequence {observations[2]}, {observations[1]}, {observations[0]} given the model)\")\n",
76
+ "print(\"-\" * 30)\n",
77
+ "\n",
78
+ "# --- 2. Viterbi Algorithm (Most Likely State Sequence) ---\n",
79
+ "print(f\"--- Viterbi Algorithm (Most Likely State Sequence) ---\")\n",
80
+ "print(f\"Most Likely Hidden State Sequence (Viterbi): {best_path_labels_viterbi} (Numeric: {best_path_indices_viterbi})\")\n",
81
+ "print(f\"Log Probability of this path: {logprob_viterbi:.6f}\")\n",
82
+ "print(f\"Probability of this path: {best_path_prob_viterbi:.6f}\")\n",
83
+ "print(\"-\" * 30)\n",
84
+ "\n",
85
+ "# --- 3. MAP Algorithm (Most Likely State Sequence) ---\n",
86
+ "print(f\"--- MAP Algorithm (Most Likely State Sequence) ---\")\n",
87
+ "print(f\"Most Likely Hidden State Sequence (MAP): {best_path_labels_map} (Numeric: {best_path_indices_map})\")\n",
88
+ "print(f\"Log Probability of this path: {logprob_map:.6f}\")\n",
89
+ "print(f\"Probability of this path: {best_path_prob_map:.6f}\")\n",
90
+ "print(\"-\" * 30)\n",
91
+ "\n",
92
+ "# --- 4. Forward-Backward Algorithm (Posterior Probabilities) ---\n",
93
+ "print(f\"--- Forward-Backward Algorithm (Posterior Probabilities P(state_t|O,λ)) ---\")\n",
94
+ "print(\"Rows = Time Steps (for observations v3, v2, v1)\")\n",
95
+ "print(\"Columns = States [s1, s2]\")\n",
96
+ "print(posterior_probs.round(4))\n",
97
+ "print(\"-\" * 30)\n",
98
+ "\n",
99
+ "# --- HMM Structure Visualization ---\n",
100
+ "\n",
101
+ "# Create directed graph for visualization\n",
102
+ "G = nx.DiGraph()\n",
103
+ "for i, state in enumerate(states):\n",
104
+ " G.add_node(state)\n",
105
+ "for obs in observations:\n",
106
+ " G.add_node(obs)\n",
107
+ "G.add_edge('Start', states[0], weight=start_prob[0])\n",
108
+ "G.add_edge('Start', states[1], weight=start_prob[1])\n",
109
+ "\n",
110
+ "# Add transitions and emissions\n",
111
+ "for i, state_from in enumerate(states):\n",
112
+ " for j, state_to in enumerate(states):\n",
113
+ " if trans_mat[i, j] > 0:\n",
114
+ " G.add_edge(state_from, state_to, weight=trans_mat[i, j])\n",
115
+ " for j, obs in enumerate(observations):\n",
116
+ " if emission_prob[i, j] > 0:\n",
117
+ " G.add_edge(state_from, obs, weight=emission_prob[i, j])\n",
118
+ "\n",
119
+ "# Define node positions\n",
120
+ "pos = {\n",
121
+ " 'Start': (0.5, 1.1), 's1': (0.25, 0.5), 's2': (0.75, 0.5),\n",
122
+ " 'v1': (0.1, 0.1), 'v2': (0.5, 0.1), 'v3': (0.9, 0.1)\n",
123
+ "}\n",
124
+ "\n",
125
+ "# Create the plot\n",
126
+ "plt.figure(figsize=(14, 12))\n",
127
+ "nx.draw_networkx_nodes(G, pos, node_size=2500, node_color='skyblue', alpha=0.6)\n",
128
+ "nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold')\n",
129
+ "nx.draw_networkx_edges(G, pos, width=2, alpha=0.6, edge_color='gray')\n",
130
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels=nx.get_edge_attributes(G, 'weight'), font_size=10)\n",
131
+ "\n",
132
+ "# Add title and display\n",
133
+ "plt.title('HMM Structure Visualization', fontsize=16)\n",
134
+ "plt.axis('off')\n",
135
+ "plt.show()\n"
136
+ ]
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": null,
141
+ "id": "3bd69b13",
142
+ "metadata": {},
143
+ "outputs": [],
144
+ "source": []
145
+ },
146
+ {
147
+ "cell_type": "code",
148
+ "execution_count": null,
149
+ "id": "9f4488a1",
150
+ "metadata": {},
151
+ "outputs": [],
152
+ "source": []
153
+ },
154
+ {
155
+ "cell_type": "markdown",
156
+ "id": "27e0e0c6",
157
+ "metadata": {},
158
+ "source": [
159
+ "Okay, let's break down this Python code step by step.\n",
160
+ "\n",
161
+ "**Overall Purpose:**\n",
162
+ "\n",
163
+ "This code demonstrates the fundamental concepts and algorithms associated with a Hidden Markov Model (HMM). It defines a specific HMM, provides an observed sequence of outputs, and then uses the `hmmlearn` library to:\n",
164
+ "\n",
165
+ "1. Calculate the **likelihood** of the observed sequence given the model (Forward Algorithm).\n",
166
+ "2. Find the **most probable sequence of hidden states** that generated the observation sequence (Viterbi Algorithm).\n",
167
+ "3. Find the sequence composed of the **most likely state at each individual time step** (MAP Algorithm, based on Forward-Backward).\n",
168
+ "4. Calculate the **probability of being in each hidden state at each time step**, given the entire observation sequence (Forward-Backward Algorithm).\n",
169
+ "5. **Visualize** the structure of the defined HMM.\n",
170
+ "\n",
171
+ "**Code Breakdown:**\n",
172
+ "\n",
173
+ "1. **Imports:**\n",
174
+ " * `numpy as np`: Used for numerical operations, especially creating and manipulating arrays (matrices and vectors) for the HMM parameters.\n",
175
+ " * `matplotlib.pyplot as plt`: Used for plotting, specifically for visualizing the HMM structure.\n",
176
+ " * `networkx as nx`: A library for creating, manipulating, and studying complex networks (graphs). Used here to build the HMM visualization.\n",
177
+ " * `from hmmlearn.hmm import CategoricalHMM`: Imports the specific HMM class from the `hmmlearn` library suitable for discrete (categorical) observations.\n",
178
+ "\n",
179
+ "2. **Initial Parameters:**\n",
180
+ " * `start_prob (π)`: A NumPy array representing the initial state probabilities. `[1.0, 0.0]` means the HMM is certain to start in the first state (`s1`).\n",
181
+ " * `trans_mat (A)`: A 2D NumPy array representing the transition matrix. `trans_mat[i, j]` is the probability of transitioning *from* state `i` *to* state `j`.\n",
182
+ " * `[0.1, 0.9]`: From state `s1`, there's a 10% chance of staying in `s1` and a 90% chance of moving to `s2`.\n",
183
+ " * `[0.5, 0.5]`: From state `s2`, there's a 50% chance of moving to `s1` and a 50% chance of staying in `s2`.\n",
184
+ " * `emission_prob (B)`: A 2D NumPy array representing the emission matrix. `emission_prob[i, j]` is the probability of observing the `j`-th observation *while* in state `i`.\n",
185
+ " * `[0.3, 0.5, 0.2]`: In state `s1`, P(observe `v1`)=0.3, P(observe `v2`)=0.5, P(observe `v3`)=0.2.\n",
186
+ " * `[0.6, 0.2, 0.2]`: In state `s2`, P(observe `v1`)=0.6, P(observe `v2`)=0.2, P(observe `v3`)=0.2.\n",
187
+ "\n",
188
+ "3. **Define States and Observations:**\n",
189
+ " * `states`: A list of strings naming the hidden states (`s1`, `s2`).\n",
190
+ " * `observations`: A list of strings naming the possible observations (`v1`, `v2`, `v3`).\n",
191
+ "\n",
192
+ "4. **Create and Configure HMM:**\n",
193
+ " * `observed_sequence_numeric`: The sequence of observations the model will analyze (`[v3, v2, v1]`). It's converted to numeric indices (`[2, 1, 0]`) because `hmmlearn` works with numerical data. Each number corresponds to the index of the observation in the `observations` list. It's reshaped into a 2D array (`[[2], [1], [0]]`) as `hmmlearn` expects sequences as column vectors (or matrices where each row is a time step).\n",
194
+ " * `n_states`, `n_features`: Calculated from the lengths of the `states` and `observations` lists. These are required parameters for the `CategoricalHMM`.\n",
195
+ " * `model = CategoricalHMM(...)`: Creates an instance of the `CategoricalHMM` class.\n",
196
+ " * `n_components=n_states`: Specifies the number of hidden states.\n",
197
+ " * `n_features=n_features`: Specifies the number of unique possible observations.\n",
198
+ " * `n_iter=0`: **Crucially**, this prevents the model from trying to *learn* or *estimate* the parameters from data. We want to use the exact parameters defined earlier.\n",
199
+ " * `verbose=False`: Suppresses detailed output during potential (but disabled) fitting.\n",
200
+ " * `model.startprob_ = start_prob`, `model.transmat_ = trans_mat`, `model.emissionprob_ = emission_prob`: Manually setting the model's parameters to the predefined `start_prob`, `trans_mat`, and `emission_prob`. The trailing underscore (`_`) is a convention in `hmmlearn` (and `scikit-learn`) for attributes learned or set after initialization.\n",
201
+ "\n",
202
+ "5. **1. Forward Algorithm (Likelihood P(O|λ)):**\n",
203
+ " * `log_likelihood = model.score(observed_sequence_numeric)`: This method calculates the log-likelihood of the `observed_sequence_numeric` given the HMM model (`λ`, which represents the set of parameters π, A, B). Internally, this uses the Forward Algorithm. Working with log-likelihoods prevents numerical underflow issues with very small probabilities.\n",
204
+ " * `likelihood = np.exp(log_likelihood)`: Converts the log-likelihood back to the actual probability. This value represents P(observations | model).\n",
205
+ "\n",
206
+ "6. **2. Viterbi Algorithm (Most Likely Path):**\n",
207
+ " * `logprob_viterbi, best_path_indices_viterbi = model.decode(observed_sequence_numeric, algorithm=\"viterbi\")`: This method finds the single most likely sequence of hidden states that could have generated the observed sequence.\n",
208
+ " * `algorithm=\"viterbi\"`: Specifies the Viterbi algorithm.\n",
209
+ " * `logprob_viterbi`: The log probability of this single most likely path.\n",
210
+ " * `best_path_indices_viterbi`: A NumPy array containing the indices (0 or 1) of the states in the most likely path.\n",
211
+ " * `best_path_prob_viterbi = np.exp(logprob_viterbi)`: Converts the log probability of the path to the actual probability.\n",
212
+ " * `best_path_labels_viterbi = [states[i] for i in best_path_indices_viterbi]`: Converts the numeric state indices back to their string labels (`s1`, `s2`).\n",
213
+ "\n",
214
+ "7. **3. MAP Algorithm (Most Likely State Sequence):**\n",
215
+ " * `logprob_map, best_path_indices_map = model.decode(observed_sequence_numeric, algorithm=\"map\")`: This method finds the sequence of states where each state in the sequence is the *individually* most likely state at that specific time step, given the *entire* observation sequence. This is achieved by running the Forward-Backward algorithm first to calculate posterior probabilities (see step 8) and then picking the state with the highest posterior probability at each time step.\n",
216
+ " * `algorithm=\"map\"`: Specifies the Maximum A Posteriori decoding based on individual state posteriors. **Note:** This path is *not guaranteed* to be the same as the Viterbi path, although it often is. Viterbi finds the globally best *sequence*, while MAP finds the sequence of locally best *states*.\n",
217
+ " * `logprob_map`: The log probability associated with the MAP path (calculated differently than Viterbi's path probability).\n",
218
+ " * `best_path_indices_map`: A NumPy array containing the indices of the states in the MAP path.\n",
219
+ " * `best_path_prob_map = np.exp(logprob_map)`: Converts the log probability.\n",
220
+ " * `best_path_labels_map = [states[i] for i in best_path_indices_map]`: Converts indices to labels.\n",
221
+ "\n",
222
+ "8. **4. Forward-Backward Algorithm (Posterior Probabilities):**\n",
223
+ " * `posterior_probs = model.predict_proba(observed_sequence_numeric)`: This method calculates the posterior probabilities using the Forward-Backward algorithm.\n",
224
+ " * The result `posterior_probs` is a 2D NumPy array where `posterior_probs[t, i]` gives the probability of being in state `i` at time step `t`, given the *entire* observation sequence `O` and the model parameters `λ`. Mathematically, this is P(state `i` at time `t` | `O`, `λ`).\n",
225
+ "\n",
226
+ "9. **Display Results:**\n",
227
+ " * This section uses `print()` statements with f-strings to clearly output:\n",
228
+ " * The HMM parameters that were set.\n",
229
+ " * The numeric observed sequence.\n",
230
+ " * The results (log-likelihood and likelihood) from the Forward algorithm.\n",
231
+ " * The results (most likely path labels/indices, log probability, probability) from the Viterbi algorithm.\n",
232
+ " * The results (most likely path labels/indices, log probability, probability) from the MAP algorithm.\n",
233
+ " * The posterior probabilities calculated by the Forward-Backward algorithm, formatted for readability.\n",
234
+ "\n",
235
+ "10. **HMM Structure Visualization:**\n",
236
+ " * `G = nx.DiGraph()`: Creates an empty directed graph object using `networkx`.\n",
237
+ " * `G.add_node(...)`: Adds nodes to the graph representing the hidden states (`s1`, `s2`) and the possible observations (`v1`, `v2`, `v3`). A special 'Start' node is added for visualizing initial probabilities.\n",
238
+ " * `G.add_edge(...)`: Adds directed edges to represent:\n",
239
+ " * Initial probabilities (from 'Start' to `s1`/`s2`).\n",
240
+ " * Transitions between states (`s1` to `s1`, `s1` to `s2`, etc.).\n",
241
+ " * Emissions from states to observations (`s1` to `v1`, `s1` to `v2`, etc.).\n",
242
+ " * The `weight` attribute of each edge stores the corresponding probability (start, transition, or emission). Edges with probability 0 are omitted.\n",
243
+ " * `pos = {...}`: Manually defines the (x, y) coordinates for positioning each node in the plot for a clear layout.\n",
244
+ " * `plt.figure(...)`: Creates a Matplotlib figure to draw on.\n",
245
+ " * `nx.draw_networkx_nodes(...)`, `nx.draw_networkx_labels(...)`, `nx.draw_networkx_edges(...)`, `nx.draw_networkx_edge_labels(...)`: `networkx` functions (interfacing with Matplotlib) to draw the nodes, labels, edges, and edge weights (probabilities) using the defined positions.\n",
246
+ " * `plt.title(...)`, `plt.axis('off')`, `plt.show()`: Standard Matplotlib commands to add a title, hide the axes, and display the plot.\n",
247
+ "\n",
248
+ "In summary, the code sets up a known HMM, runs standard HMM algorithms on a given observation sequence using `hmmlearn`, prints the results of these algorithms, and provides a visual representation of the HMM's structure and parameters."
249
+ ]
250
+ },
251
+ {
252
+ "cell_type": "code",
253
+ "execution_count": null,
254
+ "id": "7b1e29fd",
255
+ "metadata": {},
256
+ "outputs": [],
257
+ "source": []
258
+ },
259
+ {
260
+ "cell_type": "code",
261
+ "execution_count": null,
262
+ "id": "2a4fe0aa",
263
+ "metadata": {},
264
+ "outputs": [],
265
+ "source": []
266
+ },
267
+ {
268
+ "cell_type": "code",
269
+ "execution_count": null,
270
+ "id": "961e2845",
271
+ "metadata": {},
272
+ "outputs": [],
273
+ "source": []
274
+ },
275
+ {
276
+ "cell_type": "code",
277
+ "execution_count": null,
278
+ "id": "c1c63df4",
279
+ "metadata": {},
280
+ "outputs": [],
281
+ "source": []
282
+ },
283
+ {
284
+ "cell_type": "code",
285
+ "execution_count": null,
286
+ "id": "075e2ec5",
287
+ "metadata": {},
288
+ "outputs": [],
289
+ "source": []
290
+ },
291
+ {
292
+ "cell_type": "code",
293
+ "execution_count": null,
294
+ "id": "4cad6b10",
295
+ "metadata": {},
296
+ "outputs": [],
297
+ "source": []
298
+ },
299
+ {
300
+ "cell_type": "code",
301
+ "execution_count": null,
302
+ "id": "a4f33416",
303
+ "metadata": {},
304
+ "outputs": [],
305
+ "source": []
306
+ },
307
+ {
308
+ "cell_type": "code",
309
+ "execution_count": null,
310
+ "id": "4ef99e6e",
311
+ "metadata": {},
312
+ "outputs": [],
313
+ "source": []
314
+ },
315
+ {
316
+ "cell_type": "code",
317
+ "execution_count": null,
318
+ "id": "7e0d4278",
319
+ "metadata": {},
320
+ "outputs": [],
321
+ "source": []
322
+ },
323
+ {
324
+ "cell_type": "code",
325
+ "execution_count": null,
326
+ "id": "7950131a",
327
+ "metadata": {},
328
+ "outputs": [],
329
+ "source": []
330
+ },
331
+ {
332
+ "cell_type": "code",
333
+ "execution_count": null,
334
+ "id": "dab58080",
335
+ "metadata": {},
336
+ "outputs": [],
337
+ "source": []
338
+ },
339
+ {
340
+ "cell_type": "code",
341
+ "execution_count": null,
342
+ "id": "5997093e",
343
+ "metadata": {},
344
+ "outputs": [],
345
+ "source": []
346
+ },
347
+ {
348
+ "cell_type": "code",
349
+ "execution_count": null,
350
+ "id": "4189cecd",
351
+ "metadata": {},
352
+ "outputs": [],
353
+ "source": []
354
+ },
355
+ {
356
+ "cell_type": "code",
357
+ "execution_count": null,
358
+ "id": "e0e9209e",
359
+ "metadata": {},
360
+ "outputs": [],
361
+ "source": []
362
+ },
363
+ {
364
+ "cell_type": "code",
365
+ "execution_count": null,
366
+ "id": "88fd7412",
367
+ "metadata": {},
368
+ "outputs": [],
369
+ "source": []
370
+ },
371
+ {
372
+ "cell_type": "code",
373
+ "execution_count": null,
374
+ "id": "3a954a40",
375
+ "metadata": {},
376
+ "outputs": [],
377
+ "source": []
378
+ },
379
+ {
380
+ "cell_type": "code",
381
+ "execution_count": null,
382
+ "id": "a81fe51f",
383
+ "metadata": {},
384
+ "outputs": [],
385
+ "source": []
386
+ },
387
+ {
388
+ "cell_type": "code",
389
+ "execution_count": null,
390
+ "id": "dda2c68d",
391
+ "metadata": {},
392
+ "outputs": [],
393
+ "source": []
394
+ },
395
+ {
396
+ "cell_type": "code",
397
+ "execution_count": null,
398
+ "id": "f40deb42",
399
+ "metadata": {},
400
+ "outputs": [],
401
+ "source": []
402
+ },
403
+ {
404
+ "cell_type": "code",
405
+ "execution_count": null,
406
+ "id": "95f14ee5",
407
+ "metadata": {},
408
+ "outputs": [],
409
+ "source": []
410
+ },
411
+ {
412
+ "cell_type": "code",
413
+ "execution_count": null,
414
+ "id": "075600a4",
415
+ "metadata": {},
416
+ "outputs": [],
417
+ "source": []
418
+ },
419
+ {
420
+ "cell_type": "code",
421
+ "execution_count": null,
422
+ "id": "ed137130",
423
+ "metadata": {},
424
+ "outputs": [],
425
+ "source": []
426
+ },
427
+ {
428
+ "cell_type": "code",
429
+ "execution_count": null,
430
+ "id": "c474b206",
431
+ "metadata": {},
432
+ "outputs": [],
433
+ "source": []
434
+ },
435
+ {
436
+ "cell_type": "code",
437
+ "execution_count": null,
438
+ "id": "1ac070f1",
439
+ "metadata": {},
440
+ "outputs": [],
441
+ "source": [
442
+ "import matplotlib.pyplot as plt\n",
443
+ "import networkx as nx\n",
444
+ "\n",
445
+ "# Define states and observations\n",
446
+ "states = [\"s1\", \"s2\"]\n",
447
+ "observations = [\"v1\", \"v2\", \"v3\"]\n",
448
+ "\n",
449
+ "# Create a directed graph\n",
450
+ "G = nx.DiGraph()\n",
451
+ "\n",
452
+ "# Add state and observation nodes\n",
453
+ "G.add_nodes_from(states + observations)\n",
454
+ "\n",
455
+ "# Define transitions (from state to state) and emissions (from state to observation) with probabilities\n",
456
+ "transitions = [(\"s1\", \"s1\", 0.1), (\"s1\", \"s2\", 0.9), \n",
457
+ " (\"s2\", \"s1\", 0.5), (\"s2\", \"s2\", 0.5)]\n",
458
+ "emissions = [(\"s1\", \"v1\", 0.3), (\"s1\", \"v2\", 0.5), (\"s1\", \"v3\", 0.2),\n",
459
+ " (\"s2\", \"v1\", 0.6), (\"s2\", \"v2\", 0.2), (\"s2\", \"v3\", 0.2)]\n",
460
+ "\n",
461
+ "# Add edges with weights (probabilities)\n",
462
+ "G.add_weighted_edges_from(transitions)\n",
463
+ "G.add_weighted_edges_from(emissions)\n",
464
+ "\n",
465
+ "# Set node colors: states in blue, observations in green\n",
466
+ "node_colors = ['lightblue' if node in states else 'lightgreen' for node in G.nodes]\n",
467
+ "\n",
468
+ "# Set position using spring layout (to avoid overlap)\n",
469
+ "pos = nx.spring_layout(G, seed=42, k=1.5)\n",
470
+ "\n",
471
+ "# Plot the graph\n",
472
+ "plt.figure(figsize=(10, 8))\n",
473
+ "nx.draw(G, pos, with_labels=True, node_size=3000, node_color=node_colors, font_size=12, font_weight='bold', arrows=True)\n",
474
+ "\n",
475
+ "# Draw edge labels with probabilities\n",
476
+ "edge_labels = nx.get_edge_attributes(G, 'weight')\n",
477
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10)\n",
478
+ "\n",
479
+ "# Title and show\n",
480
+ "plt.title('Hidden Markov Model with Probabilities')\n",
481
+ "plt.show()\n"
482
+ ]
483
+ },
484
+ {
485
+ "cell_type": "code",
486
+ "execution_count": null,
487
+ "id": "635dc455",
488
+ "metadata": {},
489
+ "outputs": [],
490
+ "source": [
491
+ "import matplotlib.pyplot as plt\n",
492
+ "import networkx as nx\n",
493
+ "\n",
494
+ "# Define states and observations\n",
495
+ "states = [\"s1\", \"s2\"]\n",
496
+ "observations = [\"v1\", \"v2\", \"v3\"]\n",
497
+ "\n",
498
+ "# Create a directed graph\n",
499
+ "G = nx.DiGraph()\n",
500
+ "\n",
501
+ "# Add state and observation nodes\n",
502
+ "G.add_nodes_from(states + observations)\n",
503
+ "\n",
504
+ "# Define initial probabilities, transitions (state to state) and emissions (state to observation) with probabilities\n",
505
+ "start_prob = {\"s1\": 1.0, \"s2\": 0.0} # Initial state probabilities\n",
506
+ "transitions = [(\"s1\", \"s1\", 0.1), (\"s1\", \"s2\", 0.9), \n",
507
+ " (\"s2\", \"s1\", 0.5), (\"s2\", \"s2\", 0.5)]\n",
508
+ "emissions = [(\"s1\", \"v1\", 0.3), (\"s1\", \"v2\", 0.5), (\"s1\", \"v3\", 0.2),\n",
509
+ " (\"s2\", \"v1\", 0.6), (\"s2\", \"v2\", 0.2), (\"s2\", \"v3\", 0.2)]\n",
510
+ "\n",
511
+ "# Add edges with weights (probabilities)\n",
512
+ "G.add_weighted_edges_from(transitions)\n",
513
+ "G.add_weighted_edges_from(emissions)\n",
514
+ "\n",
515
+ "# Set node colors: states in blue, observations in green\n",
516
+ "node_colors = ['lightblue' if node in states else 'lightgreen' for node in G.nodes]\n",
517
+ "\n",
518
+ "# Set position using spring layout (to avoid overlap)\n",
519
+ "pos = nx.spring_layout(G, seed=42, k=1.5)\n",
520
+ "\n",
521
+ "# Plot the graph\n",
522
+ "plt.figure(figsize=(12, 10))\n",
523
+ "\n",
524
+ "# Draw the graph (states are in blue, observations in green)\n",
525
+ "nx.draw(G, pos, with_labels=True, node_size=3000, node_color=node_colors, font_size=12, font_weight='bold', arrows=True)\n",
526
+ "\n",
527
+ "# Draw edge labels with probabilities\n",
528
+ "edge_labels = nx.get_edge_attributes(G, 'weight')\n",
529
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10)\n",
530
+ "\n",
531
+ "# Draw initial probability annotations\n",
532
+ "start_state_label = f\"Start: s1 = {start_prob['s1']}, s2 = {start_prob['s2']}\"\n",
533
+ "plt.text(0.5, 1.1, start_state_label, horizontalalignment='center', fontsize=12, color='black', weight='bold')\n",
534
+ "\n",
535
+ "# Add transition and emission annotations for clarity\n",
536
+ "for (start, end, prob) in transitions:\n",
537
+ " plt.text(pos[start][0], pos[start][1] + 0.1, f\"p={prob:.2f}\", fontsize=10, color='blue')\n",
538
+ "\n",
539
+ "for (state, obs, prob) in emissions:\n",
540
+ " plt.text(pos[state][0], pos[state][1] - 0.1, f\"p={prob:.2f}\", fontsize=10, color='green')\n",
541
+ "\n",
542
+ "# Title and show\n",
543
+ "plt.title('Hidden Markov Model (HMM) Representation with Probabilities')\n",
544
+ "plt.show()\n"
545
+ ]
546
+ },
547
+ {
548
+ "cell_type": "code",
549
+ "execution_count": null,
550
+ "id": "d70757e2",
551
+ "metadata": {},
552
+ "outputs": [],
553
+ "source": []
554
+ },
555
+ {
556
+ "cell_type": "code",
557
+ "execution_count": null,
558
+ "id": "7f3dbfd8",
559
+ "metadata": {},
560
+ "outputs": [],
561
+ "source": []
562
+ },
563
+ {
564
+ "cell_type": "code",
565
+ "execution_count": null,
566
+ "id": "69fc82f1",
567
+ "metadata": {},
568
+ "outputs": [],
569
+ "source": []
570
+ },
571
+ {
572
+ "cell_type": "code",
573
+ "execution_count": null,
574
+ "id": "decf526c",
575
+ "metadata": {},
576
+ "outputs": [],
577
+ "source": []
578
+ },
579
+ {
580
+ "cell_type": "code",
581
+ "execution_count": null,
582
+ "id": "0ebbcf48",
583
+ "metadata": {},
584
+ "outputs": [],
585
+ "source": []
586
+ },
587
+ {
588
+ "cell_type": "code",
589
+ "execution_count": null,
590
+ "id": "2d5589e6",
591
+ "metadata": {},
592
+ "outputs": [],
593
+ "source": []
594
+ },
595
+ {
596
+ "cell_type": "code",
597
+ "execution_count": null,
598
+ "id": "64314504",
599
+ "metadata": {},
600
+ "outputs": [],
601
+ "source": [
602
+ "import numpy as np\n",
603
+ "import matplotlib.pyplot as plt\n",
604
+ "import networkx as nx\n",
605
+ "from hmmlearn.hmm import CategoricalHMM\n",
606
+ "\n",
607
+ "# Initial Parameters\n",
608
+ "start_prob = np.array([1.0, 0.0]) # Initial state probabilities (π)\n",
609
+ "trans_mat = np.array([ # Transition matrix (A)\n",
610
+ " [0.1, 0.9],\n",
611
+ " [0.5, 0.5]\n",
612
+ "])\n",
613
+ "emission_prob = np.array([ # Emission matrix (B)\n",
614
+ " [0.3, 0.5, 0.2],\n",
615
+ " [0.6, 0.2, 0.2]\n",
616
+ "])\n",
617
+ "\n",
618
+ "# Observation sequence in numeric form (e.g., [v3, v2, v1] -> [2, 1, 0])\n",
619
+ "observed_sequence_numeric = np.array([[2], [1], [0]])\n",
620
+ "\n",
621
+ "# Define states and observations for clarity\n",
622
+ "states = [\"s1\", \"s2\"] # State labels\n",
623
+ "observations = [\"v1\", \"v2\", \"v3\"] # Observation labels\n",
624
+ "\n",
625
+ "# Create and configure the hmmlearn model\n",
626
+ "model = CategoricalHMM(n_components=2, n_features=3, n_iter=0, verbose=False)\n",
627
+ "model.startprob_ = start_prob\n",
628
+ "model.transmat_ = trans_mat\n",
629
+ "model.emissionprob_ = emission_prob\n",
630
+ "\n",
631
+ "# Create directed graph for the HMM visualization\n",
632
+ "G = nx.DiGraph()\n",
633
+ "\n",
634
+ "# Add state nodes\n",
635
+ "for i, state in enumerate(states):\n",
636
+ " G.add_node(state, label=state)\n",
637
+ "\n",
638
+ "# Add observation nodes\n",
639
+ "for observation in observations:\n",
640
+ " G.add_node(observation, label=observation)\n",
641
+ "\n",
642
+ "# Add transition edges with probabilities (including self-transitions)\n",
643
+ "for i, state_from in enumerate(states):\n",
644
+ " for j, state_to in enumerate(states):\n",
645
+ " trans_prob = trans_mat[i, j]\n",
646
+ " if trans_prob > 0: # Only add edges with non-zero transition probability\n",
647
+ " G.add_edge(state_from, state_to, weight=trans_prob)\n",
648
+ "\n",
649
+ "# Add emission edges (representing each state emitting observations with their probabilities)\n",
650
+ "for i, state in enumerate(states):\n",
651
+ " for j, observation in enumerate(observations):\n",
652
+ " emit_prob = emission_prob[i, j]\n",
653
+ " if emit_prob > 0: # Only add edges with non-zero emission probability\n",
654
+ " G.add_edge(state, observation, weight=emit_prob)\n",
655
+ "\n",
656
+ "# Add the start probability edge from a virtual \"Start\" node to the initial state\n",
657
+ "G.add_edge('Start', states[0], weight=start_prob[0])\n",
658
+ "G.add_edge('Start', states[1], weight=start_prob[1])\n",
659
+ "\n",
660
+ "# Prepare edge labels (for transition and emission probabilities)\n",
661
+ "labels = nx.get_edge_attributes(G, 'weight')\n",
662
+ "\n",
663
+ "# Define custom positions to improve alignment\n",
664
+ "pos = {\n",
665
+ " 'Start': (0.5, 1.1), # Place 'Start' at the top\n",
666
+ " 's1': (0.25, 0.5), # State 1 to the left\n",
667
+ " 's2': (0.75, 0.5), # State 2 to the right\n",
668
+ " 'v1': (0.1, 0.1), # Observation v1 below state 1\n",
669
+ " 'v2': (0.5, 0.1), # Observation v2 centered below the states\n",
670
+ " 'v3': (0.9, 0.1) # Observation v3 below state 2\n",
671
+ "}\n",
672
+ "\n",
673
+ "# Adjust position of nodes\n",
674
+ "for i, state in enumerate(states):\n",
675
+ " pos[state] = (pos[state][0], pos[state][1]) # Slightly adjust y for better vertical alignment\n",
676
+ "\n",
677
+ "# Create the plot\n",
678
+ "plt.figure(figsize=(14, 12))\n",
679
+ "\n",
680
+ "# Draw nodes\n",
681
+ "nx.draw_networkx_nodes(G, pos, node_size=2500, node_color='skyblue', alpha=0.6)\n",
682
+ "\n",
683
+ "# Draw state labels\n",
684
+ "nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold', font_color='black')\n",
685
+ "\n",
686
+ "# Draw edges\n",
687
+ "nx.draw_networkx_edges(G, pos, width=2, alpha=0.6, edge_color='gray')\n",
688
+ "\n",
689
+ "# Draw edge labels for probabilities\n",
690
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_size=10)\n",
691
+ "\n",
692
+ "# Add title\n",
693
+ "plt.title(f'HMM Structure Visualization (Transitions and Emissions)', fontsize=16)\n",
694
+ "plt.axis('off') # Hide axes\n",
695
+ "\n",
696
+ "# Show the plot\n",
697
+ "plt.show()\n"
698
+ ]
699
+ },
700
+ {
701
+ "cell_type": "code",
702
+ "execution_count": null,
703
+ "id": "e3c12642",
704
+ "metadata": {},
705
+ "outputs": [],
706
+ "source": [
707
+ "import numpy as np\n",
708
+ "import matplotlib.pyplot as plt\n",
709
+ "import networkx as nx\n",
710
+ "from hmmlearn.hmm import CategoricalHMM\n",
711
+ "\n",
712
+ "# Initial Parameters\n",
713
+ "start_prob = np.array([1.0, 0.0]) # Initial state probabilities (π)\n",
714
+ "trans_mat = np.array([ # Transition matrix (A)\n",
715
+ " [0.1, 0.9],\n",
716
+ " [0.5, 0.5]\n",
717
+ "])\n",
718
+ "emission_prob = np.array([ # Emission matrix (B)\n",
719
+ " [0.3, 0.5, 0.2],\n",
720
+ " [0.6, 0.2, 0.2]\n",
721
+ "])\n",
722
+ "\n",
723
+ "# Define states and observations\n",
724
+ "states = [\"s1\", \"s2\"]\n",
725
+ "observations = [\"v1\", \"v2\", \"v3\"]\n",
726
+ "\n",
727
+ "# Create HMM model and assign parameters\n",
728
+ "model = CategoricalHMM(n_components=2, n_features=3, n_iter=0)\n",
729
+ "model.startprob_ = start_prob\n",
730
+ "model.transmat_ = trans_mat\n",
731
+ "model.emissionprob_ = emission_prob\n",
732
+ "\n",
733
+ "# Create directed graph for visualization\n",
734
+ "G = nx.DiGraph()\n",
735
+ "for i, state in enumerate(states):\n",
736
+ " G.add_node(state)\n",
737
+ "for obs in observations:\n",
738
+ " G.add_node(obs)\n",
739
+ "G.add_edge('Start', states[0], weight=start_prob[0])\n",
740
+ "G.add_edge('Start', states[1], weight=start_prob[1])\n",
741
+ "\n",
742
+ "# Add transitions and emissions\n",
743
+ "for i, state_from in enumerate(states):\n",
744
+ " for j, state_to in enumerate(states):\n",
745
+ " if trans_mat[i, j] > 0:\n",
746
+ " G.add_edge(state_from, state_to, weight=trans_mat[i, j])\n",
747
+ " for j, obs in enumerate(observations):\n",
748
+ " if emission_prob[i, j] > 0:\n",
749
+ " G.add_edge(state_from, obs, weight=emission_prob[i, j])\n",
750
+ "\n",
751
+ "# Define node positions\n",
752
+ "pos = {\n",
753
+ " 'Start': (0.5, 1.1), 's1': (0.25, 0.5), 's2': (0.75, 0.5),\n",
754
+ " 'v1': (0.1, 0.1), 'v2': (0.5, 0.1), 'v3': (0.9, 0.1)\n",
755
+ "}\n",
756
+ "\n",
757
+ "# Create the plot\n",
758
+ "plt.figure(figsize=(14, 12))\n",
759
+ "nx.draw_networkx_nodes(G, pos, node_size=2500, node_color='skyblue', alpha=0.6)\n",
760
+ "nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold')\n",
761
+ "nx.draw_networkx_edges(G, pos, width=2, alpha=0.6, edge_color='gray')\n",
762
+ "nx.draw_networkx_edge_labels(G, pos, edge_labels=nx.get_edge_attributes(G, 'weight'), font_size=10)\n",
763
+ "\n",
764
+ "# Add title and display\n",
765
+ "plt.title('HMM Structure Visualization', fontsize=16)\n",
766
+ "plt.axis('off')\n",
767
+ "plt.show()\n"
768
+ ]
769
+ },
770
+ {
771
+ "cell_type": "code",
772
+ "execution_count": null,
773
+ "id": "9750255d",
774
+ "metadata": {},
775
+ "outputs": [],
776
+ "source": []
777
+ },
778
+ {
779
+ "cell_type": "code",
780
+ "execution_count": null,
781
+ "id": "c8d8dbbc",
782
+ "metadata": {},
783
+ "outputs": [],
784
+ "source": []
785
+ },
786
+ {
787
+ "cell_type": "code",
788
+ "execution_count": null,
789
+ "id": "3b6ee519",
790
+ "metadata": {},
791
+ "outputs": [],
792
+ "source": [
793
+ "import numpy as np\n",
794
+ "from hmmlearn.hmm import CategoricalHMM\n",
795
+ "\n",
796
+ "# Initial Parameters\n",
797
+ "start_prob = np.array([1.0, 0.0]) # Initial state probabilities (π)\n",
798
+ "trans_mat = np.array([ # Transition matrix (A)\n",
799
+ " [0.1, 0.9],\n",
800
+ " [0.5, 0.5]\n",
801
+ "])\n",
802
+ "emission_prob = np.array([ # Emission matrix (B)\n",
803
+ " [0.3, 0.5, 0.2],\n",
804
+ " [0.6, 0.2, 0.2]\n",
805
+ "])\n",
806
+ "\n",
807
+ "# Observation sequence in numeric form (e.g., [v3, v2, v1] -> [2, 1, 0])\n",
808
+ "observed_sequence_numeric = np.array([[2], [1], [0]])\n",
809
+ "\n",
810
+ "# Define states and observations for clarity\n",
811
+ "states = [\"s1\", \"s2\"] # State labels\n",
812
+ "observations = [\"v1\", \"v2\", \"v3\"] # Observation labels\n",
813
+ "\n",
814
+ "# Number of states and features (possible observations)\n",
815
+ "n_states = len(states)\n",
816
+ "n_features = len(observations)\n",
817
+ "\n",
818
+ "# Create and configure the hmmlearn model\n",
819
+ "model = CategoricalHMM(n_components=n_states, n_features=n_features, n_iter=0, verbose=False)\n",
820
+ "\n",
821
+ "# Manually set the parameters after model creation\n",
822
+ "model.startprob_ = start_prob\n",
823
+ "model.transmat_ = trans_mat\n",
824
+ "model.emissionprob_ = emission_prob\n",
825
+ "\n",
826
+ "# Print model parameters\n",
827
+ "print(\"--- HMM Model Parameters ---\")\n",
828
+ "print(f\"Start Probabilities (π): {model.startprob_}\")\n",
829
+ "print(f\"Transition Matrix (A):\\n{model.transmat_}\")\n",
830
+ "print(f\"Emission Matrix (B):\\n{model.emissionprob_}\")\n",
831
+ "print(f\"Observed Sequence (Numeric): {observed_sequence_numeric.flatten()}\")\n",
832
+ "print(\"-\" * 30)\n",
833
+ "\n",
834
+ "# --- 1. Forward Algorithm (Likelihood P(O|λ)) ---\n",
835
+ "log_likelihood = model.score(observed_sequence_numeric)\n",
836
+ "likelihood = np.exp(log_likelihood)\n",
837
+ "\n",
838
+ "print(f\"--- Forward Algorithm (Likelihood P(O|λ)) ---\")\n",
839
+ "print(f\"Log Likelihood: {log_likelihood:.6f}\")\n",
840
+ "print(f\"Likelihood: {likelihood:.6f}\")\n",
841
+ "print(f\"(This is the probability of observing the sequence {observations[2]}, {observations[1]}, {observations[0]} given the model)\")\n",
842
+ "print(\"-\" * 30)\n",
843
+ "\n",
844
+ "# --- 2. Viterbi Algorithm (Most Likely Path) ---\n",
845
+ "logprob_viterbi, best_path_indices_viterbi = model.decode(observed_sequence_numeric, algorithm=\"viterbi\")\n",
846
+ "best_path_prob_viterbi = np.exp(logprob_viterbi)\n",
847
+ "best_path_labels_viterbi = [states[i] for i in best_path_indices_viterbi]\n",
848
+ "\n",
849
+ "print(f\"--- Viterbi Algorithm (Most Likely State Sequence) ---\")\n",
850
+ "print(f\"Most Likely Hidden State Sequence (Viterbi): {best_path_labels_viterbi} (Numeric: {best_path_indices_viterbi})\")\n",
851
+ "print(f\"Log Probability of this path: {logprob_viterbi:.6f}\")\n",
852
+ "print(f\"Probability of this path: {best_path_prob_viterbi:.6f}\")\n",
853
+ "print(\"-\" * 30)\n",
854
+ "\n",
855
+ "# --- 3. MAP Algorithm (Most Likely State Sequence) ---\n",
856
+ "logprob_map, best_path_indices_map = model.decode(observed_sequence_numeric, algorithm=\"map\")\n",
857
+ "best_path_prob_map = np.exp(logprob_map)\n",
858
+ "best_path_labels_map = [states[i] for i in best_path_indices_map]\n",
859
+ "\n",
860
+ "print(f\"--- MAP Algorithm (Most Likely State Sequence) ---\")\n",
861
+ "print(f\"Most Likely Hidden State Sequence (MAP): {best_path_labels_map} (Numeric: {best_path_indices_map})\")\n",
862
+ "print(f\"Log Probability of this path: {logprob_map:.6f}\")\n",
863
+ "print(f\"Probability of this path: {best_path_prob_map:.6f}\")\n",
864
+ "print(\"-\" * 30)\n",
865
+ "\n",
866
+ "# --- 4. Forward-Backward Algorithm (Posterior Probabilities) ---\n",
867
+ "posterior_probs = model.predict_proba(observed_sequence_numeric)\n",
868
+ "\n",
869
+ "print(f\"--- Forward-Backward Algorithm (Posterior Probabilities P(state_t|O,λ)) ---\")\n",
870
+ "print(\"Rows = Time Steps (for observations v3, v2, v1)\")\n",
871
+ "print(\"Columns = States [s1, s2]\")\n",
872
+ "print(posterior_probs.round(4))\n",
873
+ "print(\"-\" * 30)\n"
874
+ ]
875
+ },
876
+ {
877
+ "cell_type": "code",
878
+ "execution_count": null,
879
+ "id": "e64012f2",
880
+ "metadata": {},
881
+ "outputs": [],
882
+ "source": [
883
+ "CategoricalHMM?"
884
+ ]
885
+ },
886
+ {
887
+ "cell_type": "code",
888
+ "execution_count": null,
889
+ "id": "abc0ffae",
890
+ "metadata": {},
891
+ "outputs": [],
892
+ "source": [
893
+ "import numpy as np\n",
894
+ "from hmmlearn.hmm import CategoricalHMM\n",
895
+ "\n",
896
+ "start_prob = np.array([1.0, 0.0])\n",
897
+ "\n",
898
+ "trans_mat = np.array([\n",
899
+ " [0.1, 0.9],\n",
900
+ " [0.5, 0.5]\n",
901
+ "])\n",
902
+ "\n",
903
+ "emission_prob = np.array([\n",
904
+ " [0.3, 0.5, 0.2],\n",
905
+ " [0.6, 0.2, 0.2]\n",
906
+ "])\n",
907
+ "\n",
908
+ "observed_sequence_numeric = np.array([[2], [1], [0]])\n",
909
+ "\n",
910
+ "states = [\"s1\", \"s2\"]\n",
911
+ "observations = [\"v1\", \"v2\", \"v3\"]\n",
912
+ "\n",
913
+ "model = CategoricalHMM(n_components=len(states), n_iter=0, verbose=False)\n",
914
+ "\n",
915
+ "model.startprob_ = start_prob\n",
916
+ "model.transmat_ = trans_mat\n",
917
+ "model.emissionprob_ = emission_prob\n",
918
+ "\n",
919
+ "print(\"--- HMM Model Parameters ---\")\n",
920
+ "print(f\"Start Probabilities (π): {model.startprob_}\")\n",
921
+ "print(f\"Transition Matrix (A):\\n{model.transmat_}\")\n",
922
+ "print(f\"Emission Matrix (B):\\n{model.emissionprob_}\")\n",
923
+ "print(f\"Observed Sequence (Numeric): {observed_sequence_numeric.flatten()}\")\n",
924
+ "print(\"-\" * 30)\n",
925
+ "\n",
926
+ "log_likelihood = model.score(observed_sequence_numeric)\n",
927
+ "likelihood = np.exp(log_likelihood)\n",
928
+ "\n",
929
+ "print(f\"--- Forward Algorithm (Likelihood P(O|λ)) ---\")\n",
930
+ "print(f\"Log Likelihood: {log_likelihood:.6f}\")\n",
931
+ "print(f\"Likelihood: {likelihood:.6f}\")\n",
932
+ "print(f\"(This is the probability of observing the sequence {observations[2]}, {observations[1]}, {observations[0]} given the model)\")\n",
933
+ "print(\"-\" * 30)\n",
934
+ "\n",
935
+ "logprob_viterbi, best_path_indices = model.decode(observed_sequence_numeric, algorithm=\"viterbi\")\n",
936
+ "best_path_prob = np.exp(logprob_viterbi)\n",
937
+ "best_path_labels = [states[i] for i in best_path_indices]\n",
938
+ "\n",
939
+ "print(f\"--- Viterbi Algorithm (Most Likely State Sequence) ---\")\n",
940
+ "print(f\"Most Likely Hidden State Sequence: {best_path_labels} (Numeric: {best_path_indices})\")\n",
941
+ "print(f\"Log Probability of this path: {logprob_viterbi:.6f}\")\n",
942
+ "print(f\"Probability of this path: {best_path_prob:.6f}\")\n",
943
+ "print(\"-\" * 30)\n",
944
+ "\n",
945
+ "posterior_probs = model.predict_proba(observed_sequence_numeric)\n",
946
+ "\n",
947
+ "print(f\"--- Forward-Backward Algorithm (Posterior Probabilities P(state_t|O,λ)) ---\")\n",
948
+ "print(\"Rows = Time Steps (for observations v3, v2, v1)\")\n",
949
+ "print(\"Columns = States [s1, s2]\")\n",
950
+ "print(posterior_probs.round(4))\n",
951
+ "print(\"-\" * 30)\n"
952
+ ]
953
+ },
954
+ {
955
+ "cell_type": "code",
956
+ "execution_count": null,
957
+ "id": "7bbc7e10",
958
+ "metadata": {},
959
+ "outputs": [],
960
+ "source": [
961
+ "import numpy as np\n",
962
+ "from hmmlearn.hmm import CategoricalHMM\n",
963
+ "\n",
964
+ "# --- Parameters ---\n",
965
+ "# Define the model parameters. These include:\n",
966
+ "# - Initial state probabilities (π)\n",
967
+ "# - Transition matrix (A)\n",
968
+ "# - Emission matrix (B)\n",
969
+ "\n",
970
+ "# Initial state probabilities (π)\n",
971
+ "# This represents the initial distribution of the states. In our case, \n",
972
+ "# we start with state s1 with a 100% probability and never start in state s2.\n",
973
+ "start_prob = np.array([1.0, 0.0]) # Starting in state s1 (prob = 1)\n",
974
+ "\n",
975
+ "# Transition matrix (A)\n",
976
+ "# This matrix defines the probabilities of transitioning from one state to another.\n",
977
+ "# For example, from state s1, there's a 10% chance of staying in s1, and a 90% chance of moving to s2.\n",
978
+ "# From state s2, there's a 50% chance of moving to s1 and a 50% chance of staying in s2.\n",
979
+ "trans_mat = np.array([\n",
980
+ " [0.1, 0.9], # Transition probabilities from state s1: P(s1 -> s1) = 0.1, P(s1 -> s2) = 0.9\n",
981
+ " [0.5, 0.5] # Transition probabilities from state s2: P(s2 -> s1) = 0.5, P(s2 -> s2) = 0.5\n",
982
+ "])\n",
983
+ "\n",
984
+ "# Emission matrix (B)\n",
985
+ "# This matrix defines the probability of observing each of the observations (v1, v2, v3) \n",
986
+ "# given the current state.\n",
987
+ "# For example, when in state s1:\n",
988
+ "# P(v1|s1) = 0.3, P(v2|s1) = 0.5, P(v3|s1) = 0.2\n",
989
+ "# When in state s2:\n",
990
+ "# P(v1|s2) = 0.6, P(v2|s2) = 0.2, P(v3|s2) = 0.2\n",
991
+ "emission_prob = np.array([\n",
992
+ " [0.3, 0.5, 0.2], # Emission probabilities for state s1: P(v1|s1) = 0.3, P(v2|s1) = 0.5, P(v3|s1) = 0.2\n",
993
+ " [0.6, 0.2, 0.2] # Emission probabilities for state s2: P(v1|s2) = 0.6, P(v2|s2) = 0.2, P(v3|s2) = 0.2\n",
994
+ "])\n",
995
+ "\n",
996
+ "# Observation sequence (v1=0, v2=1, v3=2)\n",
997
+ "# We define an observation sequence [v3, v2, v1] as a numeric sequence [2, 1, 0].\n",
998
+ "observed_sequence_numeric = np.array([[2], [1], [0]]) # Shape (n_samples, 1)\n",
999
+ "\n",
1000
+ "# State and Observation labels (for clarity)\n",
1001
+ "states = [\"s1\", \"s2\"] # Two hidden states: s1 and s2\n",
1002
+ "observations = [\"v1\", \"v2\", \"v3\"] # Three possible observations: v1, v2, v3\n",
1003
+ "\n",
1004
+ "# --- Create and Configure hmmlearn Model ---\n",
1005
+ "# Initialize the HMM model with 2 components (states).\n",
1006
+ "# n_iter=0 means we are not training the model, we are directly assigning the parameters.\n",
1007
+ "model = CategoricalHMM(n_components=len(states), n_iter=0, verbose=False)\n",
1008
+ "\n",
1009
+ "# Set the model parameters\n",
1010
+ "model.startprob_ = start_prob # Set the initial state probabilities (π)\n",
1011
+ "model.transmat_ = trans_mat # Set the transition matrix (A)\n",
1012
+ "model.emissionprob_ = emission_prob # Set the emission matrix (B)\n",
1013
+ "print(model.startprob_,model.transmat_,model.emissionprob_,sep='\\n')\n",
1014
+ "# --- Print Model Parameters ---\n",
1015
+ "print(\"--- HMM Model Parameters ---\")\n",
1016
+ "print(f\"Start Probabilities (π): {model.startprob_}\")\n",
1017
+ "print(f\"Transition Matrix (A):\\n{model.transmat_}\")\n",
1018
+ "print(f\"Emission Matrix (B):\\n{model.emissionprob_}\")\n",
1019
+ "print(f\"Observed Sequence (Numeric): {observed_sequence_numeric.flatten()}\")\n",
1020
+ "print(\"-\" * 30)\n",
1021
+ "\n",
1022
+ "# --- 1. Forward Algorithm (Likelihood P(O|λ)) ---\n",
1023
+ "# The Forward algorithm calculates the likelihood of observing the sequence of events (O)\n",
1024
+ "# given the model parameters (λ). It is internally implemented in model.score().\n",
1025
+ "log_likelihood = model.score(observed_sequence_numeric) # Log-likelihood of the observation sequence\n",
1026
+ "likelihood = np.exp(log_likelihood) # Convert log-likelihood to probability\n",
1027
+ "\n",
1028
+ "# Print the result of the Forward Algorithm\n",
1029
+ "print(f\"--- Forward Algorithm (Likelihood P(O|λ)) ---\")\n",
1030
+ "print(f\"Log Likelihood: {log_likelihood:.6f}\")\n",
1031
+ "print(f\"Likelihood: {likelihood:.6f}\")\n",
1032
+ "print(f\"(This is the probability of observing the sequence {observations[2]}, {observations[1]}, {observations[0]} given the model)\")\n",
1033
+ "print(\"-\" * 30)\n",
1034
+ "\n",
1035
+ "# --- 2. Viterbi Algorithm (Most Likely State Sequence) ---\n",
1036
+ "# The Viterbi algorithm is used to find the most likely sequence of hidden states \n",
1037
+ "# that could have generated the observed sequence.\n",
1038
+ "# The model.decode() function applies the Viterbi algorithm.\n",
1039
+ "logprob_viterbi, best_path_indices = model.decode(observed_sequence_numeric, algorithm=\"viterbi\")\n",
1040
+ "best_path_prob = np.exp(logprob_viterbi) # Convert log-probability to normal probability\n",
1041
+ "best_path_labels = [states[i] for i in best_path_indices] # Convert numeric indices to state labels\n",
1042
+ "\n",
1043
+ "# Print the result of the Viterbi Algorithm\n",
1044
+ "print(f\"--- Viterbi Algorithm (Most Likely State Sequence) ---\")\n",
1045
+ "print(f\"Most Likely Hidden State Sequence: {best_path_labels} (Numeric: {best_path_indices})\")\n",
1046
+ "print(f\"Log Probability of this path: {logprob_viterbi:.6f}\")\n",
1047
+ "print(f\"Probability of this path: {best_path_prob:.6f}\")\n",
1048
+ "print(\"-\" * 30)\n",
1049
+ "\n",
1050
+ "# --- 3. Forward-Backward Algorithm (Posterior Probabilities) ---\n",
1051
+ "# The Forward-Backward algorithm calculates the posterior probabilities of the hidden states\n",
1052
+ "# at each time step, given the entire observed sequence. This is done using model.predict_proba().\n",
1053
+ "posterior_probs = model.predict_proba(observed_sequence_numeric)\n",
1054
+ "\n",
1055
+ "# Print the result of the Forward-Backward Algorithm\n",
1056
+ "print(f\"--- Forward-Backward Algorithm (Posterior Probabilities P(state_t|O,λ)) ---\")\n",
1057
+ "print(\"Rows = Time Steps (for observations v3, v2, v1)\")\n",
1058
+ "print(\"Columns = States [s1, s2]\")\n",
1059
+ "print(posterior_probs.round(4)) # Rounded for readability\n",
1060
+ "print(\"-\" * 30)\n",
1061
+ "\n",
1062
+ "# You can verify that sum(posterior_probs[t,:]) == 1.0 for each time step t (since it's a probability distribution).\n"
1063
+ ]
1064
+ }
1065
+ ],
1066
+ "metadata": {
1067
+ "kernelspec": {
1068
+ "display_name": "Python 3 (ipykernel)",
1069
+ "language": "python",
1070
+ "name": "python3"
1071
+ },
1072
+ "language_info": {
1073
+ "codemirror_mode": {
1074
+ "name": "ipython",
1075
+ "version": 3
1076
+ },
1077
+ "file_extension": ".py",
1078
+ "mimetype": "text/x-python",
1079
+ "name": "python",
1080
+ "nbconvert_exporter": "python",
1081
+ "pygments_lexer": "ipython3",
1082
+ "version": "3.12.4"
1083
+ }
1084
+ },
1085
+ "nbformat": 4,
1086
+ "nbformat_minor": 5
1087
+ }