如何在Prolog中编码因果关系(作为线性函数)

时间:2018-07-12 10:29:58

标签: prolog ontology

假设两个变量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个值(汽车的行驶距离和汽车的油耗)之间。

有什么想法吗?预先感谢!

/ JC

2 个答案:

答案 0 :(得分:3)

原谅我正在回答的事实,只是使用比注释更合适的格式,尽管这可能不是您正在寻找的答案。

除非我误解了您的问题,否则我认为您在此处描述的问题是定义不明确/描述不正确的问题。我对此的理解是,您拥有X和Y的数据集,它们恰好遵循线性关系,并且您想“推断”在没有任何其他信息的情况下X导致Y的原因,或者只是想办法描述通过谓词就是这种情况。问题在于,相关的数据集永远无法单独为您提供该信息。

我想从数据集中建立因果关系,您需要描述您要遵循的因果关系类型以及如何先断言和调查。如果您不知道事件的顺序或替代方案的行为,那么拥有一个永远无法告诉您因果关系的数据集。

我肯定有很多因果关系模型,在实践中我只遇到了两个有意义的模型:时间顺序模型和反事实模型。

时间顺序模型中,如果您能够确定事件何时发生,则可以通过非常简单的“且X在Y之前”来推断因果关系。例如。如果认为“ X =行驶”发生在“ Y =燃油量测量”之前,则可以使用谓词逻辑确定因果关系,方法是:

  • 每当旅行在燃料测量之前,该关系就总是必要是线性的
  • 在旅行之前进行燃料测量时,该关系不一定是线性的。 (因为是这样,那么您将只能建立关联而不是因果关系)
  • 存在封闭世界现象(即在没有旅行的情况下没有其他因素会导致燃料消耗)

事实模型中,您没有有关事件发生时间的任何信息,但是您所拥有的只是有关替代事件的信息。因此,“ X导致Y”的因果关系是由它的反事实建立的,即,如果您可以证明“ X没发生,Y也不会发生”(或等效地¬X表示¬Y)。

反事实模型中的一个复杂因素是它允许“责任”的概念,即,如果X和¬X都可以导致Y,那么它们都被认为是Y的潜在原因。对于数据集,您可以这样说:“如果对于所有事件X,结果都是Y,而对于所有事件¬X不一定是Y,那么我们可以推断出X导致了Y”。因此,在您的特定示例中,您可以设置一个这样的世界

    燃料消耗只能从“旅行”事件发生,或者可以由构成非旅行事件并且是互斥事件的替代假设发生,例如,说“虹吸”
  • 旅行“事件”和虹吸“事件”都会导致物理测量,例如行驶的距离。 (在我们的小例子中,虹吸事件可能只是零)。
  • 在数据集中,您可以“了解”发生了什么事件(例如旅行或虹吸)以及有关该实例的油耗和行驶距离的信息。

然后您可以通过显示以下内容,将“行驶”作为事件以相对于行进距离的线性模型方式“引起”燃油消耗:

  • 每当发生“旅行”事件时,根据您的线性模型,行进的距离确实对应于油耗
  • 每当发生“虹吸”事件时,根据该模型,行驶的距离并不一定“对应”油耗。

更新以解决此评论:问题不是推断因果关系之一,而是在假设因果关系已在实践中建立的情况下如何表示因果关系。在这种情况下,以上几点仍然适用,因为您需要更清楚地定义要表示的因果关系类型,然后才能表示出来。

例如,如果我们谈论按严格的时间顺序发生的事件,则时间因果关系可能看起来像这样(以类似于prolog的伪代码):

%%%%%%%%%%%%%%%%%%
%%% 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) )

答案 1 :(得分:2)

根据您的建议,我认为这段代码可以回答我的原始问题。谢谢!

:-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