用HMM(隐马)图解三国杀的于吉“质疑”

时间:2022-08-29 09:03:38

·背景

最近乘闲暇之余初探了HMM(隐马尔科夫模型),觉得还有点意思,但是网上的教程都超级枯草,可读性很差,抄来抄去的,一堆公式仍在你面前,谁能搞的懂(但园内的两篇写的还算不错。真才实学)。在熬制3天后,把这篇心得反馈给各位码友,为了更加生动的说明模型,特举例三国杀的"于吉"以便加深各位印象。

用HMM(隐马)图解三国杀的于吉“质疑”

·于吉

武将技:【蛊惑】——你可以说出任何一种基本牌或非延时类锦囊牌,并正面朝下使用或打出一张手牌。若无人质疑,则该牌按你所述之牌结算。若有人质疑则亮出验明:若为真,质疑者各失去1点体力;若为假,质疑者各摸1张牌。无论真假,弃置被质疑的牌。仅当被质疑的牌为红桃花色且为真时,该牌仍然可以进行结算。最大的意义在于猜测真假,也就是HMM中的隐藏队列。

用HMM(隐马)图解三国杀的于吉“质疑” 用HMM(隐马)图解三国杀的于吉“质疑” 用HMM(隐马)图解三国杀的于吉“质疑”

·HMM 五对象

·观察队列:也就是对手打出的声明牌序,例如【杀、杀、桃、杀、南蛮】。这3张牌个人感觉算是于吉回合内声明频率最高的3张牌。

·隐藏队列:也就是对手打出该张牌时是真?是假?,例如【真、真、假、假、真】,这个是HMM之后要计算的对象之一。

·初始状态Matrix P/Pie:声明第一张牌时,是真是假的概率。

·状态转移Matrix A:从声明第二章牌开始,由真变假,或假变真,或真变真,或假变假的概率。

·混淆矩阵Matrix B:每次声明时的真假心态下,该将什么牌声明成什么牌。

·HMM 两大问题(还有一个学习就不写了)

·评估问题:该轮的声明牌序,其中存在假牌的可能性有多高?

·解码问题:该轮的声明牌序,其中哪几张牌可能为假牌?

·HMM 评估算法过程

用HMM(隐马)图解三国杀的于吉“质疑”

·HMM 解码算法过程

用HMM(隐马)图解三国杀的于吉“质疑”

·HMM测算结果

Complie Done

act:0   Q[0][0]:0.16            Q[0][1]:0.1
act:0 Q[1][0]:0.0332 Q[1][1]:0.047
act:1 Q[2][0]:0.021128 Q[2][1]:0.005476
act:0 Q[3][0]:0.003302 Q[3][1]:0.005047
act:2 Q[4][0]:0.00220564 Q[4][1]:0.00085047 Last Sum Prob=0.00305611 act:0 Q[0][0]:0.16 Q[0][1]:0.1
act:0 com[0]0.096 comp[1]0.07 Q[1][0]:0.0192 com[0]0.064 comp[1]0.03 Q[1][1]:0.032
act:1 com[0]0.01152 comp[1]0.0224 Q[2][0]:0.00896 com[0]0.00768 comp[1]0.0096 Q[2][1]:0.00192
act:0 com[0]0.005376 comp[1]0.001344 Q[3][0]:0.0010752 com[0]0.003584 comp[1]0.000576 Q[3][1]:0.001792
act:2 com[0]0.00064512 comp[1]0.0012544 Q[4][0]:0.00050176 com[0]0.00043008 comp[1]0.0005376 Q[4][1]:0.00016128 Last Max Prob:0.00050176 Path[0][0]=-1 Path[0][1]=-1
Path[1][0]=0 Path[1][1]=0
Path[2][0]=1 Path[2][1]=1
Path[3][0]=0 Path[3][1]=0
Path[4][0]=1 Path[4][1]=1 real 0m0.001s
user 0m0.000s
sys 0m0.000s

Last Sum Prob=0.00305611,个人理解更贴近于本次序列不作弊的可能性。

Path[i][j]来源t-1时刻两种隐藏状态的概率对比,前面<后面 为1,前面>后面 为0。从1和0的区别看,0的出现意味着该张牌声明时作假可能性更高。

·不足之处

  1. HMM主要依赖于t-1,而在真实世界中,于吉的声明会顾忌整个牌局,也就是t-N之前的状态。
  2. 大多数HMM关注两个互斥类属性(Yes or No),而在牌局中,于吉的声明真、假后,如果再出现质疑,会出现超越声明真假本身的真假效果(好拗口),这使得对手判断难度增加。
  3. HMM具有强关联,也就是在数据样本大到一定阶段后,会发现某种观察状态与隐藏属性会无限接近1:1的关系。而在牌局中,即便是基本牌的花色又是一个X因素,尤其是红桃杀的牌数(2张)小于红桃"桃"(7张),而南蛮入侵都是"黑桃"和"草花"。这使得观察序列与隐藏序列受到了一定干扰,或容易被人臆断。
  4. HMM的干扰因素。干扰因素一,在于HMM 3个矩阵模型的参数设定,这个倒是还能控制一下。如果是像于吉在牌局中的质疑,还会受到对手人数和血量的干扰,如果周泰把把质疑,必然会于吉第N+1张的声明胆量,这些都是HMM所不能控制。
  5. P/A/B的参数主观因素更高,对结果影响较大

·源码

#include <iostream>
#include <vector>
#include <map>
#include <iomanip>
#include <algorithm> using namespace std; vector<string> v_ob;
vector<string> v_hide_real;
map<string,int> m_ob;
map<string,int> m_p;
double P[2]={0.8,0.2}; //初始状态矩阵
double A[2][2]={{0.6,0.4},{0.7,0.3}}; //状态转移矩阵
double B[2][3]={{0.2,0.4,0.4},{0.5,0.2,0.3}}; //混淆矩阵 void Para_init(); //初始化观察队列
void Forward(); //算前向
void Viterbi(); int main()
{
Para_init();
Forward();
Viterbi(); } //vector 作为函数入参数 void show_vector(vector <int> &vecTest)
void Viterbi()
{
int LEN=v_ob.size();
int M=2;
double Q[LEN][M];
double Path[LEN][M];
for(int i=0;i<LEN;i++)
{
int act=m_ob[v_ob[i]]; //当天活动
cout<<"act:"<<act<<"\t";
for(int j=0;j<M;j++)
{
if(i==0)
{
Q[i][j]=P[j]*B[j][act];
Path[i][j]=-1;
}
else
{
double compare[2];
for(int z=0;z<M;z++)
{
compare[z]=Q[i-1][z]*A[z][j];
}
if(compare[0]<compare[1])
{ Path[i][j]=1;}
else
{ Path[i][j]=0;}
Q[i][j]=max(compare[0],compare[1])*B[j][act];
cout<<"com[0]"<<left<<setw(11)<<compare[0]<<" "<<"comp[1]"<<setw(11)<<compare[1]<<"\t";
}
cout<<"Q["<<i<<"]["<<j<<"]:"<<left<<setw(11)<<Q[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
cout<<"Last Max Prob:"<<max(Q[LEN-1][0],Q[LEN-1][0])<<endl;
cout<<endl; for(int i=0;i<LEN;i++)
{
for(int j=0;j<M;j++)
{cout<<"Path["<<i<<"]["<<j<<"]="<<Path[i][j]<<"\t";}
cout<<endl;
} } void Forward()
{
int LEN=v_ob.size();
int M=2;
double Q[LEN][M];
for(int i=0;i<LEN;i++)
{
int act=m_ob[v_ob[i]]; //当天活动
cout<<"act:"<<act<<"\t";
for(int j=0;j<M;j++)
{
//首行判断
if(i==0)
{
Q[i][j]=P[j]*B[j][act];
//cout<<"j="<<j<<"act="<<act<<endl;
}
else
{
double sum=0;
for(int z=0;z<M;z++)
{
// cout<<"tmp="<<Q[i-1][z]*A[z][j]<<" ";
sum+=Q[i-1][z]*A[z][j];
}
Q[i][j]=sum*B[j][act];
}
cout<<"Q["<<i<<"]["<<j<<"]:"<<left<<setw(11)<<Q[i][j]<<"\t";
}
cout<<endl;
} double sum=0;
for(int j=0;j<M;j++)
{
sum+=Q[LEN-1][j];
}
cout<<endl;
cout<<"Last Sum Prob="<<sum<<endl;
cout<<endl;
} void Para_init()
{
//add oberser_list
v_ob.push_back("kill");
v_ob.push_back("kill");
v_ob.push_back("tao");
v_ob.push_back("kill");
v_ob.push_back("man");
// dict
m_ob.insert(make_pair("kill",0));
m_ob.insert(make_pair("tao",1));
m_ob.insert(make_pair("man",2)); m_p.insert(make_pair("true",0));
m_p.insert(make_pair("false",1));
}

  

本人才疏学浅,各位麻友轻拍砖~~~ ^_^

用HMM(隐马)图解三国杀的于吉“质疑”的更多相关文章

  1. Atitit 马尔可夫过程(Markov process)&&num;160&semi;hmm隐马尔科夫。&&num;160&semi;马尔可夫链,的原理attilax总结

    Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫. 马尔可夫链,的原理attilax总结 1. 马尔可夫过程1 1.1. 马尔科夫的应用 生成一篇"看起来像文章的 ...

  2. HMM隐马尔可夫模型(词语粘合)

    HMM用于自然语言处理(NLP)中文分词,是用来描述一个含有隐含未知参数的马尔可夫过程,其目的是希望通过求解这些隐含的参数来进行实体识别,说简单些也就是起到词语粘合的作用. HMM隐马尔可夫模型包括: ...

  3. hmm隐马尔可夫真的那么难吗?

    hmm隐马尔可夫真的那么难吗? 首先上代码 这里是github上的关于hmm的:链接 概率计算问题:前向-后向算法 学习问题:Baum-Welch算法(状态未知) 预测问题:Viterbi算法 htt ...

  4. HMM隐马尔可夫模型来龙去脉(一)

    目录 隐马尔可夫模型HMM学习导航 一.认识贝叶斯网络 1.概念原理介绍 2.举例解析 二.马尔可夫模型 1.概念原理介绍 2.举例解析 三.隐马尔可夫模型 1.概念原理介绍 2.举例解析 四.隐马尔 ...

  5. HMM隐马尔可夫模型来龙去脉(二)

    目录 前言 预备知识 一.估计问题 1.问题推导 2.前向算法/后向算法 二.序列问题 1.问题推导 2.维特比算法 三.参数估计问题 1.问题推导 2.期望最大化算法(前向后向算法) 总结 前言 H ...

  6. 机器学习-HMM隐马尔可夫模型-笔记

    HMM定义 1)隐马尔科夫模型 (HMM, Hidden Markov Model) 可用标注问题,在语音识别. NLP .生物信息.模式识别等领域被实践证明是有效的算法. 2)HMM 是关于时序的概 ...

  7. HMM隐马尔科夫模型

    这是一个非常重要的模型,凡是学统计学.机器学习.数据挖掘的人都应该彻底搞懂. python包: hmmlearn 0.2.0 https://github.com/hmmlearn/hmmlearn ...

  8. HMM隐马尔科夫算法&lpar;Hidden Markov Algorithm&rpar;初探

    1. HMM背景 0x1:概率模型 - 用概率分布的方式抽象事物的规律 机器学习最重要的任务,是根据一些已观察到的证据(例如训练样本)来对感兴趣的未知变量(例如类别标记)进行估计和推测. 概率模型(p ...

  9. 自然语言处理&lpar;1&rpar;-HMM隐马尔科夫模型基础概念(一)

    隐马尔科夫模型HMM 序言 文本序列标注是自然语言处理中非常重要的一环,我先接触到的是CRF(条件随机场模型)用于解决相关问题,因此希望能够对CRF有一个全面的理解,但是由于在学习过程中发现一个算法像 ...

随机推荐

  1. CocoaPods的那些坑

    CocoaPods的那些坑 文章转自http://blog.csdn.net/zhanniuniu/article/details/52159362#comments 我跟博主的经历超级像!不过自己用 ...

  2. 【CodeVS1080】线段树练习

    Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或者减去一个 ...

  3. 【翻译二十二】java-并发之集合与原子变量

    Concurrent Collections The java.util.concurrent package includes a number of additions to the Java C ...

  4. Oracle DataGuard搭建(一)

    第一次搭建oracle dataguard.学oracle很长时间,却没有完整的搭过dg,说起来让人笑.总得有第一次,而且第一次总是很痛苦的. 数据库版本: Oracle Database 11g E ...

  5. angular编写表单验证

    angular编写表单验证 一.整体概述 表单内容如下图,包括常用的用户名.密码.确认密码.手机.邮箱等 整体js代码很少,就一个指令用于写确认密码和密码是否相等.其他 验证都是使用angular自带 ...

  6. SpringBoot&plus;mybatis使用&commat;Transactional无效

    项目中新增过程中如果出现异常需要回滚, 在service实现方法中使用@Transactional注解失效 解决: 1, 在controller中使用try{}catch捕捉异常 2, 在servic ...

  7. Linux 小知识翻译 - 「服务器」

    这次聊聊 「服务器」 这个词. 可能会觉得为什么「突然问这个?」.接下来请先考虑一下下面的题目. A) 「Web服务器是指提供网页数据的软件」 B) 「Web服务器是指运行上述软件的硬件」 那么,究竟 ...

  8. ES6学习笔记五(promise异步)

    知识点1:rosolve是执行下一步then() // Promise { let ajax=function(){ console.log('执行2'); return new Promise(fu ...

  9. 封装、property特性及绑定与非绑定方法

    1.封装 (1)什么是封装? 封:属性对外是隐藏的,但对内是开放的: 装:申请一个名称空间,往里面装入一系列名字/属性 (2)为什么要封装? 封装数据属性的目的 首先定义属性的目的就是为了给类外部的使 ...

  10. win32多线程-新版本MtVerify&period;h

    api调用错误诊断宏,对GetLastError()函数的封装,并解析错误 从网上找的版本并进行了部分修改 /* * MtVerify.h * * The function PrintError() ...