如何使用python将日志概率转换为0和1之间的简单概率值

如何使用python将日志概率转换为0和1之间的简单概率值,python,gaussian,logarithm,gmm,probability-distribution,Python,Gaussian,Logarithm,Gmm,Probability Distribution,我使用高斯混合模型进行说话人识别。我使用此代码预测每个语音片段的说话人 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))

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

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软件。

您必须获取日志概率的指数()才能获取实际概率。这是因为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])

来自sklearn的GMM模块的score_样本给出了概率密度,它们的总和不会为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
,


来源:

尽管我想不出一个好的理由,你需要将日志概率转换回来。一般来说,日志概率更容易处理。我也尝试过使用np.exp()函数,但它没有给出准确的结果。它为我提供了具有科学值(包括大于1)的输出数组。怎么可能呢?因为概率永远不会大于1。@Sandeep在不知道数组内容的情况下,很难重现您的设置。我在问题中提到了我的数组内容(输出)。我在问题中提到了我的5*5数组输出。请查看该输出并建议我如何在0和1之间转换这些数组值。我想确定阈值,这就是为什么我需要介于0和1之间的值。效果很好@Sandeep您读取的输出肯定不正确。Numpy以科学记数法印刷。对于python列表,可以尝试
np.exp().tolist()