mineForItem<T> function
Recursively mines frequent itemsets for a specific item and its conditional tree.
This function explores the FP-Tree starting from a given item, builds its
conditional FP-Tree, and recursively mines it to find all frequent itemsets
that are extensions of the current prefix and the item.
Implementation
Map<List<int>, int> mineForItem<T>(
FPTree tree,
int item,
List<int> prefix,
Map<int, int> frequency,
int absoluteMinSupport,
ItemMapper<T> mapper,
Logger logger,
) {
final frequentItemsets = <List<int>, int>{};
final newPrefix = List<int>.from(prefix)..add(item);
final support = frequency[item]!;
frequentItemsets[newPrefix] = support;
logger.debug(
' Processing item: ${mapper.getItem(item)} (support: $support)',
);
// Find conditional pattern bases
final conditionalPatternBases = tree.findPaths(item);
// Calculate conditional frequency
final conditionalFrequency = <int, int>{};
for (final entry in conditionalPatternBases.entries) {
for (final itemInPath in entry.key) {
conditionalFrequency[itemInPath] =
(conditionalFrequency[itemInPath] ?? 0) + entry.value;
}
}
final conditionalFrequentItems = filterFrequentItems(
conditionalFrequency,
absoluteMinSupport,
);
if (conditionalFrequentItems.isNotEmpty) {
// Reconstruct transactions for conditional tree
final weightedTransactions = buildConditionalTransactions(
conditionalPatternBases,
conditionalFrequentItems,
);
if (weightedTransactions.isNotEmpty) {
final conditionalTree = FPTree(conditionalFrequentItems)
..addWeightedTransactions(weightedTransactions);
// Single-path optimization
if (conditionalTree.isSinglePath()) {
logger.debug(
' Single-path optimization applied for prefix: ${newPrefix.map(mapper.getItem).join(', ')}',
);
final pathNodes = conditionalTree.getSinglePathNodes();
final allSubsets = generateSubsets(pathNodes);
for (final subset in allSubsets) {
final itemset = subset.map((node) => node.item!).toList();
final support = subset
.map((node) => node.count)
.reduce((a, b) => a < b ? a : b);
frequentItemsets[List<int>.from(newPrefix)..addAll(itemset)] =
support;
}
} else {
// Recursively mine the conditional tree
final minedPatterns = mineLogic(
conditionalTree,
newPrefix,
conditionalFrequentItems,
absoluteMinSupport,
mapper,
logger,
);
frequentItemsets.addAll(minedPatterns);
}
}
}
return frequentItemsets;
}