私はグーグルを検索しても役に立たなかった。Prologで用語の頻度をコード化する方法を教えてくれる人はいますか?「論理」が多ければ多いほどよい。テキストファイルの場合、英数字以外の文字を無視し、単語を検出し、ストップワード(外部ファイルで指定されている可能性があります)を削除し、ファイル内の各単語の出現回数をカウントして、頻度の低い順に「word:freq」のようなものを出力します。
ありがとう!
(これは宿題ではありません、ところで、これは私がやっているプロジェクトです)
私はグーグルを検索しても役に立たなかった。Prologで用語の頻度をコード化する方法を教えてくれる人はいますか?「論理」が多ければ多いほどよい。テキストファイルの場合、英数字以外の文字を無視し、単語を検出し、ストップワード(外部ファイルで指定されている可能性があります)を削除し、ファイル内の各単語の出現回数をカウントして、頻度の低い順に「word:freq」のようなものを出力します。
ありがとう!
(これは宿題ではありません、ところで、これは私がやっているプロジェクトです)
この回答ではSWI-Prologの広範なライブラリサポートを使用しているため、あなたの場合は不適切かもしれません.
もちろん、プログラミング タスクを解決する方法は、選択した言語で何が利用できるか、およびそれを使用する能力に大きく影響されます。
ここではlibrary(assoc)を使用します。システムがそれを見逃した場合は、リストを使用するか、アサート/リトラクトを使用してシミュレートできます。
このフラグメントは、単語を数える(慣用的な) 方法を示しているだけです。頻度の計算は、ライブラリ (集合体) または少しの算術演算で簡単に実行できます。おそらく、言語を練習するために自分で書き留めてみてください...
/* File: frequency_of_words.pl
Author: Carlo,,,
Created: May 23 2012
Purpose: http://stackoverflow.com/questions/10711483/calculating-term-frequency-in-prolog
*/
:- module(frequency_of_words, [count_words/2, count_words/1]).
:- [library(assoc)].
count_words(File, Assoc) :-
empty_assoc(Empty),
open(File, read, Stream),
frequency_of_words(Stream, Empty, Assoc, ""),
close(Stream).
count_words(File) :-
count_words(File, Assoc),
assoc_to_list(Assoc, List),
maplist(writeln, List).
frequency_of_words(Stream, SoFar, Words, CurrWord) :-
get_code(Stream, Code),
( Code == -1
-> update_dictionary(SoFar, Words, CurrWord)
; use_character(Code, SoFar, Updated, CurrWord, NextWord),
frequency_of_words(Stream, Updated, Words, NextWord)
).
update_dictionary(SoFar, SoFar, Word) :-
skip_word(Word).
update_dictionary(SoFar, Updated, Codes) :-
atom_codes(Word, Codes),
( get_assoc(Word, SoFar, CountSoFar) ; CountSoFar = 0 ),
WordCount is CountSoFar + 1,
put_assoc(Word, SoFar, WordCount, Updated).
use_character(Code, SoFar, Updated, CurrWord, NextWord) :-
( word_character(Code)
-> Updated = SoFar,
NextWord = [Code|CurrWord]
; reverse(CurrWord, Forward),
update_dictionary(SoFar, Updated, Forward),
NextWord = ""
).
word_character(Code) :-
[Code] @>= "A", [Code] @=< "Z" ;
[Code] @>= "a", [Code] @=< "z" ;
[Code] @>= "0", [Code] @=< "9" ;
[Code] == "_".
skip_word(""). % a trick on EOF or consecutive blanks: not really a skipword
skip_word("is").
テスト:
?- count_words('frequency_of_words.pl').
0-2
1-3
2012-1
23-1
9-1
A-1
Author-1
Carlo-1
Code-14
Codes-2
CountSoFar-3
Created-1
CurrWord-6
EOF-1
Empty-2
File-3
Forward-2
Full-2
List-2
May-1
NextWord-5
Purpose-1
SoFar-11
StackOverflow-1
Stream-6
Updated-7
Word-5
WordCount-2
Words-3
Z-1
_-1
a-3
answer-1
assoc-1
assoc_to_list-1
atom_codes-1
blanks-1
close-1
consecutive-1
count_words-2
empty_assoc-1
frequency_of_words-5
get_assoc-1
get_code-1
library-1
maplist-1
module-1
not-1
on-1
open-1
or-1
pl-1
put_assoc-1
read-1
really-1
reverse-1
skip_word-3
skipword-1
trick-1
update_dictionary-4
use_character-2
word_character-2
writeln-1
z-1
ここにあなたが始めるための何かがあります:
単語はそれぞれ入力ファイルの別の行にあると想定しています
「ストップワード」を処理しない
ソートを実装しない
; Print the term frequency for words in file Path
print_freq_from_file(Path) :-
open( Path, read, Stream ),
read_file( Stream, Words ),
calc_freq( Words, Freq ),
sort_freq( Freq, SortedFreq ),
print_freq( SortedFreq ).
; calc_freq(Words,Freq) Freq is the term frequency of the words in list Words
calc_freq( [], [] ).
calc_freq( [Word|Words], Freq ) :-
calc_freq( Words, FreqRest ),
add_word( Word, FreqRest, Freq ).
; add_word( Word, Freq1, Freq2 ) Freq2 is Freq1 with Word added
add_word( Word, [], [(Word,1)] ).
add_word( Word, [(Word,N)|Rest], [(Word,N1)|Rest] ) :-
N1 is N+1.
add_word( Word, [Term|Rest], [Term|NewRest] ) :-
add_word( Word, Rest, NewRest ).
; Print the given term frequency
print_freq( [] ).
print_freq( [(W,N)|Rest] ) :-
write( W ), write( ' : ' ), write( N ), nl,
print_freq( Rest ).
ストップワードをフィルタリングするには、次の方法が適していますassert
。
read_sw(Path) :-
open( Path, read, Stream ),
read_words_file( Stream, Words ),
add_sw(Words).
add_sw([]).
add_sw([Word|Rest]) :-
assertz(stop_word(Word)),
add_sw(Rest).
これが完了するstop_word/1
と、単語がストップワードであるかどうかを確認し、それを無視するために使用できます。たとえば、Scott Hunterの回答を実装している場合は、に句を追加して、calc_freq/2
これらの単語を除外できます。
calc_freq( [], [] ).
calc_freq( [Word|Words], Freq ) :-
stop_word(Word), !,
calc_freq( Words, Freq ).
calc_freq( [Word|Words], Freq ) :-
calc_freq( Words, FreqRest ),
add_word( Word, FreqRest, Freq ).