Количество фраз Delphi / плотность ключевых слов
Кто-нибудь знает, как или есть какой-нибудь код для подсчета количества уникальных фраз в документе? (Одно слово, две словосочетания, три словосочетания).
Спасибо
Пример того, что я ищу: я имею в виду, что у меня есть текстовый документ, и мне нужно увидеть, какие слова являются наиболее популярными. Пример текста
Я взял машину на автомойку.
Я: 1 взял: 1 the: 2 машина: 2 до: 1 мытье: 1 Я взял: 1 взял: 1 машина: 2 автомобиль до: 1 к: 1 автомойка: 1 Я взял: 1 забрал машину: 1 машина для: 1 машина до: 1 к машине: 1 автомойка: 1 Я взял машину, чтобы: 1 взял машину до: 1 машина к машине: 1 машина до автомойки: 1
Мне нужна фраза и количество, которое она показывает.
Любая помощь будет оценена. Я обнаружил, что в этом шкафу был скрипт PHP от http://tools.seobook.com/general/keyword-density/source.php
Раньше у меня был какой-то код для этого, но я не могу его найти.
4 ответа
Вот некоторый исходный код, который решает вашу проблему.
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
С веб-сайта 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;
Может это поможет
Так я бы решил проблему. Предполагая, что каждый проход через файл данных создаст новый файл данных для следующего шага. Упомянутый управляющий символ может быть любым символом, который естественным образом не появляется в данных. Когда вы пишете управляющий символ, не пишите дубликаты.
- Пробежитесь по вашему документу и посчитайте каждое слово отдельно.
- Еще раз просмотрите документ и замените любое слово, использованное только один раз, контрольным символом, добавив в новый список встречающиеся пары (слова A B C становятся элементом AB и элементом B C). Управляющие символы действуют как жесткие разделители. Любое слово, которое находится между управляющими символами, также должно быть преобразовано, поскольку оно не может быть преобразовано в пару.
- Запустите ваш документ снова и замените любую пару, использованную только один раз, контрольным символом, добавив в новый список любые триплеты, которые встречаются. Преобразуйте пары между управляющими символами в управляющие символы.
Повторите добавление еще одного уровня слова в каждый список, пока не получите пустой список или у вас не будет максимальной фразы, которую вы хотите поддержать.
Этот метод подразумевает тот факт, что ваши самые распространенные фразы не могут содержать более мелкие фразы, используемые реже.
Количество возможных комбинаций растет очень быстро. Предположим, что в основном языке используется 30000 слов, тогда количество комбинаций из трех фраз составляет 30000^3.
В любом случае реализация нулевого уровня будет состоять в том, чтобы создать (хэш) список слов, отфильтровать список, если необходимо, для очень распространенных слов (,, и т. Д.), Чтобы уменьшить количество фраз. Другие вещи, которые вы, возможно, захотите сделать, это уменьшить число множественных чисел до одиночных, удалить трейлинг, корпус и т. Д.
Затем обойдите текст дословно (стиль токенизатора), пропустив общие слова, и просто сохраните упорядоченный список фраз, с которыми вы сталкиваетесь, с подсчетом, и надеемся, что ваша память не исчерпается, поскольку у Delphi нет 64-битной версии:)
Разве у Кнута не было целой книги о комбинациях?