diff --git a/README.md b/README.md
index 9495dd7..22270ef 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,8 @@
 
 
 # lihang_book_algorithm
-
-哇!看到有人star这个项目了
-本来打算把这个项目当成一个备份的
-但既然有人star了,那么就要好好对待啦!!!
+被李航老师肯定啦!!开心!
+

 
 ## 简介
 我这里不介绍任何机器学习算法的原理,只是将《统计学习方法》中每一章的算法用我自己的方式实现一遍。
@@ -55,10 +53,13 @@
 
纯Python代码:[AdaBoost/adaboost.py](https://github.com/WenDesi/lihang_book_algorithm/blob/master/AdaBoost/adaboost.py)
 
Python C++代码:[AdaBoost/adaboost_cpp.py](https://github.com/WenDesi/lihang_book_algorithm/blob/master/AdaBoost/adaboost_cpp.py),[AdaBoost/Sign/Sign/sign.h](https://github.com/WenDesi/lihang_book_algorithm/blob/master/AdaBoost/Sign/Sign/sign.h),[AdaBoost/Sign/Sign/sign.cpp](https://github.com/WenDesi/lihang_book_algorithm/blob/master/AdaBoost/Sign/Sign/sign.cpp)
 
-### 第九章 EM算法及其推广
-正在施工中...
+### 第十章 隐马尔科夫模型
+博客:[李航《统计学习方法》第十章——用Python实现隐马尔科夫模型](http://blog.csdn.net/wds2006sdo/article/details/75212599)
+
代码:[hmm/hmm.py](https://github.com/WenDesi/lihang_book_algorithm/blob/master/hmm/hmm.py)
+
 
 ## 额外章节
+
 ###softmax分类器
 博客:[python 实现 softmax分类器(MNIST数据集)](http://blog.csdn.net/wds2006sdo/article/details/53699778)
 
代码:[softmax/softmax.py](https://github.com/WenDesi/lihang_book_algorithm/blob/master/softmax/softmax.py)
diff --git a/hmm/hmm.py b/hmm/hmm.py
new file mode 100644
index 0000000..2894f6a
--- /dev/null
+++ b/hmm/hmm.py
@@ -0,0 +1,238 @@
+# encoding=utf8
+
+import numpy as np
+import csv
+
+class HMM(object):
+    def __init__(self,N,M):
+        self.A = np.zeros((N,N))        # 状态转移概率矩阵
+        self.B = np.zeros((N,M))        # 观测概率矩阵
+        self.Pi = np.array([1.0/N]*N)   # 初始状态概率矩阵
+
+        self.N = N                      # 可能的状态数
+        self.M = M                      # 可能的观测数
+
+    def cal_probality(self, O):
+        self.T = len(O)
+        self.O = O
+
+        self.forward()
+        return sum(self.alpha[self.T-1])
+
+    def forward(self):
+        """
+        前向算法
+        """
+        self.alpha = np.zeros((self.T,self.N))
+
+        # 公式 10.15
+        for i in range(self.N):
+            self.alpha[0][i] = self.Pi[i]*self.B[i][self.O[0]]
+
+        # 公式10.16
+        for t in range(1,self.T):
+            for i in range(self.N):
+                sum = 0
+                for j in range(self.N):
+                    sum += self.alpha[t-1][j]*self.A[j][i]
+                self.alpha[t][i] = sum * self.B[i][self.O[t]]
+
+    def backward(self):
+        """
+        后向算法
+        """
+        self.beta = np.zeros((self.T,self.N))
+
+        # 公式10.19
+        for i in range(self.N):
+            self.beta[self.T-1][i] = 1
+
+        # 公式10.20
+        for t in range(self.T-2,-1,-1):
+            for i in range(self.N):
+                for j in range(self.N):
+                    self.beta[t][i] += self.A[i][j]*self.B[j][self.O[t+1]]*self.beta[t+1][j]
+
+    def cal_gamma(self, i, t):
+        """
+        公式 10.24
+        """
+        numerator = self.alpha[t][i]*self.beta[t][i]
+        denominator = 0
+
+        for j in range(self.N):
+            denominator += self.alpha[t][j]*self.beta[t][j]
+
+        return numerator/denominator
+
+    def cal_ksi(self, i, j, t):
+        """
+        公式 10.26
+        """
+
+        numerator = self.alpha[t][i]*self.A[i][j]*self.B[j][self.O[t+1]]*self.beta[t+1][j]
+        denominator = 0
+
+        for i in range(self.N):
+            for j in range(self.N):
+                denominator += self.alpha[t][i]*self.A[i][j]*self.B[j][self.O[t+1]]*self.beta[t+1][j]
+
+        return numerator/denominator
+
+    def init(self):
+        """
+        随机生成 A,B,Pi
+        并保证每行相加等于 1
+        """
+        import random
+        for i in range(self.N):
+            randomlist = [random.randint(0,100) for t in range(self.N)]
+            Sum = sum(randomlist)
+            for j in range(self.N):
+                self.A[i][j] = randomlist[j]/Sum
+
+        for i in range(self.N):
+            randomlist = [random.randint(0,100) for t in range(self.M)]
+            Sum = sum(randomlist)
+            for j in range(self.M):
+                self.B[i][j] = randomlist[j]/Sum
+
+    def train(self, O, MaxSteps = 100):
+        self.T = len(O)
+        self.O = O
+
+        # 初始化
+        self.init()
+
+        step = 0
+        # 递推
+        while step