X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=GikoBayesian.pas;h=55791a3cdd0f6240ae9b5af5abeee66ded838ded;hb=refs%2Fheads%2FBb62;hp=96646b1f96147c334727618d21a553e1824ce7bc;hpb=d43438e666d8bfae26136c61193b9725a8cf79ae;p=gikonavigoeson%2Fgikonavi.git diff --git a/GikoBayesian.pas b/GikoBayesian.pas index 96646b1..55791a3 100644 --- a/GikoBayesian.pas +++ b/GikoBayesian.pas @@ -4,9 +4,13 @@ unit GikoBayesian; \file GikoBayesian.pas \brief ƒxƒCƒWƒAƒ“ƒtƒBƒ‹ƒ^ -$Id: GikoBayesian.pas,v 1.8 2004/10/21 05:59:39 yoffy Exp $ + +$Id: GikoBayesian.pas,v 1.22 2009/01/31 15:47:15 h677 Exp $ } +//! •½‰¼–¼‚ðŽ«‘‚ÉŠÜ‚ß‚È‚¢ +{$DEFINE GIKO_BAYESIAN_NO_HIRAGANA_DIC} + interface //================================================== @@ -60,7 +64,7 @@ type \brief ƒtƒBƒ‹ƒ^ƒAƒ‹ƒSƒŠƒYƒ€ ************************************************************} TGikoBayesianAlgorithm = - (gbaPaulGraham, gbaGaryRonbinson{, gbaGaryRonbinsonFisher}); + (gbaPaulGraham, gbaGaryRobinson, gbaGaryRobinsonFisher); {!*********************************************************** \brief ƒxƒCƒWƒAƒ“ƒtƒBƒ‹ƒ^ @@ -106,7 +110,11 @@ type } function CalcGaryRobinson( wordCount : TWordCount ) : Extended; -// function CalcGaryRobinsonFisher( wordCount : TWordCount ) : Extended; + {! + \brief GaryRobinson-Fisher –@‚ÉŠî‚¢‚Ä•¶Í‚Ì’–Ú“x‚ðŒˆ’è‚µ‚Ü‚· + \return •¶Í‚Ì’–Ú“x (’–Ú‚É’l‚µ‚È‚¢ 0.0`1.0 ’–Ú‚·‚ׂ«) + } + function CalcGaryRobinsonFisher( wordCount : TWordCount ) : Extended; {! \brief •¶Í‚ð‰ðÍ @@ -120,7 +128,7 @@ type function Parse( const text : string; wordCount : TWordCount; - algorithm : TGikoBayesianAlgorithm = gbaGaryRonbinson + algorithm : TGikoBayesianAlgorithm = gbaGaryRobinsonFisher ) : Extended; {! @@ -156,7 +164,8 @@ implementation //================================================== uses - SysUtils, Math, Windows; + SysUtils, Math, Windows, + MojuUtils; const GIKO_BAYESIAN_FILE_VERSION = '1.0'; @@ -301,12 +310,12 @@ begin for i := 1 to sl.Count - 1 do begin s := sl[ i ]; - name := RemoveToken( s, #1 ); + name := GikoBayesian.RemoveToken( s, #1 ); info := TWordInfo.Create; - info.NormalWord := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 ); - info.ImportantWord := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 ); - info.NormalText := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 ); - info.ImportantText := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 ); + info.NormalWord := StrToIntDef( '$' + GikoBayesian.RemoveToken( s, #1 ), 0 ); + info.ImportantWord := StrToIntDef( '$' + GikoBayesian.RemoveToken( s, #1 ), 0 ); + info.NormalText := StrToIntDef( '$' + GikoBayesian.RemoveToken( s, #1 ), 0 ); + info.ImportantText := StrToIntDef( '$' + GikoBayesian.RemoveToken( s, #1 ), 0 ); AddObject( name, info ); end; @@ -365,11 +374,10 @@ var idx : Integer; begin - idx := IndexOf( name ); // Œƒ’x - if idx < 0 then - Result := nil + if Find( name, idx ) then + Result := TWordInfo( inherited Objects[ idx ] ) else - Result := TWordInfo( inherited Objects[ idx ] ); + Result := nil; end; @@ -381,11 +389,10 @@ var idx : Integer; begin - idx := IndexOf( name ); - if idx < 0 then - AddObject( name, value ) + if Find( name, idx ) then + inherited Objects[ idx ] := value else - inherited Objects[ idx ] := value; + AddObject( name, value ); end; @@ -397,35 +404,208 @@ procedure TGikoBayesian.CountWord( const text : string; wordCount : TWordCount ); type - Modes = (ModeWhite, ModeGraph, ModeAlpha, ModeHanKana, ModeNum, + Modes = (ModeWhite, ModeGraph, ModeAlpha, ModeNum, ModeHanKana, ModeWGraph, ModeWAlpha, ModeWNum, ModeWHira, ModeWKata, ModeWKanji); var - p, tail, last : PChar; - mode, newMode : Modes; - aWord : string; - ch : Longword; - chSize : Integer; - delimiter : TStringList; - delimited : Boolean; - i, idx : Integer; - countInfo : TWordCountInfo; + p, tail, last : PChar; + mode, newMode : Modes; + ch : Longword; + chSize : Integer; + wHiraDelimiter : TStringList; + wHiraFinalDelimiter : TStringList; + wKanjiDelimiter : TStringList; + words : TStringList; + aWord : string; +// countInfo : TWordCountInfo; + + function cutBoth( _aWord : string; _delim : TStringList ) : string; + var + _i : Integer; + begin + for _i := 0 to _delim.Count - 1 do begin + _aWord := CustomStringReplace( + _aWord, + _delim[ _i ], + #10 + _delim[ _i ] + #10, False ); + end; + Result := _aWord; + end; + + function cutFirst( _aWord : string; _delim : TStringList ) : string; + var + _i : Integer; + begin + for _i := 0 to _delim.Count - 1 do begin + _aWord := CustomStringReplace( + _aWord, + _delim[ _i ], + #10 + _delim[ _i ], False ); + end; + Result := _aWord; + end; + + function cutFinal( _aWord : string; _delim : TStringList ) : string; + var + _i : Integer; + begin + for _i := 0 to _delim.Count - 1 do begin + _aWord := CustomStringReplace( + _aWord, + _delim[ _i ], + _delim[ _i ] + #10, False ); + end; + Result := _aWord; + end; + + procedure addWord( _dst : TWordCount; _words : TStringList ); + var + _aWord : string; + _i, _idx : Integer; + _countInfo : TWordCountInfo; + begin + for _i := 0 to _words.Count - 1 do begin + _aWord := _words[ _i ]; + if Length( _aWord ) > 0 then begin + if _dst.Find( _aWord, _idx ) then begin + _countInfo := TWordCountInfo( _dst.Objects[ _idx ] ); + end else begin + _countInfo := TWordCountInfo.Create; + _dst.AddObject( _aWord, _countInfo ); + end; + _countInfo.WordCount := _countInfo.WordCount + 1; + end; + end; + end; + + function changeMode( _aWord : string; _mode : Modes ) : string; + var + _i : Integer; + _aWord2 : string; + _pWord, _pWord2 : PChar; + _pWordTail, _pFound : PChar; + const + _delim : string = #10; + begin +{$IFDEF GIKO_BAYESIAN_NO_HIRAGANA_DIC} + if mode = ModeWHira then begin + Result := ''; + Exit; + end; +{$ENDIF} + if Ord( _mode ) >= Ord( ModeWGraph ) then begin + // “ú–{Œê + // ƒXƒy[ƒX‚ð‹l‚ß‚é + _aWord := CustomStringReplace( _aWord, ' ', '', False ); + _aWord := CustomStringReplace( _aWord, '@', '', False ); + + // ƒfƒŠƒ~ƒ^‚Å’PŒê•ª‚¯ + case mode of + ModeWHira: + begin + _aWord := cutFinal( _aWord, wHiraFinalDelimiter ); + Result := cutBoth( _aWord, wHiraDelimiter ); + end; + + ModeWKanji: + begin + // ƒfƒŠƒ~ƒ^‚Å’PŒê•ª‚¯ + _aWord := cutBoth( _aWord, wKanjiDelimiter ); + // 4 byte (2 Žš) ‚¸‚‚ŒPŒê•ª‚¯ + _pWord := PChar( _aWord ); + _i := Length( _aWord ); + _pWordTail := _pWord + _i; + SetLength( _aWord2, _i + (_i shr 2) ); + _pWord2 := PChar( _aWord2 ); + + while _pWord < _pWordTail do begin + _pFound := AnsiStrPos( _pWord, PChar( _delim ) ); + if _pFound = nil then + _pFound := _pWordTail; + _pFound := _pFound - 3; + + while _pWord <= _pFound do begin + CopyMemory( _pWord2, _pWord, 4 ); _pWord2[ 4 ] := #10; + _pWord2 := _pWord2 + 5; _pWord := _pWord + 4; + end; + _i := _pFound + 4 - _pWord; // 4 = 3 + #10 + CopyMemory( _pWord2, _pWord, _i ); + _pWord2 := _pWord2 + _i; _pWord := _pWord + _i; + end; + if _pWord < _pWordTail then begin + _i := _pWordTail - _pWord; + CopyMemory( _pWord2, _pWord, _i ); + _pWord2 := _pWord2 + _i; + end; + SetLength( _aWord2, _pWord2 - PChar( _aWord2 ) ); + + Result := _aWord2; + end; + + else + Result := _aWord; + end; + end else begin + Result := _aWord; + end; + end; const - KAKUJOSI = '‚ð' + #10 + '‚É' + #10 + '‚ª' + #10 + '‚Æ' + #10 + '‚©‚ç' + - #10 + '‚Å' + #10 + '‚Ö' + #10 + '‚æ‚è' + #10 + '‚Ü‚Å'; + WHIRA_DELIMITER = '‚ð' + #10 + '‚É' + #10 + '‚ª' + #10 + '‚Æ' + #10 + '‚©‚ç' + + #10 + '‚Ö' + #10 + '‚æ‚è' + #10 + '‚Ü‚Å'+ #10 + '‚Å' + + #10 + '‚±‚±' + #10 + '‚»‚±' + #10 + '‚Ç‚±' + + #10 + '‚±‚ê' + #10 + '‚»‚ê' + #10 + '‚ ‚ê' + #10 + '‚Ç‚ê' + + #10 + '‚±‚Ì' + #10 + '‚»‚Ì' + #10 + '‚ ‚Ì' + #10 + '‚Ç‚Ì' + + #10 + '‚±‚¤' + #10 + '‚»‚¤' + #10 + '‚ ‚ ' + #10 + '‚Ç‚¤' + + #10 + '‚±‚ñ‚È' + #10 + '‚»‚ñ‚È' + #10 + '‚ ‚ñ‚È' + #10 + '‚Ç‚ñ‚È' + + #10 + '‚ꂽ' + #10 + '‚ê‚Ä' + #10 + '‚ê‚ê' + #10 + '‚ê‚ë' + + #10 + '‚ê‚é' + #10 + '‚ç‚ê‚é' + + #10 + '‚Å‚·' + #10 + '‚Ü‚·' + #10 + '‚Ü‚¹‚ñ' + + #10 + '‚Å‚µ‚½' + #10 + '‚Ü‚µ‚½' + + #10 + '‚·‚é' + #10 + '‚µ‚È‚¢' + #10 + '‚³‚ê‚é' + #10 + '‚³‚ê‚È‚¢' + ; + WKANJI_DELIMITER = '“I' + #10 + '«' + #10 + 'Ž®' + #10 + '‰»' + #10 + '–@' + + #10 + '•s' + #10 + '–³' + #10 + '”ñ' + #10 + '”½' + ; + WHIRA_FINAL_DELIMITER = '‚Á‚½' + #10 + '‚Á‚Ä' + ;{ + + #10 + '‚æ‚Á‚Ä' + #10 + '‚µ‚½‚ª‚Á‚Ä' + #10 + '‚È‚Ì‚Å' + + #10 + '‚¾‚©‚ç' + #10 + '‚Å‚·‚©‚ç' + + #10 + '‚Ü‚½' + + #10 + '‚µ‚©‚µ' + #10 + '‚¾‚ª' + #10 + '‚¯‚Ç' + #10 + '‚¯‚ê‚Ç' + + #10 + '‚â‚Í‚è' + #10 + '‚â‚Á‚Ï‚è' + + #10 + '‚Å‚µ' + #10 + '‚¾‚ë' + + #10 + '‚·‚é' + #10 + '‚µ‚È‚¢' + #10 + '‚µ‚½' + #10 + '‚µ‚È‚¢' + ;} + // '[' ‚ð '‚Ÿ‚¡‚£‚¥‚§' ‚ɁB + HA_LINE = '‚ ‚©‚³‚½‚È‚Í‚Ü‚â‚ç‚킪‚´‚¾‚΂ςŸ‚ì'; + HI_LINE = '‚¢‚«‚µ‚¿‚ɂЂ݂è‚‚¶‚Ñ‚Ò‚¡'; + HU_LINE = '‚¤‚­‚·‚‚ʂӂނä‚é‚®‚Ô‚Õ‚£'; + HE_LINE = '‚¦‚¯‚¹‚Ä‚Ë‚Ö‚ß‚ê‚ï‚°‚ׂ؂¥'; + HO_LINE = '‚¨‚±‚»‚Æ‚Ì‚Ù‚à‚æ‚ë‚ð‚²‚Ú‚Û‚§'; + KA_LINE = 'ƒAƒJƒTƒ^ƒiƒnƒ}ƒ„ƒ‰ƒƒKƒUƒ_ƒoƒpƒ@ƒ•ƒŽ'; + KI_LINE = 'ƒCƒLƒVƒ`ƒjƒqƒ~ƒŠƒƒMƒWƒrƒsƒB'; + KU_LINE = 'ƒEƒNƒXƒcƒkƒtƒ€ƒ†ƒ‹ƒOƒuƒvƒDƒ”'; + KE_LINE = 'ƒGƒPƒZƒeƒlƒwƒƒŒƒ‘ƒQƒxƒyƒFƒ–'; + KO_LINE = 'ƒIƒRƒ\ƒgƒmƒzƒ‚ƒˆƒƒ’ƒSƒ{ƒ|ƒH'; kKanji = [$80..$A0, $E0..$ff]; begin - delimiter := TStringList.Create; + wHiraDelimiter := TStringList.Create; + wHiraFinalDelimiter := TStringList.Create; + wKanjiDelimiter := TStringList.Create; + words := TStringList.Create; try mode := ModeWhite; - delimiter.Text := KAKUJOSI; +{$IFNDEF GIKO_BAYESIAN_NO_HIRAGANA_DIC} + wHiraDelimiter.Text := WHIRA_DELIMITER; + wHiraFinalDelimiter.Text := WHIRA_FINAL_DELIMITER; +{$ENDIF} + wKanjiDelimiter.Text := WKANJI_DELIMITER; p := PChar( text ); tail := p + Length( text ); last := p; while p < tail do begin - delimited := False; // •¶Žš‚̃^ƒCƒv‚ð”»•Ê // ¦‹å“Ç“_‚Í ModeGraph ‚É‚È‚é‚̂Ō•ʂɑΉž‚µ‚È‚­‚Ä‚à‚¢‚¢ // if Byte(Byte( p^ ) - $a1) < $5e then begin @@ -433,7 +613,8 @@ begin if p + 1 < tail then begin ch := (PByte( p )^ shl 8) or PByte( p + 1 )^; case ch of - $8140: newMode := ModeWhite; + // ƒXƒy[ƒX‚Å’PŒê•ª‚¯‚¹‚¸‚É‹l‚ß‚é + //$8140: newMode := ModeWhite; $8141..$824e: newMode := ModeWGraph; $824f..$8258: newMode := ModeWNum; $8260..$829a: newMode := ModeWAlpha; @@ -450,40 +631,29 @@ begin end; chSize := 2; - - // ‹æØ‚è‚ɂȂ镶Žš‚ª‚ ‚é‚©ŒŸ¸‚·‚é - if p + 3 < tail then begin // 3 = delimiter ‚̍ő厚” - 1 - for i := 0 to delimiter.Count - 1 do begin - if CompareMem( - p, PChar( delimiter[ i ] ), Length( delimiter[ i ] ) ) then begin - delimited := True; - chSize := Length( delimiter[ i ] ); - Break; - end; - end; - end; end else begin newMode := Modes( CharMode1[ Byte( p^ ) ] ); + if (p^ = ' ') and (Ord( mode ) >= Ord( ModeWGraph )) then begin + // ¡‚Ü‚Å“ú–{Œê‚ō¡ƒXƒy[ƒX + // ’PŒê‚ðŒq‚°‚ÄŒã‚ŃXƒy[ƒX‚ð‹l‚ß‚é + // ¦”¼ŠpƒJƒi‚͒ʏíƒXƒy[ƒX‚Å‹æØ‚邾‚낤‚©‚ç‹l‚ß‚È‚¢ + newMode := mode; + end; chSize := 1; end; - if (mode <> newMode) or delimited then begin + if mode <> newMode then begin // •¶Žš‚̃^ƒCƒv‚ª•ÏX‚³‚ꂽ - // ‚à‚µ‚­‚Í‹æØ‚è‚ɂȂ镶Žš‚É‘˜‹ö‚µ‚½ if mode <> ModeWhite then begin SetLength( aWord, p - last ); CopyMemory( PChar( aWord ), last, p - last ); - //aWord := Copy( last, 0, p - last ); - idx := wordCount.IndexOf( aWord ); // ’x - if idx < 0 then begin - countInfo := TWordCountInfo.Create; - wordCount.AddObject( aWord, countInfo ); - end else begin - countInfo := TWordCountInfo( wordCount.Objects[ idx ] ); - end; - countInfo.WordCount := countInfo.WordCount + 1; + + words.Text := changeMode( aWord, mode ); + + // ’PŒê“o˜^ + addWord( wordCount, words ); end; last := p; @@ -495,18 +665,19 @@ begin end; // while if mode <> ModeWhite then begin - aWord := Copy( last, 0, p - last ); - idx := wordCount.IndexOf( aWord ); - if idx < 0 then begin - countInfo := TWordCountInfo.Create; - wordCount.AddObject( aWord, countInfo ); - end else begin - countInfo := TWordCountInfo( wordCount.Objects[ idx ] ); - end; - countInfo.WordCount := countInfo.WordCount + 1; + SetLength( aWord, p - last ); + CopyMemory( PChar( aWord ), last, p - last ); + + words.Text := changeMode( aWord, mode ); + + // ’PŒê“o˜^ + addWord( wordCount, words ); end; finally - delimiter.Free; + words.Free; + wKanjiDelimiter.Free; + wHiraFinalDelimiter.Free; + wHiraDelimiter.Free; end; end; @@ -522,15 +693,22 @@ function TGikoBayesian.CalcPaulGraham( wordCount : TWordCount ) : Extended; begin info := Objects[ aWord ]; if info = nil then - Result := 0.4 + Result := 0.415 else if info.NormalWord = 0 then Result := 0.99 else if info.ImportantWord = 0 then Result := 0.01 - else - Result := ( info.ImportantWord / info.ImportantText ) / - ((info.NormalWord * 2 / info.NormalText ) + - (info.ImportantWord / info.ImportantText)); + else if info.ImportantWord + info.NormalWord * 2 < 5 then + Result := 0.5 + else begin + try + Result := ( info.ImportantWord / info.ImportantText ) / + ((info.NormalWord * 2 / info.NormalText ) + + (info.ImportantWord / info.ImportantText)); + except + on EZeroDivide do Result := 0.99; + end; + end; end; var @@ -558,11 +736,15 @@ begin i := min( SAMPLE_COUNT, narray.Count ); while i > 0 do begin Dec( i ); + s := s * Single( narray[ i ] ); q := q * (1 - Single( narray[ i ] )); end; - - Result := s / (s + q); + try + Result := s / (s + q); + except + Result := 0.5; + end; finally narray.Free; end; @@ -582,18 +764,27 @@ function TGikoBayesian.CalcGaryRobinson( wordCount : TWordCount ) : Extended; if info = nil then Result := 0.415 else if info.ImportantWord = 0 then - Result := 0.0001 + Result := 0.01 else if info.NormalWord = 0 then - Result := 0.9999 + Result := 0.99 else + { Result := ( info.ImportantWord / info.ImportantText ) / ((info.NormalWord / info.NormalText ) + (info.ImportantWord / info.ImportantText)); + } + try + Result := (info.ImportantWord * info.NormalText) / + (info.NormalWord * info.ImportantText + + info.ImportantWord * info.NormalText); + except + Result := 0.5; + end; end; function f( cnt : Integer; n, mean : Single ) : Extended; const - k = 0.00001; + k = 0.001; begin Result := ( (k * mean) + (cnt * n) ) / (k + cnt); end; @@ -604,8 +795,7 @@ var mean : Extended; countInfo : TWordCountInfo; i : Integer; - normal : Extended; - important : Extended; + P1, Q1{, R1} : Extended; cnt : Extended; begin @@ -623,24 +813,128 @@ begin end; mean := mean / wordCount.Count; - cnt := 0; - normal := 1; - important := 1; + P1 := 1; + Q1 := 1; for i := 0 to wordCount.Count - 1 do begin countInfo := TWordCountInfo( wordCount.Objects[ i ] ); n := f( countInfo.WordCount, narray[ i ], mean ); - normal := normal * n; - important := important * (1 - n); - if countInfo <> nil then - cnt := cnt + countInfo.WordCount; + P1 := P1 * ( 1 - n ); + Q1 := Q1 * n; end; + cnt := wordCount.Count; if cnt = 0 then cnt := 1; - normal := 1 - Exp( Ln( normal ) * (1 / cnt) ); - important := 1 - Exp( Ln( important ) * (1 / cnt) ); + try + P1 := 1 - Power( P1, 1 / cnt ); + except + end; + try + Q1 := 1 - Power( Q1, 1 / cnt ); + except + end; + + if P1 + Q1 = 0 then begin + Result := 0.5 + end else begin + n := (P1 - Q1) / (P1 + Q1); + Result := (1 + n) / 2; + end; + +end; + +//============================== +// CalcGaryRobinsonFisher +//============================== +function TGikoBayesian.CalcGaryRobinsonFisher( + wordCount : TWordCount +) : Extended; + + function p( const aWord : string ) : Single; + var + info : TWordInfo; + begin + info := Objects[ aWord ]; + if info = nil then + Result := 0.415 + else if info.ImportantWord = 0 then + Result := 0.01 + else if info.NormalWord = 0 then + Result := 0.99 + else + { + Result := ( info.ImportantWord / info.ImportantText ) / + ((info.NormalWord / info.NormalText ) + + (info.ImportantWord / info.ImportantText)); + } + Result := (info.ImportantWord * info.NormalText) / + (info.NormalWord * info.ImportantText + + info.ImportantWord * info.NormalText); + end; + + function f( cnt : Integer; n, mean : Single ) : Extended; + const + k = 0.001; + begin + Result := ( (k * mean) + (cnt * n) ) / (k + cnt); + end; + + function prbx( x2, degree : Extended ) : Extended; + begin + + Result := 0.5; + + end; + +var + n : Extended; + narray : array of Single; + mean : Extended; + countInfo : TWordCountInfo; + i : Integer; +// normal : Extended; +// important : Extended; + P1, Q1 : Extended; + cnt : Extended; +begin + + if wordCount.Count = 0 then begin + Result := 1; + Exit; + end; + + SetLength( narray, wordCount.Count ); + mean := 0; + for i := 0 to wordCount.Count - 1 do begin + n := p( wordCount[ i ] ); + narray[ i ] := n; + mean := mean + n; + end; + mean := mean / wordCount.Count; + + P1 := 1; + Q1 := 1; + for i := 0 to wordCount.Count - 1 do begin + countInfo := TWordCountInfo( wordCount.Objects[ i ] ); + n := f( countInfo.WordCount, narray[ i ], mean ); + P1 := P1 * ( 1 - n ); + Q1 := Q1 * n; + end; + cnt := wordCount.Count; + if cnt = 0 then + cnt := 1; + try + P1 := Power( P1, 1 / cnt ); + except + end; + try + Q1 := Power( Q1, 1 / cnt ); + except + end; + + P1 := 1 - prbx( -2 * Ln( P1 ), 2 * cnt ); + Q1 := 1 - prbx( -2 * Ln( Q1 ), 2 * cnt ); - n := (important - normal+ 0.00001) / (important + normal + 0.00001); - Result := (1 + n) / 2; + Result := (1 + P1 - Q1) / 2; end; @@ -650,14 +944,16 @@ end; function TGikoBayesian.Parse( const text : string; wordCount : TWordCount; - algorithm : TGikoBayesianAlgorithm = gbaGaryRonbinson + algorithm : TGikoBayesianAlgorithm ) : Extended; begin CountWord( text, wordCount ); case algorithm of gbaPaulGraham: Result := CalcPaulGraham( wordCount ); - gbaGaryRonbinson: Result := CalcGaryRobinson( wordCount ); + gbaGaryRobinson: Result := CalcGaryRobinson( wordCount ); + gbaGaryRobinsonFisher: + Result := CalcGaryRobinsonFisher( wordCount ); else Result := 0; end;