# 先定义weibull函数
def weibullfun(x, alpha, beta, gamma, g):
k = (-np.log((1-g)/(1-gamma)))**(1/beta)
y = 1 - (1 - gamma)*np.exp(-(k*x/alpha) ** beta) # hack here to avoid the complex number of
return y
from scipy.stats import bernoulli
# coherence level in literature
coh = np.array([0.032, 0.064, 0.128, 0.256, 0.512])
# 定义参数
g = 0.82
gamma = 0.5 # Baseline chance level
beta = 3. # slop steepness
alpha = 0.25 # coherence threshold corresponding to g
nTrialPerCoh = 1000 # how many trials per coh level
pCoh = weibullfun(coh, alpha, beta, gamma, g)
plt.plot(coh, pCoh, 'o-')
plt.xlabel('coherence')
plt.ylabel('Prob of correct')
data = np.empty((coh.size, nTrialPerCoh))
for iCoh in range(coh.size): # loop coherence level
# use bernouli process to generate data
data[iCoh, :] = bernoulli.rvs(pCoh[iCoh], size=nTrialPerCoh)
cohTrial = np.tile(coh[:, np.newaxis], (1, nTrialPerCoh)).flatten() #(5000, ) array
data = data.flatten() # (5000, ) array
eps = np.finfo(float).eps #大于0的极小值,防止后续计算对数时出现0的情况
def loglikeli(alpha, coh, data):
gamma = 0.5
g = 0.82
beta = 3.
prob = np.empty(coh.size)
for i in range(coh.size):
p = weibullfun(coh[i], alpha, beta, gamma, g)
prob[i] = p*data[i]+(1-p)*(1-data[i])
prob = prob*0.999+eps # 避免prob里面有0的情况, log(0)=-infinity
return -np.log(prob).sum()
#prob取值在(0,1],经过对数函数后会变为负数,取负的对数似然值能保证返回值是一个正数