Количество фраз Delphi / плотность ключевых слов - PullRequest
0 голосов
/ 17 марта 2010

Кто-нибудь знает, как или есть какой-нибудь код для подсчета количества уникальных фраз в документе? (Одно слово, две словосочетания, три словосочетания).

Спасибо

Пример того, что я ищу: Я имею в виду, что у меня есть текстовый документ, и мне нужно увидеть, какие слова являются наиболее популярными. Пример текста

Я отвез машину на автомойку.

I : 1
took : 1
the : 2
car: 2
to : 1
wash : 1
I took : 1
took the : 1
the car : 2
car to : 1
to the : 1
car wash : 1
I took the : 1
took the car : 1
the car to : 1
car to the : 1
to the car : 1
the car wash : 1
I took the car to : 1
took the car to the : 1
the car to the car : 1
car to the car wash : 1

Мне нужна фраза и счет, который она показывает.

Любая помощь будет оценена. В шкафу я обнаружил PHP-скрипт от http://tools.seobook.com/general/keyword-density/source.php

Раньше у меня был какой-то код для этого, но я не могу его найти.

Ответы [ 4 ]

2 голосов
/ 17 марта 2010

Вот некоторый исходный код, который решает вашу проблему.

function CountWordSequences(const s:string; Counts:TStrings = nil):TStrings;
var
  words, seqs : TStrings;
  nw,i,j:integer;
  t :string;
begin
  if Counts=nil then Counts:=TStringList.Create;
  words:=TStringList.Create;        // build a list of all words
  words.DelimitedText:=s;
  seqs:=TStringList.Create;
  for nw:=1 to words.Count do       // build a list of all word sequences
   begin
    for i:=0 to words.Count-nw do
     begin
      t:='';
      for j:=0 to nw-1 do
       begin
        t:=t+words[i+j];
        if j<>nw-1 then t:=t+' ';
       end;
      seqs.Add(t);
     end;
   end;
  words.Destroy;
  for i:=0 to seqs.Count-1 do         // count repeated sequences
   begin
    j:=Counts.IndexOf(seqs.Strings[i]);
    if j=-1 then
      Counts.AddObject(seqs.Strings[i],TObject(1))
    else
      Counts.Objects[j] := TObject(Succ(Integer(Counts.Objects[j])));
   end;
  seqs.Destroy;
  result:=Counts;
end;

Вам нужно будет разработать этот код для реального производства, например, путем распознавания большего количества разделителей слов (не только пробелов) и реализации некоторой нечувствительности к регистру.

Чтобы проверить это, поместите в форму Button, EntryField и Memo и добавьте следующий код.

procedure TForm1.Button1Click(Sender: TObject);
var i:integer; l:TStrings;
 begin
  l:=CountWordSequences(edit1.Text,TStringList.Create);
  for i:=1 to l.count do
    memo1.Lines.Add('"'+l.Strings[i-1]+'": '+inttostr(Integer(l.Objects[i-1])));
 end;

Сначала я попробую с I took the car to the car wash

дает

"I": 1
"took": 1
"the": 2
"car": 2
"to": 1
"wash.": 1
"I took": 1
"took the": 1
"the car": 2
"car to": 1
"to the": 1
"car wash.": 1
"I took the": 1
"took the car": 1
"the car to": 1
"car to the": 1
"to the car": 1
"the car wash.": 1
"I took the car": 1
"took the car to": 1
"the car to the": 1
"car to the car": 1
"to the car wash.": 1
"I took the car to": 1
"took the car to the": 1
"the car to the car": 1
"car to the car wash.": 1
"I took the car to the": 1
"took the car to the car": 1
"the car to the car wash.": 1
"I took the car to the car": 1
"took the car to the car wash.": 1
"I took the car to the car wash.": 1
0 голосов
/ 18 марта 2010

Так я бы решил проблему. Предполагая, что каждый проход через файл данных создаст новый файл данных для следующего шага. Упомянутый управляющий символ может быть любым символом, который естественным образом не появляется в данных. Когда вы пишете управляющий символ, не пишите дубликаты.

  1. Беги через свой документировать и считать каждое слово по отдельности.
  2. Беги через свой снова документ и замените любое используемое слово только один раз с управляющим символом, добавление в новый список пар, которые происходят (слова A B C становятся элементом A B и пункт B C). Управляющие персонажи действовать как жесткие разделители. Любое слово, которое находится между управляющими символами, также должно быть преобразовано, поскольку оно не может быть преобразовано в пару.
  3. Run через ваш документ снова и заменить любую пару, использованную только один раз, управляющий персонаж, добавляющий к новому перечислите любые триплеты, которые происходят. Преобразуйте пары между управляющими символами в управляющие символы.

Повторяйте добавление еще одного уровня слова в каждый список, пока не получите пустой список или не наберете максимальное количество фраз, которые хотите поддерживать.

Этот метод подразумевает тот факт, что ваши самые распространенные фразы не могут содержать более мелкие фразы, используемые реже.

0 голосов
/ 17 марта 2010

Количество возможных комбинаций растет очень быстро. Предположим, что в основном языке используется 30000 слов, тогда количество комбинаций из трех фраз составляет 30000 ^ 3

В любом случае реализация нулевого уровня будет состоять в том, чтобы создать (хэш) список слов, отфильтровать список, если необходимо, для очень распространенных слов (,, и т. Д.), Чтобы уменьшить количество фраз. Другие вещи, которые вы, возможно, захотите сделать, это уменьшить число множественных чисел до одиночных, удалить трейлинг, регистр и т. Д.

Затем обойдите текст дословно (стиль токенизатора), пропустив общие слова, и просто сохраните упорядоченный список фраз, с которыми вы сталкиваетесь, с подсчетом, и надеемся, что ваша память не исчерпается, поскольку в Delphi битовая версия:)

Разве у Кнута не было целой книги о комбинациях?

0 голосов
/ 17 марта 2010

С веб-сайта Delphi Basics.

var
  position : Integer;

begin
  // Look for the word 'Cat' in a sentence
  // Note : that this search is case sensitive, so that
  //        the first 'cat' is not matched
  position := AnsiPos('Cat', 'The cat sat on the Cat mat');
  if position = 0
  then ShowMessage('''Cat'' not found in the sentence')
  else ShowMessage('''Cat'' was found at character '+IntToStr(position));
end;

Может быть, это поможет

...