diff --git a/input/v6.3/params/bg_diverse_9-tt-only_fixed-no-income.yaml b/input/v6.3/params/bg_diverse_9-tt-only_fixed-no-income.yaml new file mode 100644 index 00000000..41a6865e --- /dev/null +++ b/input/v6.3/params/bg_diverse_9-tt-only_fixed-no-income.yaml @@ -0,0 +1,50 @@ +# + python -u estimate_biogeme_plan_choice.py --input plan-choices-diverse_9-tt-only.csv --no-income --ascs car 0 --ascs ride 0 --ascs pt 0 --ascs bike 0 --car-util 5.485672 +# Modes: ['walk', 'pt', 'car', 'bike', 'ride'] +# Number of plans: 8259 +# Number of choices for plan: 9 +# Modes: ['walk', 'pt', 'car', 'bike', 'ride'] +# Number of choices: 8259 +# Using fixed ascs {'car': 0.0, 'ride': 0.0, 'pt': 0.0, 'bike': 0.0} +# Using fixed utility for car 5.485672 +# Results for model plan-choices-diverse_9-tt-only_fixed_ascs_no_income +# Nbr of parameters: 4 +# Sample size: 8259 +# Excluded data: 0 +# Null log likelihood: -16870.42 +# Final log likelihood: -19458.35 +# Likelihood ratio test (null): -5175.862 +# Rho square (null): -0.153 +# Rho bar square (null): -0.154 +# Akaike Information Criterion: 38924.7 +# Bayesian Information Criterion: 38952.78 +scoring: + scoringParameters: + - modeParams: + - mode: walk + constant: 0 + - mode: car + constant: -0.5341414592094356 + dailyMonetaryConstant: -14.30 + dailyUtilityConstant: 5.485672 + - mode: pt + constant: 0.3971116 + - mode: bike + constant: -1.3538876325 + - mode: ride + constant: -1.23976957093642 +advancedScoring: + scoringParameters: + - subpopulation: person + modeParams: + - mode: car + deltaDailyConstant: 7.213378 + varDailyConstant: truncatedNormal + - mode: bike + deltaConstant: 1.213346 + varConstant: normal + - mode: pt + deltaConstant: 4.036673 + varConstant: normal + - mode: ride + deltaConstant: 0.490086 + varConstant: normal \ No newline at end of file diff --git a/input/v6.3/params/mxl_manual.yaml b/input/v6.3/params/mxl_manual.yaml new file mode 100644 index 00000000..020987cb --- /dev/null +++ b/input/v6.3/params/mxl_manual.yaml @@ -0,0 +1,37 @@ +# This is a baseline defined manually, close to the standard model + +# daily car utility is the same as in the base model, fixed and variable portion is split 50/50 +# mean of tn is ~ 0.8, -> 4.15 / 0.8 -> 5.18 +# Other modes are assigned a standard normal distribution + +scoring: + scoringParameters: + - modeParams: + - mode: walk + constant: 0 + - mode: car + constant: 0 + dailyMonetaryConstant: -14.30 + dailyUtilityConstant: 4.15 + - mode: pt + constant: 0.3971116 + - mode: bike + constant: -1.3538876325 + - mode: ride + constant: -1.23976957093642 +advancedScoring: + scoringParameters: + - subpopulation: person + modeParams: + - mode: car + deltaDailyConstant: 5.18 + varDailyConstant: truncatedNormal + - mode: bike + deltaConstant: 1 + varConstant: normal + - mode: pt + deltaConstant: 1 + varConstant: normal + - mode: ride + deltaConstant: 1 + varConstant: normal \ No newline at end of file diff --git a/src/main/python/choicemodels/estimate_biogeme_plan_choice.py b/src/main/python/choicemodels/estimate_biogeme_plan_choice.py index 695ed668..490e2531 100644 --- a/src/main/python/choicemodels/estimate_biogeme_plan_choice.py +++ b/src/main/python/choicemodels/estimate_biogeme_plan_choice.py @@ -26,6 +26,7 @@ parser.add_argument("--ascs", help="Predefined ASCs", nargs="+", action='append', default=[]) parser.add_argument("--car-util", help="Fixed utility for car", type=float, default=None) parser.add_argument("--no-mxl", help="Disable mixed logit", action="store_true") + parser.add_argument("--no-income", help="Don't consider the income", action="store_true") args = parser.parse_args() @@ -94,7 +95,7 @@ for i in range(1, ds.k + 1): # Price is already negative - u = v[f"plan_{i}_price"] * UTIL_MONEY * (ds.global_income / v["income"]) ** EXP_INCOME + u = v[f"plan_{i}_price"] * UTIL_MONEY * (1 if args.no_income else (ds.global_income / v["income"]) ** EXP_INCOME) u -= v[f"plan_{i}_pt_n_switches"] for mode in ds.modes: @@ -124,6 +125,8 @@ modelName += "_util_money" if args.ascs: modelName += "_fixed_ascs" + if args.no_income: + modelName += "_no_income" biogeme.modelName = modelName biogeme.weight = v["weight"] diff --git a/src/main/python/choicemodels/estimate_mixed_plan_choice.py b/src/main/python/choicemodels/estimate_mixed_plan_choice.py index 7a29c8c8..9af8fe80 100644 --- a/src/main/python/choicemodels/estimate_mixed_plan_choice.py +++ b/src/main/python/choicemodels/estimate_mixed_plan_choice.py @@ -33,6 +33,7 @@ def analyse_mode_share(df, modes): parser.add_argument("--sample", help="Use sample of choice data", type=float, default=1) parser.add_argument("--seed", help="Random seed", type=int, default=0) parser.add_argument("--mnl", help="Use MNL instead of mixed logit", action="store_true") + parser.add_argument("--ascs", help="Predefined ASCs", nargs="+", action='append', default=[]) args = parser.parse_args() @@ -42,6 +43,10 @@ def analyse_mode_share(df, modes): alt_list=[f"plan_{i}" for i in range(1, ds.k + 1)], empty_val=0, varying=ds.varying, alt_is_prefix=True) + fixedvars = {x + "_usage": float(y) for x, y in args.ascs} + if fixedvars: + print("Using fixed ascs", fixedvars) + analyse_mode_share(df, ds.modes) MixedLogit.check_if_gpu_available() @@ -55,6 +60,9 @@ def analyse_mode_share(df, modes): # utils contains the price and opportunist costs addit = df["utils"] - df["pt_n_switches"] + # Fix car usage to its initial mnl value, otherwise there are convergence problems + fixedvars["car_used"] = None + if not args.mnl: model = MixedLogit() model.fit(X=df[varnames], y=df['choice'], weights=df['weight'], varnames=varnames, @@ -62,7 +70,7 @@ def analyse_mode_share(df, modes): addit=addit, # randvars={"car_used": "tn"}, randvars={"car_used": "tn", "bike_usage": "n", "pt_usage": "n", "ride_usage": "n"}, - fixedvars={"car_used": None}, + fixedvars=fixedvars, n_draws=args.n_draws, batch_size=args.batch_size, halton=True, skip_std_errs=True, optim_method='L-BFGS-B')