如何使用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()