Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R Delphi中对数似然函数的实现_R_Delphi - Fatal编程技术网

R Delphi中对数似然函数的实现

R Delphi中对数似然函数的实现,r,delphi,R,Delphi,我试图计算文本中成对单词出现的对数似然分数,并且在我的Delphi实现中得到了相同的异常结果,这是我从在线找到的Java和Python源代码中得到的。泰德·邓宁(Ted Dunning)于1993年在该资料来源上发表了一篇文章,给出了一对特定对象的结果: K11(AB,ie接头频率)=110 K12(A字附近没有B)=2442 K21(B,无附近A)=111 K22(文本中除A或B以外的字数)=29114 并给出了270.72的期望结果 Dunning还提供了R at中的一个实现 计算对数

我试图计算文本中成对单词出现的对数似然分数,并且在我的Delphi实现中得到了相同的异常结果,这是我从在线找到的Java和Python源代码中得到的。泰德·邓宁(Ted Dunning)于1993年在该资料来源上发表了一篇文章,给出了一对特定对象的结果:

  • K11(AB,ie接头频率)=110
  • K12(A字附近没有B)=2442
  • K21(B,无附近A)=111
  • K22(文本中除A或B以外的字数)=29114
并给出了270.72的期望结果

Dunning还提供了R at中的一个实现

计算对数似然比分数(也称为G2)非常重要 简单,
LLR=2和(k)(H(k)-H(行和(k))-H(列和(k)))

其中H是香农熵,计算为
(k_ij/sum(k))log(k_ij/sum(k))
之和。在R中,此函数定义为
H=function(k){N=sum(k);return(sum(k/N*log(k/N+(k==0)))}

但我不知道R,也不确定如何将其翻译成Pascal

我的翻译尝试包括这些功能

function LnOK(x : integer): extended;
begin
  if x<=0 then Result :=0
  else Result := Ln(x);
end;

function Entropy2(a, b: Integer): extended;
begin
  Result := LnOK(a + b) - LnOK(a) - LnOK(b);
end;

function Entropy4(a, b, c, d: Integer): extended;
begin
  Result := LnOK(a + b + c + d) - LnOK(a) - LnOK(b) - LnOK(c) - LnOK(d);
end;

function Log_likelihood_from_Java(f1, f2, joint, total_tokens: Integer): 
  single;
var
  k11, k12, k21, k22: Integer;
  matrixEntropy, rowEntropy, colEntropy: extended;
begin
  k11 := joint;
  k12 := f2 - joint;
  k21 := f1 - joint;
  k22 := total_tokens - f1 - f2 + joint;
  rowEntropy := Entropy2(k11 + k12, k21 + k22);
  colEntropy := Entropy2(k11 + k21, k12 + k22);
  matrixEntropy := Entropy4(k11, k12, k21, k22);
  if (rowEntropy + colEntropy < matrixEntropy) then
    Result := 0.0 // round off error
  else
   Result := 2.0 * (rowEntropy + colEntropy - matrixEntropy);
end;

感谢您的帮助!

我无法理解您编写的代码与您链接的R代码没有明显关系。我没有试图调和这些差异

这是R代码的直译。我相信你会同意,用这种方式编写的算法要简单得多

{$APPTYPE CONSOLE}

uses
  SysUtils, Math;

type
  TVector2 = array [1..2] of Double;
  TMatrix2 = array [1..2] of TVector2;

function rowSums(const M: TMatrix2): TVector2;
begin
  Result[1] := M[1,1] + M[1,2];
  Result[2] := M[2,1] + M[2,2];
end;

function colSums(const M: TMatrix2): TVector2;
begin
  Result[1] := M[1,1] + M[2,1];
  Result[2] := M[1,2] + M[2,2];
end;

function H(const k: array of Double): Double;
var
  i: Integer;
  N, kOverN: Double;
begin
  N := Sum(k);
  Result := 0.0;
  for i := low(k) to high(k) do begin
    kOverN := k[i]/N;
    if kOverN>0.0 then begin
      Result := Result + kOverN*Ln(kOverN);
    end;
  end;
end;

function LLR(const M: TMatrix2): Double;
var
  k: array [1..4] of Double absolute M; // this is a little sneaky I admit
  rs, cs: TVector2;
begin
  rs := rowSums(M);
  cs := colSums(M);
  Result := 2.0*Sum(k)*(H(k) - H(rs) - H(cs));
end;

var
  M: TMatrix2;

begin
  M[1,1] := 110;
  M[1,2] := 2442;
  M[2,1] := 111;
  M[2,2] := 29114;
  Writeln(LLR(M));
end.
输出

2.70721876936232E+0002 2.70721876936232E+0002
我在翻译
LnOk
函数时发现了问题,应该如下所示:

function LnOK(x: Integer): Extended;
begin
  if x = 0 then
    Result := 0
  else
    Result := x * Ln(x);
end;

离题

如果允许的话,作为补充说明,为了改进编码风格,您可能更喜欢重载
Entropy
函数,而不是使用不同的名称调用它们:

function Entropy(a, b: Integer): Extended; overload;
begin
  Result := LnOK(a + b) - LnOK(a) - LnOK(b);
end;

function Entropy(a, b, c, d: Integer): Extended; overload;
begin
  Result := LnOK(a + b + c + d) - LnOK(a) - LnOK(b) - LnOK(c) - LnOK(d);
end;

真正奇怪的是,你的代码与你链接到的R代码没有明显的联系。@DavidHeffernan这似乎是从Java@Fantagirocco移植过来的。似乎询问者选择了一个糟糕且不清楚的实现,因为他理解Java而不是R。但R代码中的算法更清晰。@MikeScott LnOK暗示了一个专业的人如果Ln以特定方式处理域外情况,则为受保护的实现。但此函数不这样做。是的,它选择x=0,但忽略x
function Entropy(a, b: Integer): Extended; overload;
begin
  Result := LnOK(a + b) - LnOK(a) - LnOK(b);
end;

function Entropy(a, b, c, d: Integer): Extended; overload;
begin
  Result := LnOK(a + b + c + d) - LnOK(a) - LnOK(b) - LnOK(c) - LnOK(d);
end;