从数据中推断用户的行为--建模篇

1.数据

    我们获得了用户2个多月每天接收到的短信数量,并用代码展示如下:

    

from IPython.core.pylabtools import figsize
import numpy as np
from matplotlib import pyplot as plt
count_data = np.loadtxt("data.cvs")
count_data_len = len(count_data)
print(count_data)
"""
out: [12. 22. 22. 34. 12. 11. 12. 11. 21. 21. 11. 56. 19. 29.  6. 19. 11. 21.
 11. 18. 72. 32.  9.  7. 12. 19. 23. 27. 20.  6. 13. 10. 13.  5. 16. 15.
  5.  2. 15. 15. 19. 70. 49.  6. 53. 22. 21. 32. 19. 11. 18. 20. 12. 35.
 16. 23. 15.  3.  2. 31. 30. 13. 27.  0. 39. 37.  5. 13. 12. 22.]
"""
figsize(12.5, 3.5)
colors = ['#348ABD','#A60628']
plt.bar(np.arange(count_data_len), count_data,color = colors[0])
plt.xlabel('time(day)')
plt.ylabel('sms(piece)')
plt.xlim(0, count_data_len)
plt.show()

从数据中推断用户的行为--建模篇

       问题:用户的行为是否发生过变化?显然光从图片中我们可以略微的看出,后面一段的数量总体是比前面多的。

2.两个分布模型

从数据中推断用户的行为--建模篇

            上面就是泊松分布的公式,P表示概率,N表示某种函数关系,t表示时间,n表示数量,lambda表示事件的频率(数学期望)。

   

从数据中推断用户的行为--建模篇

           上面是指数分布的概率密度函数,指数分布是事件时间间隔的概率,x是给定时间间隔,lambda是单位时间发生的次数。

3.分析建模

3.1 用户每天天收到的短信数是多少?

    显然使用具体的函数来确定用户每天收到的短信数是不可取的,用户每天收到的短信数是一个随机的过程,而具体函数给定参数后只有唯一的结果输出。

在随机过程中,泊松分布描述的是某段事件内,事件具体发生的概率,并且在泊松分布中仅有一个参数lambda,而lambda则是整个事件的数学期望。于是我们想到,既然无法得到用户每天收到短信的具体值,为何可以借助Poisson分布来模拟用户每天收到短信数量的概率分布呢。  

               得到公式:     P(C)  = P(N(1)=C) , 那么C ~  Poisson(lambda) ,  C为一天收到的短信数量, lambda为短信的平均数。

avg = sum(count_data) / count_data_len  # 收到短信的平均数
print(count_data)
lambda_ = avg
"""
out: 19.4
"""
print(lambda_)
x = np.arange(100)
pmf =st.poisson.pmf(x, lambda_)   # poisson分布函数
plt.plot(x, pmf, '-o', label='$\lambda$ ={}'.format(lambda_)) # x轴为收到短信的条数,y轴为概率
plt.xlabel('received(piece)', fontsize=12)
plt.ylabel('Density', fontsize=12)
plt.ylim(0)
plt.show()

从数据中推断用户的行为--建模篇

     或许对于真实数据的短信数量频率分布应该用  短信数量出现的天数 / 总天数  来表示更为准确,但是我们知道真实数据中并不能代表所有数据,1天收到1000条的概率很小,但还是可能的。

3.2 对两个lambda的假设

     在3.1中我们得出公式  C ~ Poisson(lambda)只是说明每天收到的短信数量服从泊松分布,并不能让我们观察出用户行为是否发生变化。但是若存在两个lambda呢?

     我们假定用户每天收到短信数量的频率分布在tau天前服从lambda_1, 在tau天后服从lambda_2的Poisson分布:

              C(t) ~ Poisson(lambda_1)      t < tau

                     ~ Poisson(lambda_2)      t >= tau

      也就是说用户在以第tau天为分割线,前段时间与后段时间收到的短信数量在数学期望上有两个不同的值,即用户在第tau天后短信更多了或者更少了,那么我们就可以说在第tau天用户的短信行为发生了变化。

3.3怎么求这两个lambda

    假如只有一个lambda,我们可以给定lambda为总体数据的平均值,但是对于两个lambda依旧采取这样的方法,把数据分成两份,再求其数学期望?显然这两个期望不会相等,或许我们再定义一个最小差值作为用户行为发生变化的准则结果也能  ,不多说,试一试,直接上代码:。


from IPython.core.pylabtools import figsize
import numpy as np
from matplotlib import pyplot as plt
figsize(13,5)
count_data = np.loadtxt("data.cvs")
count_data_len = len(count_data)
avg = sum(count_data) / count_data_len
i = 1
expectation = np.zeros_like(count_data)
for expe in expectation:
    other_len = count_data_len - i
    expe_1 = sum(count_data[:i]) / i
    expe_2 = sum(count_data[i:]) / other_len
    expe =  abs(expe_1 -expe_2) 
print(expectation)

plt.bar(np.arange(len(expectation)), expectation)
plt.ylabel('expectation difference between before and after', fontsize=12)
plt.xlabel('user change behavior time(day)', fontsize=12)
plt.ylim(0)
plt.xlim(1)
plt.show()


            从数据中推断用户的行为--建模篇

     如上图,假设用期望值差来判定的话,在最初和最后容易出现较大的差值,可能是偶然,可能行为确实发生了变化,我们是无法辨别的。

3.4 贝叶斯的lambda

     在贝叶斯的推断下,虽然不知道lambda的具体值,但可以给不同的lambda分配一个先验概率,我们知道指数分布对于任意正整数都存在一个连续的密度函数,这也许是用来模拟lambda取值很好的选择。同样在指数分布中,依旧存在一个参数,我们命名为alpha。

      即:    lambda_1 ~ Exp(alpha),      lambda_2 ~ Exp(alpha).   虽然表达式相同,但在随机过程中lambda_1,lambda_2是不一样的。

      对于alpha取什么值好呢?我们先看看alpha对数据的影响!

      首先,E(lambda) = 1/alpha,即lambda_1,lambda_2的期望值都是是alpha的倒数,那么我们对lambda_1,lambda_2进行n组次采样:

                  sum(lambda_1...) /n  和sum(lambda_2...) /n 会随着n增大而无限逼近alpha的倒数。(因为数学符合不好表示,我使用sum(x...) 表示采样数据x的总和。)

       同样的,对于C(t) ~ Poisson(lambda_1)      t < tau

                                       ~ Poisson(lambda_2)      t >= tau           

       我们用采样出的1组lambda_1,lambda_2,分别对C进行n次采样,得到n个C1, n个C2:

                 sum(C1...) / n 约等于 lambda1 ,  sum(C2...) /n 约等于lambda_2, 简写成 sum(Ci...) / n 约等于 lambda_i

       扩展到n组lambda_1,lambda_2:

                 令 CEi =  sum(Ci...) / n  ->       sum(CEi...) 约等于 sum(lambda_i...)

                 那么所有的采样数据的总和,    sum(CE1...)  + sum(CE2...) , 其中C的总量为2n个。

                 那么C的期望值就是 :  

                      E(C) = ( sum(CE1...) + sum(CE2...)  )  / 2n =  ( sum(CE1...) /n + sum(CE2...) /n   )  / 2~ = (sum(lambda_1...) + sum(lambda_2...))/2~= 1/alpha

       那么可以知道,alpha将决定我们对用户每天收到短信数量模拟采样的数学期望,可想而知,1/alpha 等于真实数据的期望能减少参数对模型的影响。

 3.5整理一下现有的模型

      C(t) ~ Poisson(lambda_1)      t < tau

             ~ Poisson(lambda_2)      t >= tau      

     其中  lambda_1 ~ Exp(alpha), lambda_2~Exp(1/alpha),     alpha = E(data).

     我们似乎忘了tau这个参数,不过在我们对用户一无所知时,这个参数应该是在时间段内都是均等分布的,也就是说用户在任何一天都是等可能改变行为的。

     那么     tau ~ DiscreteUniform(1, 70), 如果用户一共是70天。

     现在我们的模型已经确定了,很显然,这是一个动态模型,但是我们给定任意的lambda_1, lambda_2, tau. 我们都可以采样出一组模拟的用户数据C.                     




         

上一篇:运行时和编译时元编程—运行时元编程(二)


下一篇:Cisco网络设备命名规则