如何在 Prolog 中编码因果关系(作为线性函数)
How to encode causal relations in Prolog (as a linear function)
假设两个变量 X 和 Y 因果线性相关,因此 X 的增加会导致 Y 的增加(例如汽车的行驶距离及其油耗)。 X 和 Y 都是 N 个观测值的向量(示例中有 N 辆汽车)。
表示这种关系的一种方法是一个简单的线性方程 Yi = a + bXi,它描述了 N 个案例样本中的关系,其中 i = 1, 2, ..., N。这里 a和 b 是常量,而 Y 和 X 是变量。
您对如何在 Prolog 中表示有任何建议吗?我的预感是这样的
causes(cause(travelDistance), effect(fuelConsumption), a(0.5), b(1.23)).
。然而,这里似乎缺少的是代码,该代码指出关联具体是在 X 的第 i 个值和 Y 的第 i 个值(汽车的行驶距离和汽车的油耗)之间。
有什么想法吗?提前致谢!
/杰西
请原谅我回答这个问题,只是为了使用比评论更合适的格式,尽管这可能不是您此时正在寻找的答案。
除非我误解了你的问题,否则我认为你在这里描述的问题是一个定义不明确/描述不当的问题。我对它的理解是,你有一个 X 和 Y 的数据集,它们恰好遵循线性关系,并且你想要 'infer' 在没有任何其他信息的情况下 X 导致 Y,或者只是有一种方法通过谓词来描述这种情况。问题是,相关数据集本身永远无法为您提供该信息。
如果您想从数据集中建立因果关系,您需要描述您所追求的因果关系类型以及如何首先断言和调查这种因果关系。如果您不知道事件的顺序或备选方案的行为方式,那么拥有一个永远无法告诉您因果关系的数据集。
我敢肯定有很多因果关系模型,我只遇到过两个在实践中有意义使用的模型:时间顺序模型和反事实模型。
在时间顺序模型中,如果你能够建立'when'一个事件发生,那么你可以通过一个非常简单的"and X comes before Y"规则推断因果关系.例如。如果 "X = travel" 被认为发生在 "Y = fuel-measurement" 之前,那么您可以使用谓词逻辑建立因果关系,方法是证明:
- 只要旅行先于燃料测量,关系总是必然线性
- 当燃料测量先于行驶时,关系是 不一定 线性的。 (因为如果是的话,那么你就只能建立相关性而不是因果关系了)
- 封闭世界现象适用(即在没有旅行的情况下没有其他因素会增加燃料消耗)
在反事实模型中,您没有关于事件年表的任何信息,但您拥有的是关于替代事件的信息。因此 "X causes Y" 的因果关系是由它的反事实建立的,即如果你能证明 "Had X not happened, Y would not have happened either" (或等价地 ¬X 暗示 ¬Y)。
反事实模型中的一个复杂因素是它允许 'responsibility' 的概念,即如果 X 和 ¬X 都能导致 Y,那么它们都被认为是 Y 的潜在原因。然而,在数据集的上下文中,您可能可以通过说 "if for ALL events X, the outcome is Y, whereas it is not necessarily true that for ALL events ¬X the outcome is Y, then we can infer that X causes Y" 来解决这个问题。因此,在您的具体示例中,您可以建立一个这样的世界
- 燃料消耗要么只发生在 'travel' 事件中,要么是构成非旅行事件的替代假设,并且是相互排斥的事件,例如比如说,'siphoning'
- 行程 'event' 和虹吸 'event' 都会导致物理测量,例如行驶的距离。 (在我们的简单示例中,虹吸事件可能仅为零)。
- 在您的数据集中,您有关于'both'发生了什么事件(例如旅行或虹吸)的信息和关于该实例的油耗和行驶距离的信息。
然后,您可以确定 'travelling' 作为一个事件 'causes' 燃料消耗,以相对于行驶距离的线性模型方式显示:
- 每当你有一个 'travel' 事件时,根据你的线性模型,行驶的距离确实对应于燃料消耗
- 每当您遇到 'siphoning' 事件时,根据该模型,行驶的距离 'necessarily' 与油耗不对应。
更新以解决评论:问题不是推断因果关系,而是如何在因果关系已在实践中建立的假设下表示因果关系。在这种情况下,以上几点仍然适用,因为您需要更清楚地定义您所指的是哪种类型的因果关系,然后才能表示它。
例如,如果我们讨论的是严格按照时间顺序发生的事件,那么时间因果关系可能看起来像这样(在类似序言的伪代码中):
%%%%%%%%%%%%%%%%%%
%%% facts database
%%%%%%%%%%%%%%%%%%
% eventtype/1: defines type of event
eventtype('travel')
eventtype('fuel_measurement') % ... etc
% eventtime/2: defines timepoints by index and a record of actual time
eventtime(1, "12:02am")
eventtime(2, "12:03am") % ... etc
% event/3: ['event type', 'time', 'related measurement']
event( [eventtype('travel'), eventtime(1, _), 50km] )
event( [eventtype('fuel-measurement'), eventtime(2, _), 5L ] ) % ... etc
%%%%%%%%%%%%%
%%% relations
%%%%%%%%%%%%%
immediately_precedes( event(X), event(Y) ) :-
get_eventtime_index(X, Xind),
get_eventtime_index(Y, Yind),
plus_one(Xind, Yind). % assumes all above helper predicates are suitably defined elsewhere
is_linearly_related( event(X), event(Y) ) :-
get_measurement(X, Xmeas),
get_measurement(Y, Ymeas),
Model is a + b * Xmeas,
Ymeas = Model.
iscausal( eventtype(Xtype), eventtype(Ytype) ) :- % expressed as pseudocode
forall:
[event(X), event(Y)],
X = [Xtype, Xtime, Xmeas],
Y = [Ytype, Ytime, Ymeas],
immediately_precedes( event(X), event(Y) )
it applies that:
is_linearly_related( event(X), event(Y) )
根据您的建议,我认为这段代码回答了我原来的问题。谢谢!
:-use_module(library(clpfd)).
causes(
var(
name(distance),
value(Distance)
),
var(
name(fuelConsumption),
value(FuelConsumption)
)
)
:-
FuelConsumption #= 5 + 2 * Distance.
以及示例查询:
?-causes(var(name(N), value(V)), var(name(fuelConsumption), value(3))).
产生 N = distance,V = -1
假设两个变量 X 和 Y 因果线性相关,因此 X 的增加会导致 Y 的增加(例如汽车的行驶距离及其油耗)。 X 和 Y 都是 N 个观测值的向量(示例中有 N 辆汽车)。
表示这种关系的一种方法是一个简单的线性方程 Yi = a + bXi,它描述了 N 个案例样本中的关系,其中 i = 1, 2, ..., N。这里 a和 b 是常量,而 Y 和 X 是变量。
您对如何在 Prolog 中表示有任何建议吗?我的预感是这样的
causes(cause(travelDistance), effect(fuelConsumption), a(0.5), b(1.23)).
。然而,这里似乎缺少的是代码,该代码指出关联具体是在 X 的第 i 个值和 Y 的第 i 个值(汽车的行驶距离和汽车的油耗)之间。
有什么想法吗?提前致谢!
/杰西
请原谅我回答这个问题,只是为了使用比评论更合适的格式,尽管这可能不是您此时正在寻找的答案。
除非我误解了你的问题,否则我认为你在这里描述的问题是一个定义不明确/描述不当的问题。我对它的理解是,你有一个 X 和 Y 的数据集,它们恰好遵循线性关系,并且你想要 'infer' 在没有任何其他信息的情况下 X 导致 Y,或者只是有一种方法通过谓词来描述这种情况。问题是,相关数据集本身永远无法为您提供该信息。
如果您想从数据集中建立因果关系,您需要描述您所追求的因果关系类型以及如何首先断言和调查这种因果关系。如果您不知道事件的顺序或备选方案的行为方式,那么拥有一个永远无法告诉您因果关系的数据集。
我敢肯定有很多因果关系模型,我只遇到过两个在实践中有意义使用的模型:时间顺序模型和反事实模型。
在时间顺序模型中,如果你能够建立'when'一个事件发生,那么你可以通过一个非常简单的"and X comes before Y"规则推断因果关系.例如。如果 "X = travel" 被认为发生在 "Y = fuel-measurement" 之前,那么您可以使用谓词逻辑建立因果关系,方法是证明:
- 只要旅行先于燃料测量,关系总是必然线性
- 当燃料测量先于行驶时,关系是 不一定 线性的。 (因为如果是的话,那么你就只能建立相关性而不是因果关系了)
- 封闭世界现象适用(即在没有旅行的情况下没有其他因素会增加燃料消耗)
在反事实模型中,您没有关于事件年表的任何信息,但您拥有的是关于替代事件的信息。因此 "X causes Y" 的因果关系是由它的反事实建立的,即如果你能证明 "Had X not happened, Y would not have happened either" (或等价地 ¬X 暗示 ¬Y)。
反事实模型中的一个复杂因素是它允许 'responsibility' 的概念,即如果 X 和 ¬X 都能导致 Y,那么它们都被认为是 Y 的潜在原因。然而,在数据集的上下文中,您可能可以通过说 "if for ALL events X, the outcome is Y, whereas it is not necessarily true that for ALL events ¬X the outcome is Y, then we can infer that X causes Y" 来解决这个问题。因此,在您的具体示例中,您可以建立一个这样的世界
- 燃料消耗要么只发生在 'travel' 事件中,要么是构成非旅行事件的替代假设,并且是相互排斥的事件,例如比如说,'siphoning'
- 行程 'event' 和虹吸 'event' 都会导致物理测量,例如行驶的距离。 (在我们的简单示例中,虹吸事件可能仅为零)。
- 在您的数据集中,您有关于'both'发生了什么事件(例如旅行或虹吸)的信息和关于该实例的油耗和行驶距离的信息。
然后,您可以确定 'travelling' 作为一个事件 'causes' 燃料消耗,以相对于行驶距离的线性模型方式显示:
- 每当你有一个 'travel' 事件时,根据你的线性模型,行驶的距离确实对应于燃料消耗
- 每当您遇到 'siphoning' 事件时,根据该模型,行驶的距离 'necessarily' 与油耗不对应。
更新以解决评论:问题不是推断因果关系,而是如何在因果关系已在实践中建立的假设下表示因果关系。在这种情况下,以上几点仍然适用,因为您需要更清楚地定义您所指的是哪种类型的因果关系,然后才能表示它。
例如,如果我们讨论的是严格按照时间顺序发生的事件,那么时间因果关系可能看起来像这样(在类似序言的伪代码中):
%%%%%%%%%%%%%%%%%%
%%% facts database
%%%%%%%%%%%%%%%%%%
% eventtype/1: defines type of event
eventtype('travel')
eventtype('fuel_measurement') % ... etc
% eventtime/2: defines timepoints by index and a record of actual time
eventtime(1, "12:02am")
eventtime(2, "12:03am") % ... etc
% event/3: ['event type', 'time', 'related measurement']
event( [eventtype('travel'), eventtime(1, _), 50km] )
event( [eventtype('fuel-measurement'), eventtime(2, _), 5L ] ) % ... etc
%%%%%%%%%%%%%
%%% relations
%%%%%%%%%%%%%
immediately_precedes( event(X), event(Y) ) :-
get_eventtime_index(X, Xind),
get_eventtime_index(Y, Yind),
plus_one(Xind, Yind). % assumes all above helper predicates are suitably defined elsewhere
is_linearly_related( event(X), event(Y) ) :-
get_measurement(X, Xmeas),
get_measurement(Y, Ymeas),
Model is a + b * Xmeas,
Ymeas = Model.
iscausal( eventtype(Xtype), eventtype(Ytype) ) :- % expressed as pseudocode
forall:
[event(X), event(Y)],
X = [Xtype, Xtime, Xmeas],
Y = [Ytype, Ytime, Ymeas],
immediately_precedes( event(X), event(Y) )
it applies that:
is_linearly_related( event(X), event(Y) )
根据您的建议,我认为这段代码回答了我原来的问题。谢谢!
:-use_module(library(clpfd)).
causes(
var(
name(distance),
value(Distance)
),
var(
name(fuelConsumption),
value(FuelConsumption)
)
)
:-
FuelConsumption #= 5 + 2 * Distance.
以及示例查询:
?-causes(var(name(N), value(V)), var(name(fuelConsumption), value(3))).
产生 N = distance,V = -1