← Back
Editing: PlusPlus.php
<?php namespace Rubix\ML\Clusterers\Seeders; use Rubix\ML\Datasets\Dataset; use Rubix\ML\Kernels\Distance\Distance; use Rubix\ML\Kernels\Distance\Euclidean; use Rubix\ML\Specifications\DatasetIsNotEmpty; use Rubix\ML\Exceptions\RuntimeException; use function count; /** * Plus Plus * * This seeder attempts to maximize the chances of seeding distant clusters while still * remaining random. It does so by sequentially selecting random samples weighted by their * distance from the previous seed. * * References: * [1] D. Arthur et al. (2006). k-means++: The Advantages of Careful Seeding. * [2] A. Stetco et al. (2015). Fuzzy C-means++: Fuzzy C-means with effective * seeding initialization. * * @category Machine Learning * @package Rubix/ML * @author Andrew DalPino */ class PlusPlus implements Seeder { /** * The distance kernel used to compute the distance between samples. * * @var Distance */ protected Distance $kernel; /** * @param Distance|null $kernel */ public function __construct(?Distance $kernel = null) { $this->kernel = $kernel ?? new Euclidean(); } /** * Seed k cluster centroids from a dataset. * * @internal * * @param Dataset $dataset * @param int $k * @throws RuntimeException * @return list<list<string|int|float>> */ public function seed(Dataset $dataset, int $k) : array { DatasetIsNotEmpty::with($dataset)->check(); if ($k > $dataset->numSamples()) { throw new RuntimeException("Cannot seed $k clusters with only " . $dataset->numSamples() . ' samples.'); } $centroids = $dataset->randomSubset(1)->samples(); while (count($centroids) < $k) { $weights = []; foreach ($dataset->samples() as $sample) { $bestDistance = INF; foreach ($centroids as $centroid) { $distance = $this->kernel->compute($sample, $centroid); if ($distance < $bestDistance) { $bestDistance = $distance; } } $weights[] = $bestDistance ** 2; } $centroids[] = $dataset->randomWeightedSubsetWithReplacement(1, $weights)->sample(0); } return $centroids; } /** * Return the string representation of the object. * * @internal * * @return string */ public function __toString() : string { return "Plus Plus (kernel: {$this->kernel})"; } }
Save File
Cancel