gpt4 book ai didi

python - 估计转移概率( Pandas )

转载 作者:太空宇宙 更新时间:2023-11-03 14:15:52 25 4
gpt4 key购买 nike

我有 3 种事件类型的数据,我想估计转移概率 Pij(1)。这些表示事件 i 之后发生事件 j 的概率,假设事件 i 发生了(所以我需要条件概率)。我还想知道 Pij(2) 和 Pij(3),它们是事件 i 之后的第二个(第三个)事件是事件 j 的条件概率。

看看一些模型数据:

import pandas as pd
import numpy as np
np.random.seed(5)
strings=list('ABC')
events=[strings[i] for i in np.random.randint(0,3,20)]
groups=[1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2]
index=pd.date_range('2/2/2012',periods=20,freq='T')
dfm=pd.DataFrame(data={'event':events,'group':groups},index=index)
dfm.head()

event group
2012-02-02 00:00:00 C 1
2012-02-02 00:01:00 B 1
2012-02-02 00:02:00 C 1
2012-02-02 00:03:00 C 1
2012-02-02 00:04:00 A 1

到目前为止,我一直遵循一种非常不优雅和幼稚的策略,并使用 shift 来查看在接下来的时间段内发生了哪些事件:

#Create new columns containing the shifted values
for i in range(1,4):
dfm['event_t%i'%i]=dfm.event.groupby(dfm.group).shift(-i)
#Combine the columns with current and shifted values into one
for i in range(1,4):
dfm['NEWevent_t%i'%i]=dfm['event']+' '+dfm['event_t%i'%i]
dfm = dfm.drop('event_t%i'%i, 1)

#Count the number of times each combination occurs
A=dfm['NEWevent_t1'].groupby(dfm.group).value_counts()
B=dfm['NEWevent_t2'].groupby(dfm.group).value_counts()
C=dfm['NEWevent_t3'].groupby(dfm.group).value_counts()

merged=pd.concat([A, B, C], axis=1)

这确实给出了每个组发生特定事件组合(例如 AA、AB 等)的次数。继续这样做,我可以使用组变量和双字母对中的第一个字母作为分组变量来进行分组。这个蛮力解决方案可能看起来像:

merged=merged.reset_index()
merged['first']=merged['level_1'].apply(lambda x: x[0])
merged.columns=['group','i j','t1','t2','t3','first']
merged.groupby(['group','first'])['t1','t2','t3'].sum()
sums=merged.groupby(['group','first'])['t1','t2','t3'].sum()
merged=pd.merge(merged,sums,left_on=['group','first'],right_index=True)
merged['Pij(1)']=merged.t1_x/merged.t1_y
merged['Pij(2)']=merged.t2_x/merged.t2_y
merged['Pij(3)']=merged.t3_x/merged.t3_y
merged[['group','i j','Pij(1)','Pij(2)','Pij(3)']]
merged.head()

group i j Pij(1) Pij(2) Pij(3)
0 1 A A 0.25 0.666667 0.666667
1 1 A B 0.25 NaN NaN
2 1 A C 0.50 0.333333 0.333333
3 1 B A 0.50 0.500000 0.500000
4 1 B C 0.50 0.500000 0.500000

我相信一定有更简单的方法来实现这一点?关于如何提高效率的任何建议?

注意:我的实际数据集包含 500 万行、10 种事件类型和 100 个组。

最佳答案

表示转移概率的最佳方式是在转移矩阵中,其中 T(i,j) 是 Ti 转到 Tj 的概率。让我们从您的数据开始:

import pandas as pd
import numpy as np

np.random.seed(5)
strings=list('ABC')
events=[strings[i] for i in np.random.randint(0,3,20)]
groups=[1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2]
index=pd.date_range('2/2/2012',periods=20,freq='T')
dfm=pd.DataFrame(data={'event':events,'group':groups},index=index)
for i in range(1,4):
dfm['event_t%i'%i]=dfm.event.groupby(dfm.group).shift(-i)

我认为您的 shift 命令没问题,但我就是这样。无论如何,从这里您限制为 'group' == 1 并填充转换矩阵。最后,您除以列以获得转移概率。

trans = pd.DataFrame(columns=strings, index=strings)
g_dfm = dfm[dfm['group']==1]

for s1 in strings:
for s2 in strings:
events = g_dfm[(g_dfm['event']==s1) & (g_dfm['event_t1']==s2)]
trans.ix[s1, s2] = len(events)

trans = trans.astype(float).div(trans.sum(axis=1), axis=0)
trans = trans.fillna(0)

从那里,您可以制作热图:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(3,3))
ax.pcolormesh(trans.values, cmap=plt.get_cmap('Blues'), vmin=0, vmax=1)
ax.invert_yaxis()
ax.set_yticks(np.arange(0, len(trans.index))+0.5)
ax.set_xticks(np.arange(0, len(trans.columns))+0.5)
ax.set_yticklabels(trans.index, fontsize=16, color='k')
ax.set_xticklabels(trans.columns, fontsize=16, color='k')
ax.tick_params(direction='out', pad=10)
ax.set_frame_on(True)

for tk1, tk2 in zip(ax.xaxis.get_major_ticks(), ax.yaxis.get_major_ticks()):
tk1.tick1On, tk2.tick1On, tk1.tick2On, tk2.tick2On = [False]*4

plt.show()

enter image description here

冲洗并重复所有组以及第二和第三次转换。

关于python - 估计转移概率( Pandas ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33153577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com