/** * @file KMedian.h * @brief KMedian (aka K-medoid) * @author Alexander Freytag * @date 23-04-2013 (dd-mm-yyyy) */ #ifndef KMEDIANINCLUDE #define KMEDIANINCLUDE #include #include #include #include #include "ClusterAlgorithm.h" namespace OBJREC { /** * @class KMedian * @brief KMedian (aka K-medoid) * @author Alexander Freytag * @date 23-04-2013 (dd-mm-yyyy) */ class KMedian : public ClusterAlgorithm { protected: /************************ * * protected variables * **************************/ //! desired number of clusters int noClusters; //! specify which distance to use for calculating assignments std::string distanceType; //! the actual distance metric NICE::VectorDistance *distancefunction; //! maximum difference between prototype-solutions of two iterations for convergence double d_minDelta; //! maximum number of iterations until convergence int i_maxIterations; /************************ * * protected methods * **************************/ //! compute the distance between two features using the specified distance metric double vectorDistance(const NICE::Vector &vector1, const NICE::Vector &vector2, uint distancetype); //! compute assignments of all given features wrt to the currently known prototypes (cluster medoids) == ~ E-step double compute_assignments ( const NICE::VVector & features, const NICE::VVector & prototypes, std::vector & assignment ); //! compute number of assignments for every currently found cluster double compute_weights ( const NICE::VVector & features, std::vector & weights, std::vector & assignment ); //! compute the difference between prototypes of previous iteration and those currently found double compute_delta ( const NICE::VVector & oldprototypes, const NICE::VVector & prototypes ); //! compute (update) prototypes given the current assignments == ~ M-step int compute_prototypes ( const NICE::VVector & features, NICE::VVector & prototypes, std::vector & weights, const std::vector & assignment ); //! have an initial guess, i.e., randomly pick some features as initial cluster centroids void initial_guess ( const NICE::VVector & features, NICE::VVector & prototypes ); //! give additional information for the current iteration void print_iteration ( int iterations, NICE::VVector & prototypes, double delta ); public: ///////////////////// ///////////////////// ///////////////////// // CONSTRUCTORS / DESTRUCTORS ///////////////////// ///////////////////// ///////////////////// /** * @brief default constructor * @date 12-02-2014 (dd-mm-yyyy ) * @author Alexander Freytag */ KMedian ( ); /** * @brief simple constructor * @param _noClusters the number of clusters to be computed * @param _distanceMode a string specifying the distance function to be used (default: euclidean) */ KMedian( const int & _noClusters , const std::string & _distanceMode="euclidean"); /** * @brief standard constructor * @param conf config file specifying all relevant variable settings * @param _section name of the section within the configfile where the settings can be found (default: KMedian) */ KMedian( const NICE::Config * _conf, const std::string & _confSection = "KMedian"); /** simple destructor */ virtual ~KMedian(); /** * @brief Jobs previously performed in the config-version of the constructor, read settings etc. * @author Alexander Freytag * @date 12-02-2014 ( dd-mm-yyyy ) */ void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "KMedian"); ///////////////////// ///////////////////// ///////////////////// // CLUSTERING STUFF ///////////////////// ///////////////////// ////////////////// /** *@brief this is the actual method that performs the clustering for a given set of features *@author Alexander Freytag *@date 25-04-2013 (dd-mm-yyyy) *@param features input features to be clustered *@param prototypes computed prototypes (cluster medoids) for the given samples *@param weights number of assignments for every cluster *@param assignment explicite assignments of features to computed cluster medoids */ void cluster ( const NICE::VVector & features, NICE::VVector & prototypes, std::vector & weights, std::vector & assignment ); ///////////////////// INTERFACE PERSISTENT ///////////////////// // interface specific methods for store and restore ///////////////////// INTERFACE PERSISTENT ///////////////////// /** * @brief Load object from external file (stream) * @author Alexander Freytag * @date 12-02-2014 ( dd-mm-yyyy ) */ void restore ( std::istream & is, int format = 0 ); /** * @brief Save object to external file (stream) * @author Alexander Freytag * @date 12-02-2014 ( dd-mm-yyyy ) */ void store ( std::ostream & os, int format = 0 ) const; /** * @brief Clear object * @author Alexander Freytag * @date 12-02-2014 ( dd-mm-yyyy ) */ void clear (); }; } // namespace #endif