From 30bf945095e193c7a350d6482739f7297d52e574 Mon Sep 17 00:00:00 2001 From: Davis King Date: Fri, 30 May 2008 22:52:51 +0000 Subject: [PATCH] Added a kkmeans example --HG-- extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402283 --- examples/kkmeans_ex.cpp | 125 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 examples/kkmeans_ex.cpp diff --git a/examples/kkmeans_ex.cpp b/examples/kkmeans_ex.cpp new file mode 100644 index 000000000..984411495 --- /dev/null +++ b/examples/kkmeans_ex.cpp @@ -0,0 +1,125 @@ +/* + This is an example illustrating the use of the kkmeans object + from the dlib C++ Library. + + The kkmeans object is an implementation of a kernelized k-means clustering + algorithm. It is implemented by using the kcentroid object to represent + each center found by the usual k-means clustering algorithm. + + So this object allows you to perform non-linear clustering in the same way + a svm classifier finds non-linear decision surfaces. + + This example will make points from 3 classes and perform kernelized k-means + clustering on those points. + + The classes are as follows: + - points very close to the origin + - points on the circle of radius 10 around the origin + - points that are on a circle of radius 4 but not around the origin at all +*/ + +#include +#include + +#include "dlib/svm.h" +#include "dlib/rand.h" + +using namespace std; +using namespace dlib; + +int main() +{ + // Here we declare that our samples will be 2 dimensional column vectors. + typedef matrix sample_type; + + // Now we are making a typedef for the kind of kernel we want to use. I picked the + // radial basis kernel because it only has one parameter and generally gives good + // results without much fiddling. + typedef radial_basis_kernel kernel_type; + + // Here we declare an instance of the kcentroid object. The first argument to the constructor + // is the kernel we wish to use. The second is a parameter that determines the numerical + // accuracy with which the object will perform part of the learning algorithm. Generally + // smaller values give better results but cause the algorithm to run slower. You just have + // to play with it to decide what balance of speed and accuracy is right for your problem. + // Here we have set it to 0.01. + kcentroid kc(kernel_type(0.1),0.01); + + // Now we make an instance of the kkmeans object and tell it to use kcentroid objects + // that are configured with the parameters from the kc object we defined above. + kkmeans test(kc); + + std::vector samples; + std::vector initial_centers; + + sample_type m; + + dlib::rand::float_1a rnd; + + // we will make 25 points from each class + const long num = 25; + + // make some samples near the origin + double radius = 0.5; + for (long i = 0; i < num; ++i) + { + m(0) = 2*radius*rnd.get_random_double()-radius; + m(1) = sqrt(radius*radius - m(0)*m(0)); + + // add this sample to our set of samples we will run k-means + samples.push_back(m); + } + + // make some samples in a circle around the origin but far away + radius = 10.0; + for (long i = 0; i < num; ++i) + { + m(0) = 2*radius*rnd.get_random_double()-radius; + m(1) = sqrt(radius*radius - m(0)*m(0)); + + // add this sample to our set of samples we will run k-means + samples.push_back(m); + } + + // make some samples in a circle around the point (20,20) + radius = 4.0; + for (long i = 0; i < num; ++i) + { + m(0) = 2*radius*rnd.get_random_double()-radius; + m(1) = sqrt(radius*radius - m(0)*m(0)); + + // translate this point away from the origin + m(0) += 25; + m(1) += 25; + + // add this sample to our set of samples we will run k-means + samples.push_back(m); + } + + // tell the kkmeans object we made that we want to run k-means with k set to 3. + // (i.e. we want 3 clusters) + test.set_number_of_centers(3); + + // You need to pick some initial centers for the k-means algorithm. So here + // we will pick a point from each of the classes. + initial_centers.push_back(samples[0]); + initial_centers.push_back(samples[num]); + initial_centers.push_back(samples[num*2]); + + // now run the k-means algorithm on our set of samples. Note that the train function expects + // its arguments to be dlib::matrix objects so since we have our samples in std::vector objects + // we need to turn them into matrix objects. The vector_to_matrix() function does this for us. + test.train(vector_to_matrix(samples),vector_to_matrix(initial_centers)); + + // now loop over all our samples and print out their predicted class. In this example + // all points are correctly identified. + for (unsigned long i = 0; i < samples.size()/3; ++i) + { + cout << test(samples[i]) << " "; + cout << test(samples[i+num]) << " "; + cout << test(samples[i+2*num]) << "\n"; + } + +} + +