【问题标题】:How to convert log probability into simple probability between 0 and 1 values using python如何使用python将对数概率转换为0到1值之间的简单概率
【发布时间】:2020-05-17 05:41:43
【问题描述】:

我正在使用高斯混合模型进行说话人识别。我使用此代码来预测每个语音片段的说话者。

for path in file_paths:   
    path = path.strip()   
    print (path)
    sr,audio = read(source + path)
    vector   = extract_features(audio,sr)
    #print(vector)
    log_likelihood = np.zeros(len(models))
    #print(len(log_likelihood))

    for i in range(len(models)):
        gmm1   = models[i]  #checking with each model one by one
        #print(gmm1)
        scores = np.array(gmm1.score(vector)) 
        #print(scores)
        #print(len(scores))
        log_likelihood[i] = scores.sum()
        print(log_likelihood)
        winner = np.argmax(log_likelihood)
        #print(winner)
    print ("\tdetected as - ", speakers[winner])

它给了我这样的输出:

[ 311.79769716    0.            0.            0.            0.        ]
[  311.79769716 -5692.56559902     0.             0.             0.        ]
[  311.79769716 -5692.56559902 -6170.21460788     0.             0.        ]
[  311.79769716 -5692.56559902 -6170.21460788 -6736.73192695     0.        ]
[  311.79769716 -5692.56559902 -6170.21460788 -6736.73192695 -6753.00196447]
    detected as -  bart

这里的得分函数给了我每个说话者的对数概率。现在我想确定阈值,因为我需要将这些对数概率值转换为简单的概率值(在 0 到 1 之间)。我怎样才能做到这一点?我正在使用python软件。

【问题讨论】:

  • 虽然我想不出一个很好的理由,你需要将日志概率转换回来。一般来说,对数概率更容易处理。

标签: python gaussian logarithm gmm probability-distribution


【解决方案1】:

您必须获取 log 概率exponent (np.exp()) 才能获得实际概率。这是因为logarithm is the inverse of exponentiation: elog(p) = p,其中p 是概率。

下面是一个例子:

# some input array
In [9]: a
Out[9]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

# converting to probabilities using "softmax"
In [10]: probs = np.exp(a) / (np.exp(a)).sum()

# sanity check
In [11]: probs.sum()
Out[11]: 1.0

# obtaining log probabilities
In [12]: log_probs = np.log(probs)

In [13]: log_probs
Out[13]: 
array([-8.45855173, -7.45855173, -6.45855173, -5.45855173, -4.45855173,
       -3.45855173, -2.45855173, -1.45855173, -0.45855173])

# In most cases, it won't sum to 1.0
In [14]: log_probs.sum()
Out[14]: -40.126965551706405

# get the probabilities back
In [15]: probabilities = np.exp(log_probs)

In [16]: probabilities.sum()   # check passed
Out[16]: 1.0

In [17]: probabilities
Out[17]: 
array([  2.12078996e-04,   5.76490482e-04,   1.56706360e-03,
         4.25972051e-03,   1.15791209e-02,   3.14753138e-02,
         8.55587737e-02,   2.32572860e-01,   6.32198578e-01])

【讨论】:

  • 我也尝试过使用 np.exp() 函数,但它并没有给我准确的结果。它为我提供了具有科学价值(包括大于 1)的输出数组。这怎么可能?因为概率永远不会大于 1。
  • @Sandeep 在不知道数组内容的情况下,重现您的设置很棘手。
  • 我在我的问题中提到了我的数组内容(输出)。我在我的问题中提到了我的 5*5 数组输出。请查看该输出并建议我如何在 0 和 1 之间转换这些数组值。我想确定阈值,这就是为什么我需要 0 和 1 之间的值。
  • 效果很好! @Sandeep,您必须错误地读取输出。 Numpy 以科学计数法打印。也许尝试np.exp().tolist() 用于 python 列表
【解决方案2】:

来自 sklearn 的 GMM 模块的 score_sample 给出了概率密度,它们的总和不会为 0,而是积分为 1。

data = 10 * np.random.rand(100)
model = mixture.GMM(n_components=1).fit(data[:, None])
xfit = np.linspace(-5, 15, 5000)
logprob, _ = model.score_samples(xfit[:, None])
dx = xfit[1] - xfit[0]
print(dx * np.sum(np.exp(logprob)))
# 0.999773872653

You can also calculate the probability of a data point belonging to a multivariate normal distribution.,

来源:https://github.com/scikit-learn/scikit-learn/issues/4202

【讨论】:

    猜你喜欢
    • 2016-03-12
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    相关资源
    最近更新 更多