def etape_EM_PRM_SB(liste_obs): """Permet d'estimer les paramètres dans le cadre du modèle sans banque de graines. Attention : ne permet pas de traiter le cas des données manquantes.""" nbr_obs = len(liste_obs) nbr_1 = 0 nbr_t_0 = 0 nbr_t_1 = 0 nbr_t_10 = 0 nbr_t_01 = 0 for obs in liste_obs : nbr_1 += obs[0] for i in range(1, len(obs)): nbr_t_1 += obs[i-1] nbr_t_0 += 1 - obs[i-1] nbr_t_01 += (1-obs[i-1])*obs[i] nbr_t_10 += obs[i-1]*(1-obs[i]) pi = nbr_1*1.0/nbr_obs try : c = nbr_t_01*1.0/nbr_t_0 except : c = 0.99 try : A = nbr_t_10*1.0/nbr_t_1 except : A = 0.99 if c == 1 : c = 0.99 if A > 1 - c: print('Attention : le modèle PRM sans banque de graines ne permet pas de bien rendre compte de la dynamique.') A = 1 - c p = 1 - (A*1.0/(1-c)) vrais = 0 for obs in liste_obs : if obs[0] == 0: coef = pi else : coef = 1 - pi for i in range(1, len(obs)): if obs[i-1] == 0: if obs[i] == 0: coef *= (1-c) else : coef *= c else : if obs[i] == 0: coef *= (1-p)*(1-c) else : coef *= (p + (1-p)*c) vrais += log(coef) return (gs.ModPRM(c, p, 1, 1, pi), exp(vrais), 6 - 2*vrais)
def etape_EM_PRM_BGS(liste_obs, modprm): try: assert modprm.p == 1 except AssertionError: print("Attention : le modèle PRM entré en argument n'est pas un modèle à banque graines à germination simple.") return(modprm) api = 0 bpi = 0 ag = 0 bg = 0 ac = 0 bc = 0 ac2 = 0 bc2 = 0 vrais2 = 0 #On separe la liste d'observations en les differents patchs for obs in liste_obs: algo_fb = algo_fb_prm_rescale(obs, modprm) alpha = algo_fb[0] beta = algo_fb[1] coef = algo_fb[2] tps = obs.tps lo = len(obs) vrais2 += log(coef[-1]) for value in coef: vrais2 += log(value) proba_s = obs_bg_simple(alpha, beta, coef, tps, lo, modprm) proba_t = obs_bg_trans(alpha, beta, tps, lo, modprm, obs) bpi += proba_s[0][0] api += (proba_s[0][1] + proba_s[0][2]) ag += proba_s[0][2] bg += (proba_s[0][1]) for j in range(len(obs)-1): ag += (proba_t[j][0][2] + proba_t[j][1][2] + proba_t[j][2][2]) bg += (proba_t[j][0][1] + proba_t[j][1][1] + proba_t[j][2][1]) ac += (proba_t[j][0][1] + proba_t[j][0][2]) bc += proba_t[j][0][0] bc2 += (proba_t[j][1][0]) ac2 += (proba_t[j][1][1] + proba_t[j][1][2]) #On optimise npi = api/(api+bpi) ng = ag/(ag+bg) if ac + bc == 0: ac += 0.001 nc = ac/(ac+bc) nc2 = ac2/(ac2+bc2) if nc == 1 : nc = 0.99 if nc2 < nc: nc = nc2 #print('optimisation ratée') nd = (1-nc2)/(1-nc) np = 1 vrais = api*log(npi) + bpi*log(1-npi) + ag*log(ng) + bg*log(1-ng) vrais += ac*log(nc) + bc*log(1-nc) + ac2*log(nc2) + bc2*log(1-nc2) try : newmod = gs.ModPRM(nc, np, ng, nd, npi) except : return(modprm, 0, 10000) return (newmod, exp(vrais), 8 - 2*vrais2)
def etape_EM_PRM(liste_obs, modprm): api = 0 bpi = 0 ag = 0 bg = 0 ac = 0 bc = 0 ac2 = 0 bc2 = 0 ap2 = 0 bp2 = 0 vrais2 = 0 #On separe la liste d'observations en les differents patchs for obs in liste_obs: algo_fb = algo_fb_prm_rescale(obs, modprm) alpha = algo_fb[0] beta = algo_fb[1] coef = algo_fb[2] vrais2 += log(coef[-1]) for value in coef: vrais2 += log(value) tps = obs.tps lo = len(obs) proba_s = obs_bg_simple(alpha, beta, coef, tps, lo, modprm) proba_t = obs_bg_trans(alpha, beta, tps, lo, modprm, obs) bpi += proba_s[0][0] api += (proba_s[0][1] + proba_s[0][2]) ag += proba_s[0][2] bg += (proba_s[0][1]) for j in range(len(obs)-1): ag += (proba_t[j][0][2] + proba_t[j][1][2] + proba_t[j][2][2]) bg += (proba_t[j][0][1] + proba_t[j][1][1] + proba_t[j][2][1]) ac += (proba_t[j][0][1] + proba_t[j][0][2]) bc += proba_t[j][0][0] bc2 += (proba_t[j][1][0]) ac2 += (proba_t[j][1][1] + proba_t[j][1][2]) ap2 += (proba_t[j][2][1] + proba_t[j][2][2]) bp2 += (proba_t[j][2][0]) #On optimise npi = api/(api+bpi) ng = ag/(ag+bg) nc = ac/(ac+bc) nc2 = ac2/(ac2+bc2) np2 = ap2/(ap2+bp2) if np2 < nc2: nc2 = np2 print('optimisation ratée') if nc2 < nc: nc = nc2 print('optimisation ratée') nd = (1-nc2)/(1-nc) np = 1 - (1-np2)/(1-nc2) # if npi < 0.05: # npi = 0.05 # if npi > 0.95: # npi = 0.95 # if nc < 0.05 : # nc = 0.05 # if nc > 0.95: # nc = 0.95 # if ng < 0.05 : # ng = 0.05 # if ng > 0.95 : # ng = 0.95 # if nd < 0.05 : # nd = 0.05 # if nd > 0.95 : # nd = 0.95 # if np < 0.05: # np = 0.05 # if np > 0.95 : # np = 0.95 #On calcule la vraisemblance vrais = api*log(npi)+bpi*log(1-npi)+ag*log(ng)+bg*log(1-ng) + ac*log(nc)+bc*log(1-nc) vrais += ac2*log(nc2)+bc2*log(1-nc2)+ap2*log(np2)+bp2*log(1-np2) # AIC = 10 - 2*vrais AIC2 = 10 - 2*vrais2 newmod = gs.ModPRM(nc, np, ng, nd, npi) # return (newmod , exp(vrais), AIC, AIC2) return (newmod , exp(vrais), AIC2)
def etape_EM_PRM_BGS_na(liste_obs, modprm, year): try: assert modprm.p == 1 except AssertionError: print("Error : the model entered is not a SB+ model") return(modprm) api = Decimal('0.0') bpi = Decimal('0.0') ag = Decimal('0.0') bg = Decimal('0.0') ac = Decimal('0.0') bc = Decimal('0.0') ac2 = Decimal('0.0') bc2 = Decimal('0.0') vrais2 = Decimal('0.0') #Each tree base is treated one by one for obs in liste_obs: #Writing the two possible completed observations obs_temp = obs.affiche() obs1 = ListePlante(obs_temp[:]) obs0 = ListePlante(obs_temp[:]) obs1[year] = 1 obs0[year] = 0 #Forward-backward algorithm #Rescaling is used to prevent rounding errors #1 - On obs1 algo_fb_1 = algo_fb_prm_rescale(obs1, modprm) alpha_1 = algo_fb_1[0] beta_1 = algo_fb_1[1] coef_1 = algo_fb_1[2] tps = obs.tps #Time duration proba_s_1 = obs_bg_simple(alpha_1, beta_1, coef_1, tps, modprm) proba_t_1 = obs_bg_trans(alpha_1, beta_1, tps, modprm, obs1) #2 - On obs0 algo_fb_0 = algo_fb_prm_rescale(obs0, modprm) alpha_0 = algo_fb_0[0] beta_0 = algo_fb_0[1] coef_0 = algo_fb_0[2] tps = obs.tps #Time duration proba_s_0 = obs_bg_simple(alpha_0, beta_0, coef_0, tps, modprm) proba_t_0 = obs_bg_trans(alpha_0, beta_0, tps, modprm, obs0) #Computation of coefficients proba0 = sum(alpha_0[-1]) for coef in coef_0 : proba0 *= coef proba1 = sum(alpha_1[-1]) for coef in coef_1 : proba1 *= coef cond0 = proba0/(proba0+proba1) cond1 = proba1/(proba0+proba1) #Integration of probabilities in coefficients #Initial conditions #For obs0 bpi += proba_s_0[0][0]*cond0 api += (proba_s_0[0][1] + proba_s_0[0][2])*cond0 ag += proba_s_0[0][2]*cond0 bg += (proba_s_0[0][1])*cond0 #For obs1 bpi += proba_s_1[0][0]*cond1 api += (proba_s_1[0][1] + proba_s_1[0][2])*cond1 ag += proba_s_1[0][2]*cond1 bg += (proba_s_1[0][1])*cond1 #Transitions for j in range(len(obs)-1): #For obs0 ag += (proba_t_0[j][0][2] + proba_t_0[j][1][2] + proba_t_0[j][2][2])*cond0 bg += (proba_t_0[j][0][1] + proba_t_0[j][1][1] + proba_t_0[j][2][1])*cond0 ac += (proba_t_0[j][0][1] + proba_t_0[j][0][2])*cond0 bc += proba_t_0[j][0][0]*cond0 bc2 += (proba_t_0[j][1][0])*cond0 ac2 += (proba_t_0[j][1][1] + proba_t_0[j][1][2])*cond0 #For obs1 ag += (proba_t_1[j][0][2] + proba_t_1[j][1][2] + proba_t_1[j][2][2])*cond1 bg += (proba_t_1[j][0][1] + proba_t_1[j][1][1] + proba_t_1[j][2][1])*cond1 ac += (proba_t_1[j][0][1] + proba_t_1[j][0][2])*cond1 bc += proba_t_1[j][0][0]*cond1 bc2 += (proba_t_1[j][1][0])*cond1 ac2 += (proba_t_1[j][1][1] + proba_t_1[j][1][2])*cond1 #Optimisation npi = api/(api+bpi) if npi > Decimal('0.999999') : npi = Decimal('0.999999') if npi < Decimal('0.000001'): npi = Decimal('0.000001') ng = ag/(ag+bg) if ng > Decimal('0.999999') : ng = Decimal('0.999999') if ng < Decimal('0.000001'): ng = Decimal('0.000001') nc = ac/(ac+bc) if nc > Decimal('0.999999') : nc = Decimal('0.999999') if nc < Decimal('0.000001'): nc = Decimal('0.000001') nc2 = ac2/(ac2+bc2) if nc2 > Decimal('0.999999') : nc2 = Decimal('0.999999') if nc2 < Decimal('0.000001'): nc2 = Decimal('0.000001') if nc2 < nc: nc = (ac + ac2)/(ac + ac2 + bc + bc2) nc2 = nc nd = (1-nc2)/(1-nc) np = Decimal('1.0') vrais_c = api*npi.ln() + bpi*((1-npi).ln()) + ag*ng.ln() + bg*((1-ng).ln()) vrais_c += ac*nc.ln() + bc*((1-nc).ln()) + ac2*nc2.ln() + bc2*((1-nc2).ln()) try : newmod = gs.ModPRM(nc, np, ng, nd, npi) #Check if there is no error (e.g too high/low probas) except : return(modprm, 0, 10000) return (newmod, 0, 8-2*vrais_c) #The 0 is a remnant from a former version of the code
def etape_EM_PRM_BGS(liste_obs, modprm): try: assert modprm.p == 1 except AssertionError: print("Error : the model entered is not a SB+ model") return(modprm) api = Decimal('0.0') bpi = Decimal('0.0') ag = Decimal('0.0') bg = Decimal('0.0') ac = Decimal('0.0') bc = Decimal('0.0') ac2 = Decimal('0.0') bc2 = Decimal('0.0') vrais2 = Decimal('0.0') #Each tree base is treated one by one for obs in liste_obs: #Forward-backward algorithm #Rescaling is used to prevent rounding errors algo_fb = algo_fb_prm_rescale(obs, modprm) alpha = algo_fb[0] beta = algo_fb[1] coef = algo_fb[2] tps = obs.tps #Time duration #vrais2 += coef[-1].ln() for value in coef: vrais2 += value.ln() proba_s = obs_bg_simple(alpha, beta, coef, tps, modprm) proba_t = obs_bg_trans(alpha, beta, tps, modprm, obs) #Integration of probabilities in coefficients #Initial conditions bpi += proba_s[0][0] api += (proba_s[0][1] + proba_s[0][2]) ag += proba_s[0][2] bg += (proba_s[0][1]) #Transitions for j in range(len(obs)-1): ag += (proba_t[j][0][2] + proba_t[j][1][2] + proba_t[j][2][2]) bg += (proba_t[j][0][1] + proba_t[j][1][1] + proba_t[j][2][1]) ac += (proba_t[j][0][1] + proba_t[j][0][2]) bc += proba_t[j][0][0] bc2 += (proba_t[j][1][0]) ac2 += (proba_t[j][1][1] + proba_t[j][1][2]) #Optimisation npi = api/(api+bpi) ng = ag/(ag+bg) nc = ac/(ac+bc) nc2 = ac2/(ac2+bc2) if nc2 < nc: nc = (ac + ac2)/(ac + ac2 + bc + bc2) nc2 = nc nd = (1-nc2)/(1-nc) np = Decimal('1.0') try : newmod = gs.ModPRM(nc, np, ng, nd, npi) #Check if there is no error (e.g too high/low probas) except : return(modprm, 0, 10000) return (newmod, 0, 8 - 2*vrais2) #The 0 is a remnant from a former version of the code
######################################## #Test du fonctionnement des estimateurs# ######################################## if __name__ == '__main__': #En Levins, on peut descendre à 19 d'AIC avec ce jeu abscisse = [0.45, 0.52] ordonnee = [0.1, 0.2] a = Decimal('0.2') y = Decimal('0.6') an = [2013, 2015, 2016, 2017, 2018, 2019, 2021, 2022, 2023] patch_ex = ListePlante([0, 1, 1, 1, 0, 1, 0, 1, 0]) patch_ex2 = ListePlante([1, 1, 1, 0, 1, 0, 1, 1, 0]) #levins_ex = gs.ModLevins(a, y, Decimal('1'), Decimal('0.5'), Decimal('0.5'), Decimal('0.5')) prm_ex = gs.ModPRM(Decimal('0.6'), Decimal('0.4'), Decimal('0.5'), Decimal('0.4'), Decimal('0.5')) for i in range(100): res = etape_EM_PRM_BGS_na([patch_ex, patch_ex2], prm_ex, an) print(res) print(res[0]) prm_ex = res[0] #res = etape_EM_PRM_BGS_pen([patch_ex, patch_ex2], prm_ex, Decimal('20'), Decimal('0.4')) print(res[2]) print(res[0].c, res[0].g, res[0].d, res[0].pi) matrice = [[0, 1, 2], [0, 1, 2], [0, 1, 2]] print(puis_matrice_33(matrice))