The HMM Procedure
Example 18.4 Analysis of English Characters by Using a Finite HMM
In natural language processing (NLP), practitioners want to learn the structure of sentences and predict the sequences of words. HMMs have been widely applied for characterizing the statistical features of natural languages; for more information, see Jurafsky and Martin (2019). This example runs the model from Cave and Neuwirth (1980) to illustrate how to use the finite HMM to analyze the English language. The data set used in this example was extracted and converted from the classic novel Vanity Fair. To process the raw text, first remove all punctuation and numbers and convert all letters to lowercase.
The following statements create the table for the first 5,000 symbols. The table has two columns: column t is the position of the symbol, and column character is the value at time t.
data text;
input t character $8. ;
datalines;
1 c
2 h
3 a
4 p
5 t
6 e
7 r
8
... more lines ...
4992 c
4993 k
4994
4995 o
4996 n
4997
4998 h
4999 e
5000 r
;
When you get data set text, you can translate the column value into integers. The following statements relabel the character variables as the unique integers that the finite HMM procedure uses:
data tbltemp;
set text;
_temp_count_ = 1;
run;
proc sql;
create table f0 as
SELECT tbl.character, /* any other columns to be grouped */
sum(tbl._temp_count_) as count
FROM tbltemp tbl
group by tbl.character
;
quit;
data f0Id;
set f0;
y = _n_;
keep character y;
run;
proc print data=f0Id; run;
proc sort data=text out=textSort;
by character;
run;
PROC SQL;
CREATE TABLE textLeft AS
SELECT A.*, B.y
FROM textSort A LEFT JOIN f0Id B
ON A.character = B.character
ORDER BY character;
QUIT;
proc sort data=textLeft out=textLeft;
by t;
run;
data text2;
set textLeft;
run;
data mycas.text;;
set text2;
run;
This converts the novel into a sequence of 26 distinct letters and the word space, for a total of 27 symbols. Then, translate the characters to numbers, a to 2, b to 3, …, z to 27, and word space to 1.
The conversion matching table is shown in Output 18.4.1.
Output 18.4.1: Matching Table
| Obs | character | y |
|---|---|---|
| 1 | 1 | |
| 2 | a | 2 |
| 3 | b | 3 |
| 4 | c | 4 |
| 5 | d | 5 |
| 6 | e | 6 |
| 7 | f | 7 |
| 8 | g | 8 |
| 9 | h | 9 |
| 10 | i | 10 |
| 11 | j | 11 |
| 12 | k | 12 |
| 13 | l | 13 |
| 14 | m | 14 |
| 15 | n | 15 |
| 16 | o | 16 |
| 17 | p | 17 |
| 18 | q | 18 |
| 19 | r | 19 |
| 20 | s | 20 |
| 21 | t | 21 |
| 22 | u | 22 |
| 23 | v | 23 |
| 24 | w | 24 |
| 25 | x | 25 |
| 26 | y | 26 |
| 27 | z | 27 |
The following statements print the table after value conversion. The table, which is shown in Output 18.4.2, contains three columns: column t is the position of the symbol, column character is the original symbol, and column y is the translated value of the symbol at position t:
proc print data=text2(obs=10) noobs;
run;
Output 18.4.2: Converted Data of Vanity Fair
| t | character | y |
|---|---|---|
| 1 | c | 4 |
| 2 | h | 9 |
| 3 | a | 2 |
| 4 | p | 17 |
| 5 | t | 21 |
| 6 | e | 6 |
| 7 | r | 19 |
| 8 | 1 | |
| 9 | i | 10 |
| 10 | c | 4 |
Cave and Neuwirth’s model is assumed to have an underlying Markov chain with two hidden states. For each of these hidden states, assume that the 27 symbols appear according to a fixed probability distribution. The following statements estimate a finite HMM in which NSTATE=2 and NCATEGORY=27. There might be a lot of local maximums for the finite HMM; hence, you specify the multistart mode by specifying MULTISTART=1 in the OPTIMIZE statement.
data mycas.text;
set text;
run;
proc hmm data=mycas.text ;
id time=t;
model y / type=finite nstate=2 nCategory=27;
optimize algorithm=interiorpoint multistart=1;
run;
The number of observations and model information are shown in Output 18.4.3.
Output 18.4.3: Number of Observations and Model Information
The parameter estimates are shown in Output 18.4.4, and the fit statistics are shown in Output 18.4.5.
Output 18.4.4: Parameter Estimates
| Parameter Estimates | ||||
|---|---|---|---|---|
| Parameter | Estimate | Standard Error | t Value | Pr > |t| |
| TPM1_1 | 0.704759 | 0.024114 | 29.23 | <.0001 |
| TPM1_2 | 0.295241 | 0.024114 | 12.24 | <.0001 |
| TPM2_1 | 0.166937 | 0.025241 | 6.61 | <.0001 |
| TPM2_2 | 0.833063 | 0.025241 | 33.00 | <.0001 |
| CPM1_1 | 0.160701 | 0.012966 | 12.39 | <.0001 |
| CPM1_2 | 0.089868 | 0.010602 | 8.48 | <.0001 |
| CPM1_3 | 0.030318 | 0.006451 | 4.70 | <.0001 |
| CPM1_4 | 3.2313166E-9 | 0.000002708 | 0.00 | 0.9990 |
| CPM1_5 | 0.053245 | 0.013151 | 4.05 | <.0001 |
| CPM1_6 | 0.145947 | 0.013846 | 10.54 | <.0001 |
| CPM1_7 | 9.8853784E-8 | 0.000094772 | 0.00 | 0.9992 |
| CPM1_8 | 1.0702962E-8 | 0.000008608 | 0.00 | 0.9990 |
| CPM1_9 | 0.003558 | 0.007372 | 0.48 | 0.6294 |
| CPM1_10 | 0.079102 | 0.009718 | 8.14 | <.0001 |
| CPM1_11 | 0.010407 | 0.003235 | 3.22 | 0.0013 |
| CPM1_12 | 2.9038092E-9 | 0.000002435 | 0.00 | 0.9990 |
| CPM1_13 | 0.084697 | 0.011074 | 7.65 | <.0001 |
| CPM1_14 | 0.075036 | 0.010027 | 7.48 | <.0001 |
| CPM1_15 | 0.007264 | 0.016913 | 0.43 | 0.6676 |
| CPM1_16 | 9.4048854E-9 | 0.000008400 | 0.00 | 0.9991 |
| CPM1_17 | 0.016644 | 0.007055 | 2.36 | 0.0183 |
| CPM1_18 | 1.5509094E-9 | 0.000001267 | 0.00 | 0.9990 |
| CPM1_19 | 0.055810 | 0.011179 | 4.99 | <.0001 |
| CPM1_20 | 0.129421 | 0.014702 | 8.80 | <.0001 |
| CPM1_21 | 9.8906516E-9 | 0.000009233 | 0.00 | 0.9991 |
| CPM1_22 | 0.000444 | 0.004054 | 0.11 | 0.9127 |
| CPM1_23 | 0.020482 | 0.003971 | 5.16 | <.0001 |
| CPM1_24 | 0.004952 | 0.004536 | 1.09 | 0.2749 |
| CPM1_25 | 0.000722 | 0.001935 | 0.37 | 0.7090 |
| CPM1_26 | 0.029166 | 0.006321 | 4.61 | <.0001 |
| CPM1_27 | 0.002214 | 0.001130 | 1.96 | 0.0502 |
| CPM2_1 | 0.163361 | 0.008484 | 19.25 | <.0001 |
| CPM2_2 | 0.048428 | 0.006953 | 6.97 | <.0001 |
| CPM2_3 | 0.002578 | 0.002760 | 0.93 | 0.3503 |
| CPM2_4 | 0.038202 | 0.004086 | 9.35 | <.0001 |
| CPM2_5 | 0.022174 | 0.008344 | 2.66 | 0.0079 |
| CPM2_6 | 0.082464 | 0.008517 | 9.68 | <.0001 |
| CPM2_7 | 0.028182 | 0.003377 | 8.34 | <.0001 |
| CPM2_8 | 0.021606 | 0.002877 | 7.51 | <.0001 |
| CPM2_9 | 0.074078 | 0.006671 | 11.10 | <.0001 |
| CPM2_10 | 0.054831 | 0.005558 | 9.87 | <.0001 |
| CPM2_11 | 0.001002 | 0.001232 | 0.81 | 0.4159 |
| CPM2_12 | 0.010646 | 0.001924 | 5.53 | <.0001 |
| CPM2_13 | 4.4047865E-9 | 0.000003747 | 0.00 | 0.9991 |
| CPM2_14 | 0.002647 | 0.004408 | 0.60 | 0.5483 |
| CPM2_15 | 0.086386 | 0.008897 | 9.71 | <.0001 |
| CPM2_16 | 0.092061 | 0.007504 | 12.27 | <.0001 |
| CPM2_17 | 0.019706 | 0.004332 | 4.55 | <.0001 |
| CPM2_18 | 0.003444 | 0.001057 | 3.26 | 0.0011 |
| CPM2_19 | 0.054229 | 0.006840 | 7.93 | <.0001 |
| CPM2_20 | 0.031691 | 0.007756 | 4.09 | <.0001 |
| CPM2_21 | 0.099889 | 0.007977 | 12.52 | <.0001 |
| CPM2_22 | 0.030435 | 0.004060 | 7.50 | <.0001 |
| CPM2_23 | 9.164156E-9 | 0.000008615 | 0.00 | 0.9992 |
| CPM2_24 | 0.021936 | 0.003624 | 6.05 | <.0001 |
| CPM2_25 | 0.002097 | 0.001324 | 1.58 | 0.1133 |
| CPM2_26 | 0.007926 | 0.003175 | 2.50 | 0.0126 |
| CPM2_27 | 6.007417E-13 | 2.2325664E-8 | 0.00 | 1.0000 |
Output 18.4.5: Fit Statistics
| Fit Statistics | |
|---|---|
| Log Likelihood | -14289.90987 |
| AIC | 28691.819747 |
| AICC | 28693.11127 |
| BIC | 29056.782566 |
| HQC | 28819.733474 |
The most interesting part of this result is the result of the category probability matrix (CPM). In state 1, the probabilities of containing 3, 4, 5, …, 26, which correspond to the consonants, are significant. In state 2, the probabilities of containing 1, 2, 6, 10, 16, 22, which correspond to the vowels a, e, i, o, and u and the space, are significant. Without your having made any assumptions about the two hidden states, the CPM shows that one hidden state contains the vowels and the other hidden state contains the consonants. Interestingly, the space is treated more like a vowel in the context of English. The PROC HMM result shows that the distinction between vowels and consonants is a statistically significant feature inherent in the language. And thanks to HMMs, this could easily be deduced by someone who has no background knowledge of the language.