biogeme-nest_logit-cnblog

article/2025/9/18 6:06:55

biogeme-nest_logit

基础数据:

optima.dat

image-20220930090135788

变量的描述:出处

  • OccupStat:职业
  • TimePT:公共交通通行时间
  • TimeCar:小汽车通行时间
  • MarginalCostPT:公共交通总成本
  • CostCarCHF:小汽车的总汽油成本
  • distance_km:距离
  • choice:Choice variable: 0 = public transports (train, bus, tram, etc.); 1 = private modes (car, motorbike, etc.); 2 = soft modes (bike, walk, etc.)
  • Gender:性别

image-20220930091519387

  • public transportation 和slow modes 被分为了一个nest

  • car单独组成一个nest

    不同主枝下面可以有不同数量的分支,也可以只有一个分支

定义效用函数

三种交通方式的效用模型。这个效用函数,实质上 = 常数+时间成本+经济成本

image-20220930132302195

image-20220930130955627

  • ASC CAR, ASC SM, BETA TIME FULLTIME, BETA TIME OTHER, BETA DIST MALE, BETA DIST FEMALE, BETA DIST UNREPORTED, BETA COST, are parameters to be estimated(是我们需要进行标定的参数)

  • TimePT scale, MarginalCostPT scaled, TimeCar scale, CostCarCHF scale, distance km scale are attributes and fulltime , notfulltime, male, female, unreportedGender are socio-economic characteristics. (其他的是社会经济变量:时间、成本、距离、性别)

  • ASC CAR, ASC SM,ASC_PT :常数项

    需要注意的是:并不是所以的常数项都可以标定得到。(参考教程)


代码

(整体的代码结构参照:夜间清风-交通出行预测)

​ 整体代码见 biogeme -02estimation.ipynb

1.导入库+读取数据库文件并创建数据库对象

# 导入库
from biogeme import models
import biogeme.biogeme as bio
from scenarios import scenario, database
import pandas as pd
import biogeme.database as db
from biogeme.expressions import Beta, Variable#读取数据
df = pd.read_csv('optima.dat', sep='\t')  #dataframe
#创建数据库对象
database = db.Database('optima', df)

2. 根据数据设置变量

数据库中的每一个列名对应的模型中的一个变量。用以下语句设置变量:

Choice = Variable('Choice')
TimePT = Variable('TimePT')
TimeCar = Variable('TimeCar')
MarginalCostPT = Variable('MarginalCostPT')    # 边际成本
CostCarCHF = Variable('CostCarCHF')  #
distance_km = Variable('distance_km')   #距离
Gender = Variable('Gender')
OccupStat = Variable('OccupStat')
Weight = Variable('Weight')

3. 设置待估计变量

# List of parameters to be estimated   #待估计的参数列表
ASC_CAR = Beta('ASC_CAR', 0, None, None, 0)  #Beta:从数据中估计未知参数
ASC_PT = Beta('ASC_PT', 0, None, None, 1)
ASC_SM = Beta('ASC_SM', 0, None, None, 0)
BETA_TIME_FULLTIME = Beta('BETA_TIME_FULLTIME', 0, None, None, 0)
BETA_TIME_OTHER = Beta('BETA_TIME_OTHER', 0, None, None, 0)
BETA_DIST_MALE = Beta('BETA_DIST_MALE', 0, None, None, 0)
BETA_DIST_FEMALE = Beta('BETA_DIST_FEMALE', 0, None, None, 0)
BETA_DIST_UNREPORTED = Beta('BETA_DIST_UNREPORTED', 0, None, None, 0)
BETA_COST = Beta('BETA_COST', 0, None, None, 0)

Biogeme用Beta库来定义待估参数(模型系数)。ASC CAR, ASC SM,ASC_PT :常数项。其他参数是各变量对应的系数。仔细看一下效用函数就能明白。

在定义待估计系数时,需要提供5个信息:

  • 参数名称
  • 参数的默认值
  • 参数下限,没有用None表示
  • 参数上限,没有用None表示
  • 还要给参数一个标记:0表示要估计该参数;1表示保持它的默认值

4. 变量数值缩放

由于数值原因,最好将数据缩放到1左右

TimePT_scaled = TimePT / 200
TimeCar_scaled = TimeCar / 200
CostCarCHF_scaled = CostCarCHF / 10
distance_km_scaled = distance_km / 5
male = Gender == 1
female = Gender == 2
unreportedGender = Gender == -1fulltime = OccupStat == 1 
notfulltime = OccupStat != 1
#OccupStat 1:表示全职  !1 :非全职

5. 定义效用函数

MarginalCostScenario = MarginalCostPT * factor
MarginalCostPT_scaled = MarginalCostScenario / 10
#定义效用函数
V_PT = (ASC_PT+ BETA_TIME_FULLTIME * TimePT_scaled * fulltime+ BETA_TIME_OTHER * TimePT_scaled * notfulltime+ BETA_COST * MarginalCostPT_scaled
)
V_CAR = (ASC_CAR+ BETA_TIME_FULLTIME * TimeCar_scaled * fulltime+ BETA_TIME_OTHER * TimeCar_scaled * notfulltime+ BETA_COST * CostCarCHF_scaled
)
V_SM = (ASC_SM+ BETA_DIST_MALE * distance_km_scaled * male+ BETA_DIST_FEMALE * distance_km_scaled * female+ BETA_DIST_UNREPORTED * distance_km_scaled * unreportedGender
)

6. 对应效用函数与方案

V = {0: V_PT,1: V_CAR, 2: V_SM}

V: 代表各备选方案的效用函数的字典

7. 定义nest结构(分层结构)

MU_NOCAR = Beta('MU_NOCAR', 1.0, 1.0, None, 0)CAR_NEST = 1.0, [1]  # car单独分为一类 nest:CAR_NEST
NO_CAR_NEST = MU_NOCAR, [0, 2]  # PT、SM分为一类 nest:NO_CAR_NEST
nests = CAR_NEST, NO_CAR_NEST

8. 计算logprob(概率的对数)

logprob = models.lognested(V, None, nests, Choice)  #V是效用函数 
#需要输入1. 各备选方案的效用函数字典 2. 各方案可用性字典(可以为None)
#3. nests:tuple 
"""Example::nesta = MUA, [1, 2, 3]nestb = MUB, [4, 5, 6]nests = nesta, nestb
"""
#logprob:基于MEV,对嵌套logit模型的选择概率取log

9. estimation

# Create the Biogeme object for estimation  #估计
biogeme = bio.BIOGEME(database, logprob)
biogeme.modelName = '02estimation'print('Estimation...')
# Estimate the parameters. Perform bootstrapping.
#估计参数
results = biogeme.estimate(bootstrap=100)# Get the results in a pandas table
pandasResults = results.getEstimatedParameters()
print(pandasResults)

10. Simulation

print('Simulation...')simulated_choices = logprob.getValue_c(betas=results.getBetaValues(), database=database
)
#getValue_c ,如果提供了一整个数据库,则返回的是一个list,是将表达式应用到每一行的一个结果(概率值,浮点数)
#getValue_c()函数中需要输入上面标定的参数+数据库print(simulated_choices)loglikelihood = logprob.getValue_c(betas=results.getBetaValues(),  #标定系数值database=database, #数据库aggregation=True,  #如果一共了一个database,且参数为true,则表达式应用于每个条目(行),并聚合所有值,返回和。
)print(f'Final log likelihood:     {results.data.logLike}')
print(f'Simulated log likelihood: {loglikelihood}')

结果

image-20220930151342493

整体代码

#%%
"""File scenarios.py:author: Michel Bierlaire, EPFL
:date: Sun Oct 31 09:40:59 2021Specification of a nested logit model, that will be estimated, andused for simulation.  Three alternatives: public transporation, carand slow modes.  RP data.三种选择方式:public car 慢速模式Based on the Optima data.It contains a function that generates scenarios where the currentcost of public transportation is multiplied by a factor.包含一个函数,生成当前公共交通成本*一个因素"""import pandas as pd
import biogeme.database as db
from biogeme.expressions import Beta, Variable
from biogeme import models
import biogeme.biogeme as bio
from scenarios import scenario, database# Read the data
df = pd.read_csv('optima.dat', sep='\t')
database = db.Database('optima', df)# Variables from the data  #设置变量
Choice = Variable('Choice')
TimePT = Variable('TimePT')
TimeCar = Variable('TimeCar')
MarginalCostPT = Variable('MarginalCostPT')    # 边际成本
CostCarCHF = Variable('CostCarCHF')  #
distance_km = Variable('distance_km')   #距离
Gender = Variable('Gender')
OccupStat = Variable('OccupStat')
Weight = Variable('Weight')# Exclude observations such that the chosen alternative is -1
database.remove(Choice == -1.0)# Normalize the weights (规范化权重)
sumWeight = database.data['Weight'].sum()
numberOfRows = database.data.shape[0]  #行数
normalizedWeight = Weight * numberOfRows / sumWeight# List of parameters to be estimated   #待估计的参数列表
ASC_CAR = Beta('ASC_CAR', 0, None, None, 0)  #Beta:从数据中估计未知参数
ASC_PT = Beta('ASC_PT', 0, None, None, 1)
ASC_SM = Beta('ASC_SM', 0, None, None, 0)
BETA_TIME_FULLTIME = Beta('BETA_TIME_FULLTIME', 0, None, None, 0)
BETA_TIME_OTHER = Beta('BETA_TIME_OTHER', 0, None, None, 0)
BETA_DIST_MALE = Beta('BETA_DIST_MALE', 0, None, None, 0)
BETA_DIST_FEMALE = Beta('BETA_DIST_FEMALE', 0, None, None, 0)
BETA_DIST_UNREPORTED = Beta('BETA_DIST_UNREPORTED', 0, None, None, 0)
BETA_COST = Beta('BETA_COST', 0, None, None, 0)# Definition of variables:  定义变量
# For numerical reasons, it is good practice to scale the data to
# that the values of the parameters are around 1.0.
# 由于数值原因,最好将数据缩放到1左右TimePT_scaled = TimePT / 200
TimeCar_scaled = TimeCar / 200
CostCarCHF_scaled = CostCarCHF / 10
distance_km_scaled = distance_km / 5
male = Gender == 1
female = Gender == 2
unreportedGender = Gender == -1fulltime = OccupStat == 1 
notfulltime = OccupStat != 1
#OccupStat 1:表示全职  !1 :非全职# def scenario(factor=1.0):
"""Provide the model specification for a scenario with the price ofpublic transportation is multiplied by a factor:param factor: factor that multiples the price of public transportation.
:type factor: float:return: a dict with the utility functions, the nesting structure,and the choice expression.返回的是一个字典,包含效用函数,嵌套结构,选择表达式:rtype: dict(int: biogeme.expression), tuple(biogeme.expression,list(int)), biogeme.expression
"""
factor = 1.0
MarginalCostScenario = MarginalCostPT * factor
MarginalCostPT_scaled = MarginalCostScenario / 10
# Definition of utility functions:
V_PT = (ASC_PT+ BETA_TIME_FULLTIME * TimePT_scaled * fulltime+ BETA_TIME_OTHER * TimePT_scaled * notfulltime+ BETA_COST * MarginalCostPT_scaled
)
V_CAR = (ASC_CAR+ BETA_TIME_FULLTIME * TimeCar_scaled * fulltime+ BETA_TIME_OTHER * TimeCar_scaled * notfulltime+ BETA_COST * CostCarCHF_scaled
)
V_SM = (ASC_SM+ BETA_DIST_MALE * distance_km_scaled * male+ BETA_DIST_FEMALE * distance_km_scaled * female+ BETA_DIST_UNREPORTED * distance_km_scaled * unreportedGender
)# Associate utility functions with the numbering of alte1rnatives
#将效用函数和方案编号联系起来
V = {0: V_PT, 1: V_CAR, 2: V_SM}# Definition of the nests:
# 1: nests parameter   嵌套系数
# 2: list of alternatives #备选列表
MU_NOCAR = Beta('MU_NOCAR', 1.0, 1.0, None, 0)CAR_NEST = 1.0, [1]  # car单独分为一类 nest:CAR_NEST
NO_CAR_NEST = MU_NOCAR, [0, 2]  # PT、SM分为一类 nest:NO_CAR_NEST
nests = CAR_NEST, NO_CAR_NEST# return V, nests, Choice, MarginalCostScenario
# The choice model is a nested logit, with availability conditions
# For estimation, we need the log of the probability
# log(prob) :概率的对数
logprob = models.lognested(V, None, nests, Choice)  #V是效用函数 # Create the Biogeme object for estimation  #估计
biogeme = bio.BIOGEME(database, logprob)
biogeme.modelName = '02estimation'print('Estimation...')
# Estimate the parameters. Perform bootstrapping.
results = biogeme.estimate(bootstrap=100)# Get the results in a pandas table
pandasResults = results.getEstimatedParameters()
print(pandasResults)print('Simulation...')simulated_choices = logprob.getValue_c(betas=results.getBetaValues(), database=database
)print(simulated_choices)loglikelihood = logprob.getValue_c(betas=results.getBetaValues(),database=database,aggregation=True,
)print(f'Final log likelihood:     {results.data.logLike}')
print(f'Simulated log likelihood: {loglikelihood}')

附:变量说明

image-20220930125231560

image-20220930125301937

image-20220930125430334

ase
)

print(simulated_choices)

loglikelihood = logprob.getValue_c(
betas=results.getBetaValues(),
database=database,
aggregation=True,
)

print(f’Final log likelihood: {results.data.logLike}‘)
print(f’Simulated log likelihood: {loglikelihood}’)

# 附:变量说明​	[外链图片转存中...(img-cujmPN3m-1664885232398)][外链图片转存中...(img-7srFLeKO-1664885232399)][外链图片转存中...(img-Y5Vs20FO-1664885232399)]![image-20220930125448035](https://img-blog.csdnimg.cn/img_convert/1895ced390fe66bbd1259cad56756b21.png)

http://chatgpt.dhexx.cn/article/771NaWng.shtml

相关文章

必看 logit回归分析步骤汇总

Logit回归分析用于研究X对Y的影响,并且对X的数据类型没有要求,X可以为定类数据(可以做虚拟变量设置),也可以为定量数据,但要求Y必须为定类数据,并且根据Y的选项数,使用相应的数据分析…

PyTorch logit函数

1.PyTorch vs TensorFlow tensorflow是静态图,需要你把啥都准备好,然后它像个傻子一样执行,tensorflow,目前业界更适合部署,毕竟是静态图,infer的时候速度快。 pytorch,它会在执行的时候&…

logit回归模型_详解 Logit/Probit 模型中的 completely determined 问题

NEW!连享会推文专辑:Stata资源 | 数据处理 | Stata绘图 | Stata程序结果输出 | 回归分析 | 时间序列 | 面板数据 | 离散数据交乘调节 | DID | RDD | 因果推断 | SFA-TFP-DEA文本分析+爬虫 | 空间计量 | 学术论文 | 软件工具 连享会学习群-常见问题解答汇总:👉 WD 主页…

Logit Adjust

Logit Adjust BER 我们在分类问题中常用的误分类函数使得分类器最终学到的分布: P ( y ∣ x ) ∝ P ( y ) P ( x ∣ y ) P(y|x) \propto P(y)P(x|y) P(y∣x)∝P(y)P(x∣y) 假设在一个不平衡猫狗二分类问题中,狗是一个小类,只有整个数据集的…

logit

1.为什么需要logit回归? 线性回归不稳健 异常点对拟合直线的影响很大 so linear不适合做分类问题 2.为什么要sigmoid?sigmoid能做什么? y0,1是离散问题,直接建立方程 函数不连续——损失函数不可导——参数无法用梯度法优化 所以我们由 …

Logit 是怎么算的?

从知乎借几张图来描述,先看看odds 是什么? 然后Logit 就 是 Log of odds:

【计算机网络学习笔记】(汇总目录)

计算机网络学习笔记(汇总目录) 文章目录 点击以下标题,跳转到对应章节的详细讲解 【计算机网络学习笔记01】计算机网络概述(上) 【计算机网络学习笔记02】计算机网络概述(中) 【计算机网络学习…

计算机网络期末总结复习(全)

文章目录 第一章:概述1.1、计算机网络在信息时代的作用我国互联网发展状况1.2、因特网概述1、网络、互连网(互联网)和因特网2、因特网发展的三个阶段3、因特网的标准化工作4、因特网的组成补充:1.3 三种交换方式1、电路交换(Circuit Switching)2、分组交换(Packet Switc…

计算机网络的应用领域有那些,计算机网络应用领域

描述 计算机网络应用领域 一、计算机网络在现代企业中的应用 计算机网络的发展和应用改变了传统企业的管理模式和经营模式。在现代企业中企业信息网络得到了广泛的应用。它是一种专门用于企业内部信息管理的计算机网络,覆盖企业生产经营管理的各个部门,在整个企业范围内提供硬…

《王道计算机网络》学习笔记总目录+思维导图

0.思维导图 本篇文章是对《2021王道计算机网络》所有知识点的笔记总结归档,虽说是2021年的,但是这些都是最核心的底层基础知识,过多少年都不会有很大的变化,核心都差不多。我的武功秘籍:note.bithachi.cn,…

计算机必备学习网站

目录 1 论文代码网站 (1)Github:www.github.com/ (2)Papers With Code:https://paperswithcode.com/ (3)researchcode:Research Code (4)sema…

内联函数的使用与引用

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同。带参数的宏定义并不对参数进行运算,而是直接替换;内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值&a…

内联函数的意义和使用

1. 内联函数 在C中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码如下: int max(int a, int b) { return a > b ? a : b; } 为这么一个小的操作定义一个函数的好处有: ① 阅读和理解函数 max 的调用,要比读一条等价的条件表达…

内联函数和类-初阶

目录 前言 一、内联函数 二、typeid 三、范围for的使用 四、nullptr 五、类 六、class和访问限定符 总结 前言 多多重复,百炼成钢!!! 一、内联函数 用inline修饰的函数叫内联函数-在编译时C编译器会在函数的位置展开,…

内联函数——C++

内敛函数的定义: 以inline修饰的函数叫做内联函数,编译时C编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率 (它是以空间换取时间的方式提高效率,这里的空间指的…

【内联函数】inline关键字的作用与内联函数的特性

学习导航 一、内联函数产生的意义二、内联函数的使用三、内联函数的作用①简单易懂②支持调试③支持类型检查 四、内联函数的特性 一、内联函数产生的意义 在C语言中,如果我们频繁调用某些函数,并且这些函数都很代码量都很小,那么写成宏定义的…

C++之 内联函数

目录 一、 内敛函数的概念 二、 查看内联函数 三、 内联函数的特性 四、 宏和内联函数 一、 内敛函数的概念 以 inline 修饰的函数叫做内敛函数,编译时C编译器在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行…

内联函数(Inline Function )

目录 什么是内联函数(Inline Function) 如何将函数编写为内联函数(how to make function inline) 例: 为什么使用内联函数(Why to use inline function) 结论: 特殊规则 1.编译器可能不接受内联提议 …

内联函数

1.什么是内联函数 用关键字inline修饰的函数就是内联函数。关键字在函数声明和定义的时候都要加上,不写系统还是会当成常规函数 2.内联函数与一般函数的区别 1)内联含函数比一般函数在前面多一个inline修饰符 2)内联函数是直接复制“镶嵌”…

内联函数(inline)详解

为什么要有内联函数 在学习内联函数之前,大家可以写一个实现加法的宏ADD(),检测一下自己。 如果对宏等预编译知识不太熟悉的话,可以先看一下这篇文章:预编译——2.2.4 以下是一个正确的ADD宏: #define ADD(x,y) ((x…