0

語彙 (文字列のベクトル) と文でいっぱいのファイルがあります。各文に各単語が含まれる頻度を示すマトリックスを作成したいと考えています。私の現在の実装は非常に遅く、これはもっと速くなると信じています。10 語程度の 1 文を書くのに 1 分近くかかります。

これがなぜなのか、どのようにスピードアップするのか説明できますか?

注: 他の方法ではメモリに収まらないため、スパース行列を使用します。語彙のサイズは約 10.000 語です。プログラムを実行しても作業メモリが使い果たされることはないので、それが問題になることはありません。

関連するコードは次のとおりです。totalLineCount、vocab、vocabCount など、言及されていない変数は以前に初期化されています。

% initiate sentence structure
wordSentenceMatrix = sparse(vocabCount, totalLineCount);
% fill the sentence structure
fid = fopen(fileLocation, 'r');
lineCount = 0;
while ~feof(fid),
    line = fgetl(fid);
    lineCount = lineCount + 1;
    line = strsplit(line, " ");
    % go through each word and increase the corresponding value in the matrix
    for j=1:size(line,2),
        for k=1:vocabCount,
            w1 = line(j);
            w2 = vocab(k);
            if strcmp(w1, w2),
                wordSentenceMatrix(k, lineCount) = wordSentenceMatrix(k, lineCount) + 1;
            end;
        end;
    end;
end;
4

1 に答える 1

1

疎行列は、実際にはメモリ内の 3 つの配列に格納されます。簡略化された言語では、そのストレージを行インデックスの 1 つの配列、列インデックスの 1 つの配列、およびゼロ以外のエントリ値の 1 つの配列として表すことができます。(もう少し複雑な話は圧縮スパース列と呼ばれます。)

コード内の要素ごとに疎行列を拡張することにより、その行列の構造 (または疎パターン) を繰り返し変更しています。これは大量のメモリ コピーを伴うため、お勧めしません。

ボキャブラリ内の単語のインデックスをクエリする方法も非常に遅くなります。これは、センテンス内の単語ごとにボキャブラリ全体を調べているためです。より良い方法は、Matlab で Java HashMap を使用することです。

コードを次のように変更しました。

rowIdx = [];
colIdx = [];
vocabHashMap = java.util.HashMap;
for k = 1 : vocabCount
    vocabHashMap.put(vocab{k}, k);
end

fid = fopen(fileLocation, 'r');
lineCount = 0;
while ~feof(fid),
    line = fgetl(fid);
    lineCount = lineCount + 1;
    line = strsplit(line, " ");
    % go through each word and increase the corresponding value in the matrix
    for j = 1 : length(line)
        rowIdx = [rowIdx; vocabHashMap.get(line{j})];
        colIdx = [colIdx; lineCount];
    end
end
assert(length(rowIdx) == length(colIdx));
nonzeros = length(rowIdx);
wordSentenceMatrix = sparse(rowIdx, colIdx, ones(nonzeros, 1));

もちろん、テキスト コレクションの長さがアプリオリにわかっている場合は、 と のメモリを事前に割り当てる必要がrowIdxありcolIdxます。

rowIdx = zeros(nonzeros, 1);
colIdx = zeros(nonzeros, 1);

できれば Octave に移植してください。

于 2013-06-26T18:49:07.820 に答える