Incorporating a Latent Variable in an MNL Model

29 views
Skip to first unread message

ענבל גליקמן

unread,
Mar 10, 2025, 3:29:27 AMMar 10
to Biogeme

Dear Prof. Bierliare

I am trying to incorporate a latent variable into a standard MNL model. The respondents answered four personal norm statements regarding environmental concerns, rating them on a scale from 1 to 5.

I would like to create a latent variable representing pro-environmental attitudes and include it in the utility function.

This is what I have done but my model didn't converge, How can I fix this issue? Should one of the lambda parameters be fixed to 1?

I would appreciate your guidance.

LAMBDA_1 = Beta('LAMBDA_1', 1, None, None, 0)
LAMBDA_2 = Beta('LAMBDA_2', 1, None, None, 0)
LAMBDA_3 = Beta('LAMBDA_3', 1, None, None, 0)
LAMBDA_4 = Beta('LAMBDA_4', 1, None, None, 0)
SIGMA_err = Beta('SIGMA_err', 1, None, None, 0)

Err_term = SIGMA_err * bioDraws('Err', 'NORMAL')

ProEnv = (
LAMBDA_1 * PN1 +
LAMBDA_2 * PN2 +
LAMBDA_3 * PN3 +
LAMBDA_4 * PN4 +
Err_term )

ProEnv_monte = MonteCarlo(ProEnv)


Err_term = SIGMA_err * bioDraws('Err''NORMAL')

ProEnv = (
LAMBDA_1 * PN1 +
LAMBDA_2 * PN2 +
LAMBDA_3 * PN3 +
LAMBDA_4 * PN4 +
Err_term )

ProEn
v_monte = MonteCarlo(ProEnv)


  ProEnv_monte was included in (n-1) utility functions, with a different beta coefficient for each function

thanks a lot
Inbal

Michel Bierlaire

unread,
Mar 10, 2025, 3:33:29 AMMar 10
to inba...@gmail.com, Michel Bierlaire, Biogeme
Integrating the latent variable just cancels the error term.
Follow the example described here: https://transp-or.epfl.ch/documents/technicalReports/Bier18b.pdf
> --
> You received this message because you are subscribed to the Google Groups "Biogeme" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to biogeme+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/biogeme/1a8a931d-7043-4a6b-878e-77b3db2fb7ecn%40googlegroups.com.

Michel Bierlaire
Transport and Mobility Laboratory
School of Architecture, Civil and Environmental Engineering
EPFL - Ecole Polytechnique Fédérale de Lausanne
http://transp-or.epfl.ch
http://people.epfl.ch/michel.bierlaire

Michel Bierlaire

unread,
Mar 11, 2025, 3:09:42 AMMar 11
to ענבל גליקמן, Michel Bierlaire, Biogeme
Try increase the initial value of sigma to 10 or even 100.
Anyway, your specification does not look correct. You need to integrate the product of the probabilities, and then take the log.

> On 10 Mar 2025, at 20:18, ⁨ענבל גליקמן⁩ <⁨inba...@gmail.com⁩> wrote:
>
> : :I tried using the method from the explanation file you sent me, and I formulated the model as follows
> tau1_1 = Beta('tau1_1', -1, None, None, 0) # סף ראשון עבור PN1
> tau1_2 = Beta('tau1_2', 0, None, None, 0) # סף שני עבור PN1
> tau1_3 = Beta('tau1_3', 1, None, None, 0) # סף שלישי עבור PN1
>
> tau2_1 = Beta('tau2_1', -1, None, None, 0) # סף ראשון עבור PN2
> tau2_2 = Beta('tau2_2', 0, None, None, 0) # סף שני עבור PN2
> tau2_3 = Beta('tau2_3', 1, None, None, 0) # סף שלישי עבור PN2
>
> tau3_1 = Beta('tau3_1', -1, None, None, 0) # סף ראשון עבור PN3
> tau3_2 = Beta('tau3_2', 0, None, None, 0) # סף שני עבור PN3
> tau3_3 = Beta('tau3_3', 1, None, None, 0) # סף שלישי עבור PN3
>
> tau4_1 = Beta('tau4_1', -1, None, None, 0) # סף ראשון עבור PN4
> tau4_2 = Beta('tau4_2', 0, None, None, 0) # סף שני עבור PN4
> tau4_3 = Beta('tau4_3', 1, None, None, 0) # סף שלישי עבור PN4
>
>
> # === משתנה מקרי (Random Variable) בתוך אינטגרציה ===
> omega = RandomVariable('omega')
> density = dist.normalpdf(omega) # פונקציית צפיפות של ההתפלגות הנורמלית
>
> # === משתנה חבוי עם משתנה מקרי omega ===
> LV = (
> Beta('LAMBDA_1', 1, None, None, 1) * PN1 +
> Beta('LAMBDA_2', 1, None, None, 0) * PN2 +
> Beta('LAMBDA_3', 1, None, None, 0) * PN3 +
> Beta('LAMBDA_4', 1, None, None, 0) * PN4 +
> Beta('SIGMA_err', 1, None, None, 0) * omega # תוספת רעש רנדומלי
> )
>
> # === הסתברות של מודל המדידה ===
> # ספים עבור PN1
> P_PN1_1 = bioNormalCdf(tau1_1 - LV)
> P_PN1_2 = bioNormalCdf(tau1_2 - LV) - bioNormalCdf(tau1_1 - LV)
> P_PN1_3 = bioNormalCdf(tau1_3 - LV) - bioNormalCdf(tau1_2 - LV)
> P_PN1_4 = 1 - bioNormalCdf(tau1_3 - LV)
>
> # ספים עבור PN2
> P_PN2_1 = bioNormalCdf(tau2_1 - LV)
> P_PN2_2 = bioNormalCdf(tau2_2 - LV) - bioNormalCdf(tau2_1 - LV)
> P_PN2_3 = bioNormalCdf(tau2_3 - LV) - bioNormalCdf(tau2_2 - LV)
> P_PN2_4 = 1 - bioNormalCdf(tau2_3 - LV)
>
> # ספים עבור PN3
> P_PN3_1 = bioNormalCdf(tau3_1 - LV)
> P_PN3_2 = bioNormalCdf(tau3_2 - LV) - bioNormalCdf(tau3_1 - LV)
> P_PN3_3 = bioNormalCdf(tau3_3 - LV) - bioNormalCdf(tau3_2 - LV)
> P_PN3_4 = 1 - bioNormalCdf(tau3_3 - LV)
>
> # ספים עבור PN4
> P_PN4_1 = bioNormalCdf(tau4_1 - LV)
> P_PN4_2 = bioNormalCdf(tau4_2 - LV) - bioNormalCdf(tau4_1 - LV)
> P_PN4_3 = bioNormalCdf(tau4_3 - LV) - bioNormalCdf(tau4_2 - LV)
> P_PN4_4 = 1 - bioNormalCdf(tau4_3 - LV)
>
>
> loglike_PN1 = (
> (PN1 == 1) * log(P_PN1_1) +
> (PN1 == 2) * log(P_PN1_2) +
> (PN1 == 3) * log(P_PN1_3) +
> (PN1 == 4) * log(P_PN1_4)
> )
>
> loglike_PN2 = (
> (PN2 == 1) * log(P_PN2_1) +
> (PN2 == 2) * log(P_PN2_2) +
> (PN2 == 3) * log(P_PN2_3) +
> (PN2 == 4) * log(P_PN2_4)
> )
>
> loglike_PN3 = (
> (PN3 == 1) * log(P_PN3_1) +
> (PN3 == 2) * log(P_PN3_2) +
> (PN3 == 3) * log(P_PN3_3) +
> (PN3 == 4) * log(P_PN3_4)
> )
>
> loglike_PN4 = (
> (PN4 == 1) * log(P_PN4_1) +
> (PN4 == 2) * log(P_PN4_2) +
> (PN4 == 3) * log(P_PN4_3) +
> (PN4 == 4) * log(P_PN4_4)
> )
>
> loglike_measurement = loglike_PN1 + loglike_PN2 + loglike_PN3 + loglike_PN4
> V1 = BTime_car * CarTDispValue # רכב
> V2 = ASC_PT + BTime_PT * PTTDispValue + BCost_PT * EuroPTCValue + BProEnv_PT * LV # תחבורה ציבורית
> V3 = ASC_Bike + BTime_Bike * BikeTime_1 + BProEnv_Bike * LV # אופניים
> V4 = ASC_Walk + BTime_Walk * WalkTime_1 + BProEnv_Walk * LV # הליכה
>
> # מיפוי תועלות
> V = {1: V1, 2: V2, 3: V3, 4: V4}
>
> # פונקציית הסתברות כוללת (מודל המדידה + מודל הבחירה + הצפיפות של omega)
> logprob = Integrate(
> loglike_measurement + models.loglogit(V, {1: av1, 2: av2, 3: av3, 4: av4}, Choice) + log(density),
> 'omega'
> : The following error occurs
> The norm of the gradient at ASC_Bike=0, ASC_PT=0, ASC_Walk=0, BCost_PT=0, BProEnv_Bike=0, BProEnv_PT=0, BProEnv_Walk=0, BTime_Bike=0, BTime_PT=0, BTime_Walk=0, BTime_car=0, LAMBDA_2=1, LAMBDA_3=1, LAMBDA_4=1, SIGMA_err=1 is inf: g=4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244, 4.2e+244
>
> raise ValueError
> ( "array must not contain infs or NaNs")
> ValueError: array must not contain infs or NaNs
>
> Needless to say, there are no missing or infinite values in my data file
> ... I really need help resolving this issue. I’ve been stuck for many daysThanks a lot!
>
> ‫בתאריך יום ב׳, 10 במרץ 2025 ב-9:33 מאת ‪Michel Bierlaire‬‏ <‪michel.b...@epfl.ch‬‏>:‬

ענבל גליקמן

unread,
Mar 11, 2025, 3:09:49 AMMar 11
to Michel Bierlaire, Biogeme
:  :I tried using the method from the explanation file you sent me, and I formulated the model as follows
tau1_1 = Beta('tau1_1', -1, None, None, 0)  # סף ראשון עבור PN1
tau1_2 = Beta('tau1_2', 0, None, None, 0) # סף שני עבור PN1
tau1_3 = Beta('tau1_3', 1, None, None, 0) # סף שלישי עבור PN1

tau2_1 = Beta('tau2_1', -1, None, None, 0) # סף ראשון עבור PN2
tau2_2 = Beta('tau2_2', 0, None, None, 0) # סף שני עבור PN2
tau2_3 = Beta('tau2_3', 1, None, None, 0) # סף שלישי עבור PN2

tau3_1 = Beta('tau3_1', -1, None, None, 0) # סף ראשון עבור PN3
tau3_2 = Beta('tau3_2', 0, None, None, 0) # סף שני עבור PN3
tau3_3 = Beta('tau3_3', 1, None, None, 0) # סף שלישי עבור PN3

tau4_1 = Beta('tau4_1', -1, None, None, 0) # סף ראשון עבור PN4
tau4_2 = Beta('tau4_2', 0, None, None, 0) # סף שני עבור PN4
tau4_3 = Beta('tau4_3', 1, None, None, 0) # סף שלישי עבור PN4


# === משתנה מקרי (Random Variable) בתוך אינטגרציה ===
omega = RandomVariable('omega')
density = dist.normalpdf(omega) # פונקציית צפיפות של ההתפלגות הנורמלית

# === משתנה חבוי עם משתנה מקרי omega ===
LV = (
    Beta('LAMBDA_1', 1, None, None, 1) * PN1 +
Beta('LAMBDA_2', 1, None, None, 0) * PN2 +
Beta('LAMBDA_3', 1, None, None, 0) * PN3 +
Beta('LAMBDA_4', 1, None, None, 0) * PN4 +
Integrating the latent variable just cancels the error term.
Reply all
Reply to author
Forward
0 new messages