Skip to content

Commit

Permalink
Add configuration to limit length of rules
Browse files Browse the repository at this point in the history
  • Loading branch information
schmengler committed Sep 5, 2023
1 parent 657384e commit 3aaa88c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
15 changes: 13 additions & 2 deletions src/FPGrowth.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class FPGrowth
{
protected int $support = 3;
protected float $confidence = 0.7;
private int $maxLength = 0;

private $patterns;
private $rules;
Expand Down Expand Up @@ -50,6 +51,15 @@ public function setConfidence(float $confidence): self
return $this;
}

public function getMaxLength(): int
{
return $this->maxLength;
}

public function setMaxLength(int $maxLength): void
{
$this->maxLength = $maxLength;
}
/**
* @return mixed
*/
Expand All @@ -71,10 +81,11 @@ public function getRules()
* @param int $support 1, 2, 3 ...
* @param float $confidence 0 ... 1
*/
public function __construct(int $support, float $confidence)
public function __construct(int $support, float $confidence, int $maxLength = 0)
{
$this->setSupport($support);
$this->setConfidence($confidence);
$this->setMaxLength($maxLength);
}

/**
Expand All @@ -93,7 +104,7 @@ public function run(array $transactions)
*/
protected function findFrequentPatterns(array $transactions): array
{
$tree = new FPTree($transactions, $this->support, null, 0);
$tree = new FPTree($transactions, $this->support, null, 0, $this->maxLength);
return $tree->minePatterns($this->support);
}

Expand Down
25 changes: 22 additions & 3 deletions src/FPTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,23 @@ class FPTree

private FPNode $root;

private int $maxLength = 0;

private int $depth = 0;

/**
* Initialize the tree.
* @param array $transactions
* @param int $threshold
* @param $rootValue
* @param int $rootCount
*/
public function __construct(array $transactions, int $threshold, $rootValue, int $rootCount)
public function __construct(array $transactions, int $threshold, $rootValue, int $rootCount, $maxLength = 0)
{
$this->frequent = $this->findFrequentItems($transactions, $threshold);
$this->headers = $this->buildHeaderTable();
$this->root = $this->buildFPTree($transactions, $rootValue, $rootCount, $this->frequent);
$this->maxLength = $maxLength;
}

/**
Expand Down Expand Up @@ -168,6 +173,8 @@ public function minePatterns(int $threshold): array
{
if ($this->treeHasSinglePath($this->root)) {
return $this->generatePatternList();
} elseif ($this->maxLength && $this->maxLength <= $this->getDepth()) {
return [];
}

return $this->zipPatterns($this->mineSubTrees($threshold));
Expand Down Expand Up @@ -211,7 +218,13 @@ protected function generatePatternList(): array
$patterns[$this->root->value] = $this->root->count;
}

for ($i = 1; $i <= count($items); $i++) {
// limit length of combinations to remaining length
$count = count($items);
if ($this->maxLength) {
$count = min($count, $this->maxLength - $this->getDepth());
}

for ($i = 1; $i <= $count; $i++) {
$combinations = new Combinations($items,$i);
foreach ($combinations->generator() as $subset) {
$pattern = $this->root->value !== null ? array_merge($subset, [$this->root->value]) : $subset;
Expand Down Expand Up @@ -270,7 +283,8 @@ protected function mineSubTrees(int $threshold): array
}

// Now we have the input for a subtree, so construct it and grab the patterns.
$subtree = new FPTree($conditionalTreeInput, $threshold, $item, $this->frequent[$item]);
$subtree = new FPTree($conditionalTreeInput, $threshold, $item, $this->frequent[$item], $this->maxLength);
$subtree->depth = $this->depth + 1;
$subtreePatterns = $subtree->minePatterns($threshold);

// Insert subtree patterns into main patterns dictionary.
Expand All @@ -285,4 +299,9 @@ protected function mineSubTrees(int $threshold): array

return $patterns;
}

private function getDepth(): int
{
return $this->depth;
}
}

0 comments on commit 3aaa88c

Please sign in to comment.