public function cluster(TrainingSet $documents, FeatureFactoryInterface $ff)
    {
        // transform the documents according to the FeatureFactory
        $docs = $this->getDocumentArray($documents,$ff);

        // choose N centroids at random
        $centroids = array();
        foreach (array_rand($docs,$this->n) as $key) {
            $centroids[] = $docs[$key];
        }

        // cache the distance and centroid factory functions for use
        // with closures
        $dist = array($this->dist,'dist');
        $cf = array($this->centroidF,'getCentroid');

        // looooooooop
        while (true) {
            // compute the distance each document has from our centroids
            // the array is MxN where M = count($docs) and N = count($centroids)
            $distances = array_map(
                function ($doc) use (&$centroids,$dist) {
                    return array_map(
                        function ($c) use ($dist,$doc) {
                            // it is passed with an array because dist expects references
                            // and it failed when run with phpunit.
                            // see http://php.net/manual/en/function.call-user-func.php
                            // for the solution used below
                            return call_user_func_array(
                                $dist,
                                array(
                                    &$c,
                                    &$doc
                                )
                            );
                        },
                        $centroids
                    );
                },
                $docs
            );

            // initialize the empty clusters
            $clusters = array_fill_keys(
                array_keys($centroids),
                array()
            );
            foreach ($distances as $idx=>$d) {
                // assign document idx to the closest centroid
                $clusters[array_search(min($d),$d)][] = $idx;
            }

            // compute the new centroids from the assigned documents
            // using the centroid factory function
            $new_centroids = array_map(
                function ($cluster) use (&$docs,$cf) {
                    return call_user_func_array(
                        $cf,
                        array(
                            &$docs,
                            $cluster
                        )
                    );
                },
                $clusters
            );

            // compute the change each centroid had from the previous one
            $changes = array_map(
                $dist,
                $new_centroids,
                $centroids
            );

            // if the largest change is small enough we are done
            if (max($changes)<$this->cutoff) {
                // return the clusters, the centroids and the distances
                return array($clusters,$centroids,$distances);
            }

            // update the centroids and loooooop again
            $centroids = $new_centroids;
        }
    }
public function cluster(TrainingSet $documents, FeatureFactoryInterface $ff)
    {
        // transform the documents according to the FeatureFactory
        $docs = $this->getDocumentArray($documents,$ff);

        // choose N centroids at random
        $centroids = array();
        foreach (array_rand($docs,$this->n) as $key) {
            $centroids[] = $docs[$key];
        }

        // cache the distance and centroid factory functions for use
        // with closures
        $dist = array($this->dist,'dist');
        $cf = array($this->centroidF,'getCentroid');

        // looooooooop
        while (true) {
            // compute the distance each document has from our centroids
            // the array is MxN where M = count($docs) and N = count($centroids)
            $distances = array_map(
                function ($doc) use (&$centroids,$dist) {
                    return array_map(
                        function ($c) use ($dist,$doc) {
                            // it is passed with an array because dist expects references
                            // and it failed when run with phpunit.
                            // see http://php.net/manual/en/function.call-user-func.php
                            // for the solution used below
                            return call_user_func_array(
                                $dist,
                                array(
                                    &$c,
                                    &$doc
                                )
                            );
                        },
                        $centroids
                    );
                },
                $docs
            );

            // initialize the empty clusters
            $clusters = array_fill_keys(
                array_keys($centroids),
                array()
            );
            foreach ($distances as $idx=>$d) {
                // assign document idx to the closest centroid
                $clusters[array_search(min($d),$d)][] = $idx;
            }

            // compute the new centroids from the assigned documents
            // using the centroid factory function
            $new_centroids = array_map(
                function ($cluster) use (&$docs,$cf) {
                    return call_user_func_array(
                        $cf,
                        array(
                            &$docs,
                            $cluster
                        )
                    );
                },
                $clusters
            );

            // compute the change each centroid had from the previous one
            $changes = array_map(
                $dist,
                $new_centroids,
                $centroids
            );

            // if the largest change is small enough we are done
            if (max($changes)<$this->cutoff) {
                // return the clusters, the centroids and the distances
                return array($clusters,$centroids,$distances);
            }

            // update the centroids and loooooop again
            $centroids = $new_centroids;
        }
    }
public function cluster ( TrainingSet $ documents , FeatureFactoryInterface $ ff ) { // transform the documents according to the FeatureFactory $ docs = $ this -> getDocumentArray ( $ documents , $ ff ) ; // choose N centroids at random $ centroids = array ( ) ; foreach ( array_rand ( $ docs , $ this -> n ) as $ key ) { $ centroids [ ] = $ docs [ $ key ] ; } // cache the distance and centroid factory functions for use // with closures $ dist = array ( $ this -> dist , 'dist' ) ; $ cf = array ( $ this -> centroidF , 'getCentroid' ) ; // looooooooop while ( true ) { // compute the distance each document has from our centroids // the array is MxN where M = count($docs) and N = count($centroids) $ distances = array_map ( function ( $ doc ) use ( & $ centroids , $ dist ) { return array_map ( function ( $ c ) use ( $ dist , $ doc ) { // it is passed with an array because dist expects references // and it failed when run with phpunit. // see http://php.net/manual/en/function.call-user-func.php // for the solution used below return call_user_func_array ( $ dist , array ( & $ c , & $ doc ) ) ; } , $ centroids ) ; } , $ docs ) ; // initialize the empty clusters $ clusters = array_fill_keys ( array_keys ( $ centroids ) , array ( ) ) ; foreach ( $ distances as $ idx => $ d ) { // assign document idx to the closest centroid $ clusters [ array_search ( min ( $ d ) , $ d ) ] [ ] = $ idx ; } // compute the new centroids from the assigned documents // using the centroid factory function $ new_centroids = array_map ( function ( $ cluster ) use ( & $ docs , $ cf ) { return call_user_func_array ( $ cf , array ( & $ docs , $ cluster ) ) ; } , $ clusters ) ; // compute the change each centroid had from the previous one $ changes = array_map ( $ dist , $ new_centroids , $ centroids ) ; // if the largest change is small enough we are done if ( max ( $ changes ) < $ this -> cutoff ) { // return the clusters, the centroids and the distances return array ( $ clusters , $ centroids , $ distances ) ; } // update the centroids and loooooop again $ centroids = $ new_centroids ; } }
Apply the feature factory to the documents and then cluster the resulting array
using the provided distance metric and centroid factory.
Apply the feature factory to the documents and then cluster the resulting array using the provided distance metric and centroid factory .