【发布时间】:2014-08-27 08:57:49
【问题描述】:
我正在编写这样一个脚本:程序分析一堆特定语言的文本文档,绘制每个 k 的概率分布,其中 k 是出现在字母表中每个给定字母之后的第一个字符在文本的每个单词中。然后程序利用这些知识尝试使用马尔可夫链写出“真实”的单词。
我已经写了大部分脚本,而且它已经吐出了有趣的单词,关键是生成单词的函数正在使用 try 和 except 机制来避免卡住。它卡住了,因为某些概率分布不会加到 1(我猜是因为浮点类型不是那么精确或类似的东西)并且应该与这些分布一起使用的 numpy 函数会引发 ValueError 因为概率加起来不等于 1 .
通过触发某些分布的异常,根本不会生成某些单词,最终结果不如它可能的有趣。
现在,我的问题是:有没有办法让这些概率分布在生成时加起来等于 1? 我试过 gmpy2,round() 函数,但似乎没有人工作。也许这是一个愚蠢的问题,我只需要呼吸新鲜空气......无论如何,一些帮助会很有用!
这是生成概率分布的代码
def FreqRel(self,listValues):
absFreq = self.AbsFreq(listValues)
freqRel = []
for i in absFreq:
freqRel.append(i/sum(absFreq))
if sum(freqRel) != 1:
print("Frequencies do not add up to 1")
if sum(freqRel) - 1 < 0:
diff = sum(freqRel) - 1
#This should be an adjustment which should not interfere
#that much on the probability distribution
freqRel[1] = freqRel[1] - diff
print("missing",diff)
elif sum(freqRel) - 1 > 0:
diff = sum(freqRel) - 1
#This should be an adjustment which should not interfere
#that much on the probability distribution
freqRel[1] = freqRel[1] - diff
print("Too much",diff)
return freqRel
这是我在运行此函数时在控制台上打印的内容:
这是当总和不是 1 时崩溃的代码。numpy 行是崩溃的那些。 错误是:ValueError: probabilities do not add up to 1.
def spitText(n):
i = 0
while i < n:
try:
word = ""
#This oldChar setting is arbitrary, later I'm going to fix it
oldChar = "b"
for k in range(np.random.choice(distributions[0],replace=True,p=distributions[1])):
newChar = np.random.choice(alphabet,replace=True,p=distRel[alphabet.index(oldChar)])
word = word + newChar
oldChar = newChar
print(word)
time.sleep(0.2)
i+=1
except:
pass
【问题讨论】:
-
你的
freqAss是什么?它起源于哪里? -
对不起,应该是 absFreq 而不是 freqAss。那是一个错字。刚刚编辑,谢谢!
-
你能告诉我们总和不为1时崩溃的代码吗?
-
预计 1e-17 量级的舍入误差是完全合理且不可避免的,除非您的所有概率恰好是精确的二进制分数。这就是花车的工作原理。您无法通过消除舍入误差来解决此问题;您只能通过更改代码以某种合理的方式处理该舍入错误来解决它。由于您没有向我们展示相关代码,我们无法向您展示如何更改它。
-
当我运行
np.random.choice时,只有当概率总和偏离-5 个相对数量级时,我才会得到该错误。对1+3e-17的总和感到非常满意;只有当您高于1+1e-5时,它才会抱怨。所以,我很确定这不是你的真实数据,而且你在某个地方有一个实际的错误,而不仅仅是一个舍入错误。
标签: python python-3.x numpy distribution probability