马尔科夫模型在Gowalla数据集下的简单实践

马尔科夫模型实践第一战

这是笔者对马尔科夫模型理解的第一步,针对Gowalla模型展开第一次实战,题目是预测ID号为0的用户接下来下一步将会去哪个地点,这仅涉及一些简单的概统知识。

基础知识

题目固然简单,但是因为笔者数学基础不够牢固,所以还是从最简单的概统知识进行介绍。

数学知识

简单的概率计算

概率,亦称“或然率”,它是反映随机事件出现的可能性(likelihood)大小。随机事件是指在相同条件下,可能出现也可能不出现的事件。例如,从一批有正品和次品的商品中,随意抽取一件,“抽得的是正品”就是一个随机事件。设对某一随机现象进行了n次试验与观察,其中A事件出现了m次,即其出现的频率为m/n。经过大量反复试验,常有m/n越来越接近于某个确定的常数(此论断证明详见伯努利大数定律)。该常数即为事件A出现的概率,常用P (A) 表示。

P ( A ) = m n   (1) P(A) = \frac{m}{n}\ \tag{1} P(A)=nm (1)
简单的矩阵知识

矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中。 [2] 在物理学中,矩阵于电路学、力学、光学和量子物理中都有应用;计算机科学中,三维动画制作也需要用到矩阵。 矩阵的运算是数值分析领域的重要问题。将矩阵分解为简单矩阵的组合可以在理论和实际应用上简化矩阵的运算。对一些应用广泛而形式特殊的矩阵,例如稀疏矩阵和准对角矩阵,有特定的快速运算算法。

二维矩阵,形如
1 2 3 4 5 6 7 8 9 (2) \begin{matrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{matrix} \tag{2} 147258369(2)

代码知识

本实现使用的是python语言,数据处理使用的是pandas库函数和numpy库函数。

数据处理

开始时从秋丽师姐那里得到的Gowalla数据集只有单纯的数据和一个单独的txt文档介绍每一行表示什么内容,数据集内容如下:
内容介绍
在这里插入图片描述
作为初学者一开始并没有想到使用pandas如此简单的库函数进行数据处理,于是使用了如下的笨办法

filename = 'Gowalla_NY.txt'
filename_0 = 'Gowalla_0.txt'

with open(filename) as file_object:
    lines = file_object.readlines()
    for line in lines:
       if line[0] == '0':
           with open(filename_0,'a') as file_object_0:
               file_object_0.write(line)

很直白的读取数据集,并在之前先将ID为0的用户所有的地点ID数据全部单独保存在一个TXT文件中,处理起来十分麻烦,代码很冗长,而且很难达到预期效果,在师姐的推荐下使用了pandas来处理数据,并学习了一些pandas的用法,比如:

读取文件:
papa = pd.DataFrame(pd.read_csv('Gowalla_0.txt',sep = '\t'))
这里的 Gowalla_0.txt 是我预先处理过,将ID号为0的用户数据单独逐行保存后得到的细分后的数据,如下:
在这里插入图片描述
不添加表头会使得数据很难辨认,为了方便笔者单独剥去一列数据使用,笔者决定给它添加表头:
papa.columns=['ID','time','long','lab','geoID','sH','sW','sWH','rain','temp','wind']

表头完全按照:

1用户ID
2时间
3-4经纬度
5地点ID
6签到的小时
7签到星期
8签到周小时
9-11分别为 降雨 温度 风速

但是在这里出现了一些问题,如此加入表头之后,表头会覆盖第一行的数据,笔者无奈只能复制第一行数据再做一遍表头,各位读者如果有好的方式敬请留言,笔者必定躬身请教!

两条重复数据,其实第一条被处理为表头了。。hhhh

在这里插入图片描述
最后建立空列表,并将所需的列数据保存进去,注意,仔细观察可知数据集中所给的数据均按照时间顺序排列,所以不需要再进行处理:

Geo_ID = []
Geo_ID = list(papa['geoID'])

单独一次转移的概率计算函数设计

这里笔者单独写了一个函数封装:

import numpy as np
def Prob(a,x_axis,y_axis):
    b = a
    d = 0.0
    m = 0.0
    for i in range(len(a)):
        if a[i] is x_axis:
            prob = 1
            d = d + 1
        if a[i] is x_axis and a[i + 1] is y_axis:
            m = m + 1
    prob = m / d
    return prob

其中参数包括一个数组,横坐标x_axis,纵坐标y_axis
算法思想:
如果一个地点出现了一次,那么先令其转移概率prob为1,且分母d加1,表示以该地点为起点的转移共发生d次。若该数组里存在着另一个起点相同,下一跳地点也相同的地点,那么分子m加1,最后prob = m / d返回prob。
注意这里要考虑分母不为零的情况和数据类型为浮点型,若数据类型为默认整型的话,概率计算所得的小数点部分会被直接舍弃,也就是计算得到的数值均为0.

笔者在这里因为学艺不精遇到一些问题,在此列出以后规避
1.python中for循环的用法,当不使用range(len())的时候,i表示一个实例,当使用range(len())的时候,i表示一个计数。
2.if 语句中,== 和 is 有区别,不能混用:

Python中的对象包含三要素:id、type、value。
其中id用来唯一标示一个对象,type标识对象的类型,value是对象的值。
is判断的是a对象是否就是b对象,是通过id来判断的。
==判断的是a对象的值是否和b对象的值相等,是通过value来判断的。

生成转移概率矩阵

首先,我们要理解转移矩阵的构造,在本例题中,转移函数是依照地点ID也就是Geo_ID来生成的,但是重点问题在于,Geo_ID中存在重复的地点数据,所以笔者先使用set()函数来去重Geo_ID_M = list(set(Geo_ID)),得到的列表作为转移矩阵的行列表头数据,大概举例说明:

\地点1地点2地点3
地点1地点1转移到地点1的概率地点1转移到地点2的概率地点1转移到地点3的概率
地点2地点2转移到地点1的概率地点2转移到地点2的概率地点2转移到地点3的概率
地点3地点3转移到地点1的概率地点3转移到地点2的概率地点3转移到地点3的概率

先建造空的矩阵:
Geo_ID_P = [ [0] * num_P for i in range(num_P)]
其中num_P是地址信息的个数,如此获取:num_P = len(Geo_ID_M)

然后使用Prob(a,x_axis,y_axis)逐个计算概率并填充进矩阵:

for i in range(len(Geo_ID_M)):
    for j in range(len(Geo_ID_M)):
        Geo_ID_P[i][j] = Prob(Geo_ID,Geo_ID_M[i],Geo_ID_M[j])

如此一来便得到了转移矩阵

一点小瑕疵,Geo_ID_M是经过set()函数处理过的,虽然降重,但是乱序了,不过这并不影响计算。

生成初始向量

为什么需要初始向量呢?因为在预测转移的时候,需要初始向量来表示当前地点是列表中的哪一个,所以先将去重了的地点信息列表进行one-hot-encoding处理:

pi_0 = [0]*len(Geo_ID_M)
for i in range(len(Geo_ID_M)):
    if Geo_ID_M[i] == now_loc:
        pi_0[i] = 1

其中now_loc表示当前地点信息,笔者以数据集中最后一个数据作为当前地点,得到一串独热码:
在这里插入图片描述
根据马尔科夫模型的算法:

{ π ( 1 ) = π ( 0 ) P . . . . . . . . . π ( n ) = π ( n − 1 ) P n (3) \begin{cases} \pi(1) & =\pi(0)P \\ .........\\ \pi(n) & =\pi(n-1)P^n \end{cases}\tag{3} π(1).........π(n)=π(0)P=π(n1)Pn(3)

笔者这里只计算转移第一次的概率:

pi_1 = np.dot(pi_0,Geo_ID_P)

loc_0 = 0
for i in range(len(pi_1)):
    if pi_1[i] == 1:
        loc_0 = i

所以loc_0就是下一跳的地点ID。

结论

这是笔者第一次发表文章,切实感受到了自己的写作能力的提高,同时顺利的帮助自己重新理清了一遍思路,希望对初学者有所帮助,也希望前辈们及时提出文章中的纰漏和错误,以及理解上的差错,笔者定将及时改正,感谢苏老师,秋丽学姐,宁宁学姐提供的帮助。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
马尔科模型在系统状态预测中有广泛的应用,以下是一些常见的应用领域: 1. 自然语言处理:马尔科模型被广泛应用于文本生成、语言模型和机器翻译等任务中。通过建立状态为单词或词组的马尔科模型,可以预测下一个可能的单词或词组,从而实现文本的自动生成和翻译。 2. 金融市场分析:马尔科模型可以用于预测金融市场的状态,如股票价格、汇率变动等。通过建立状态为不同的市场状态(如上涨、下跌、震荡等),可以预测未来市场的走势,辅助投资决策。 3. 健康监测:马尔科模型可以应用于健康监测领域,如心电图分析、疾病预测等。通过建立状态为不同的健康状态,可以根据观测到的生理信号(如心电图数据)来预测个体当前的健康状态和未来可能的疾病发展趋势。 4. 预测天气模式:马尔科模型可以应用于天气预测领域。通过建立状态为不同的天气模式(如晴天、阴天、雨天等),可以根据历史观测数据(如气温、湿度、风速等)来预测未来的天气情况。 5. 机器人路径规划:马尔科模型可以用于机器人路径规划中的状态推测。通过建立状态为机器人可能所处的位置,可以根据传感器观测数据来预测机器人当前的位置和未来可能的移动轨迹,从而实现智能路径规划。 这些仅是马尔科模型在系统状态预测中的一些应用示例,实际上,马尔科模型具有广泛的适用性,可以应用于各种领域的状态预测问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值