Я пишу программу Java, которая в одной части пытается найти все слова, которые совместно встречаются в предложении вместе и подсчитывают их частоту.Более эффективный способ найти частоту рядов bigrams
Основная проблема заключается в том, что код кажется очень неэффективным, и текст, который я пытаюсь извлечь из этих Ranged Bigrams, является относительно большим (70000 уникальных форм слова, токены 2.5M).
Я использую векторное пространство для появления каждого уникального слова в тексте. а затем сравните их, чтобы увидеть, происходят ли два слова в одном предложении.
Вот мой код:
public static HashMap<Pair<String>, Double> flexGramCountEVSM(HashMap<String, ArrayList<Double>> wordVector, String delimiter) {
HashMap<Pair<String>, Double> bigramFrequencies = new HashMap<>();
Pair<String> thisBigram;
String word1, word2;
ArrayList<String> keys = new ArrayList<>(wordVector.keySet());
ArrayList<Double> delims = wordVector.get(delimiter);
for (int i = 0; i < keys.size(); i++) {
if (i % 1 == 0) System.out.println("---> " + i);
word1 = keys.get(i);
if (word1.equals(delimiter)) continue;
// First Word Occurrences:
ArrayList<Double> a = wordVector.get(word1);
for (int j = i + 1; j < keys.size(); j++) {
word2 = keys.get(j);
if (word2.equals(delimiter)) continue;
// Second Word Occurrences:
ArrayList<Double> b = wordVector.get(word2);
thisBigram = new Pair<>(word1, word2);
int a1, a2, b1, b2, d1, d2, thisBigramCount = 0;
if (a.size() <= b.size()) {
for (Double posA : a) {
d2 = -Collections.binarySearch(delims, posA) - 1;
d1 = d2 != 0 ? (d2 - 1) : d2;
b1 = -Collections.binarySearch(b, delims.get(d1)) - 1;
b2 = -Collections.binarySearch(b, delims.get(d2)) - 1;
if (b2 > b1) {
thisBigramCount += b2 - b1;
}
}
} else {
for (Double posB : b) {
d2 = -Collections.binarySearch(delims, posB) - 1;
d1 = d2 != 0 ? (d2 - 1) : d2;
a1 = -Collections.binarySearch(a, delims.get(d1)) - 1;
a2 = -Collections.binarySearch(a, delims.get(d2)) - 1;
if (a2 > a1) {
thisBigramCount += a2 - a1;
}
}
}
bigramFrequencies.put(thisBigram, (double) thisBigramCount);
}
}
return bigramFrequencies;
}
Я использовать бинарный поиск, чтобы найти границы приговор, так что я не должен повторять при каждом появлении каждого слова и предложения. Но я не знаю, какие другие оптимизации можно было бы сделать. Должен ли я попробовать совершенно другой подход?
С помощью этого кода для каждой итерации внешней петли, которая является возмутительной, потребуется около 3 секунд.
Есть ли лучший способ сделать это?