Fast KDE is now using submodule for organizing parameters

This commit is contained in:
Dongryeol Lee
2008-01-21 01:53:59 +00:00
parent 4ee8579638
commit 0f0eef79f0
5 changed files with 160 additions and 63 deletions
+11 -1
View File
@@ -1,7 +1,17 @@
/**
* @file dataset_scaler.h
*
* This file contains utility functions to scale the given query and
* reference dataset pair.
*
* @author Dongryeol Lee (dongryel)
* @bug No known bugs.
*/
#ifndef DATASET_SCALER_H
#define DATASET_SACLER_H
#include "fastlib/fastlib_int.h"
#include <fastlib/fastlib.h>
class DatasetScaler {
+64 -29
View File
@@ -5,33 +5,61 @@
* for a linkable library component. It implements a rudimentary
* depth-first dual-tree algorithm with finite difference and
* series-expansion approximations, using the formalized GNP framework
* by Ryan and Garry.
* by Ryan and Garry. Currently, it supports a fixed-bandwidth,
* uniform weight kernel density estimation with no multi-bandwidth
* optimizations. We assume that users will be able to cross-validate
* for the optimal bandwidth using a black-box optimizer which is not
* implemented in this code.
*
* For more details on mathematical details, please take a look at the
* published conference papers:
* published conference papers (in chronological order):
*
* @inproceedings{DBLP:conf/sdm/GrayM03,
* author = {Alexander G. Gray and
* Andrew W. Moore},
* title = {Nonparametric Density Estimation: Toward Computational
* Tractability},
* booktitle = {SDM},
* year = {2003},
* ee = {http://www.siam.org/meetings/sdm03/proceedings/sdm03_19.pdf},
* crossref = {DBLP:conf/sdm/2003},
* bibsource = {DBLP, http://dblp.uni-trier.de}
* }
*
* @misc{ gray03rapid,
* author = "A. Gray and A. Moore",
* title = "Rapid evaluation of multiple density models",
* booktitle = "In C. M. Bishop and B. J. Frey, editors,
* Proceedings of the Ninth International Workshop on
* Artificial Intelligence and Statistics",
* year = "2003",
* url = "citeseer.ist.psu.edu/gray03rapid.html"
* }
*
* @incollection{NIPS2005_570,
* title = {Dual-Tree Fast Gauss Transforms},
* author = {Dongryeol Lee and Alexander Gray and Andrew Moore},
* booktitle = {Advances in Neural Information Processing Systems 18},
* editor = {Y. Weiss and B. Sch\"{o}lkopf and J. Platt},
* publisher = {MIT Press},
* address = {Cambridge, MA},
* pages = {747--754},
* year = {2006}
* title = {Dual-Tree Fast Gauss Transforms},
* author = {Dongryeol Lee and Alexander Gray and Andrew Moore},
* booktitle = {Advances in Neural Information Processing Systems 18},
* editor = {Y. Weiss and B. Sch\"{o}lkopf and J. Platt},
* publisher = {MIT Press},
* address = {Cambridge, MA},
* pages = {747--754},
* year = {2006}
* }
*
* @inproceedings{DBLP:conf/uai/LeeG06,
* author = {Dongryeol Lee and
* Alexander G. Gray},
* title = {Faster Gaussian Summation: Theory and Experiment},
* booktitle = {UAI},
* year = {2006},
* crossref = {DBLP:conf/uai/2006},
* bibsource = {DBLP, http://dblp.uni-trier.de}
* author = {Dongryeol Lee and
* Alexander G. Gray},
* title = {Faster Gaussian Summation: Theory and Experiment},
* booktitle = {UAI},
* year = {2006},
* crossref = {DBLP:conf/uai/2006},
* bibsource = {DBLP, http://dblp.uni-trier.de}
* }
*
* @author Dongryeol Lee (dongryel)
* @see kde_main.cc
* @bugs No known bugs.
*/
#ifndef KDE_H
@@ -120,7 +148,7 @@ class FastKde {
// get bandwidth and relative error
bandwidth_ = fx_param_double_req(module, "bandwidth");
relative_error_ = fx_param_double(module, "tau", 0.1);
relative_error_ = fx_param_double(module, "relative_error", 0.1);
// temporarily initialize these to -1's
dimension_ = reference_count_ = query_count_ = -1;
@@ -390,22 +418,17 @@ class FastKde {
summary_result_.Init(param);
}
void Init() {
}
void Init(const TKernelAux &ka) {
farfield_expansion_.Init(ka);
local_expansion_.Init(ka);
}
void Init(const Matrix& dataset, index_t &start, index_t &count) {
Init();
}
void Init(const Matrix& dataset, index_t &start, index_t &count,
const KdeStat& left_stat,
const KdeStat& right_stat) {
Init();
}
void Init(const Vector& center, const TKernelAux &ka) {
@@ -425,6 +448,9 @@ class FastKde {
////////// Private Member Variables //////////
/** module used to pass parameters into the FastKde object */
struct datanode *module_;
/** parameter list */
Param parameters_;
@@ -861,6 +887,8 @@ class FastKde {
FastKde() {
qroot_ = NULL;
rroot_ = NULL;
DEBUG_POISON_PTR(module_);
}
/** destructor */
@@ -956,10 +984,17 @@ class FastKde {
/** initialize query and reference sets and construct trees */
void Init(Matrix &queries, Matrix &references,
bool queries_equal_references) {
bool queries_equal_references, struct datanode *module_in) {
// the datasets need to have the same dimensionality
DEBUG_SAME_SIZE(queries.n_rows(), references.n_rows());
// set class module pointer to the incoming one
module_ = module_in;
// read in the number of points owned by a leaf
int leaflen = fx_param_int(NULL, "leaflen", 20);
int leaflen = fx_param_int(module_, "leaflen", 20);
DEBUG_ASSERT(leaflen > 0);
// copy the datasetsread reference dataset
rset_.Copy(references);
@@ -975,7 +1010,7 @@ class FastKde {
rset_weights_.SetAll(1);
// construct query and reference trees
fx_timer_start(NULL, "tree_d");
fx_timer_start(module_, "tree_building");
rroot_ = tree::MakeKdTreeMidpoint<Tree>(rset_, leaflen,
&old_from_new_references_, NULL);
@@ -987,7 +1022,7 @@ class FastKde {
qroot_ = tree::MakeKdTreeMidpoint<Tree>(qset_, leaflen,
&old_from_new_queries_, NULL);
}
fx_timer_stop(NULL, "tree_d");
fx_timer_stop(module_, "tree_building");
// initialize the density lists
q_results_.Init(qset_.n_cols());
@@ -996,7 +1031,7 @@ class FastKde {
}
// initialize parameter list
parameters_.Init(fx_root);
parameters_.Init(module_);
parameters_.reference_count_ = rset_.n_cols();
parameters_.query_count_ = qset_.n_cols();
parameters_.FinalizeInit(fx_root, rset_.n_rows());
@@ -1008,7 +1043,7 @@ class FastKde {
FILE *stream = stdout;
const char *fname = NULL;
if((fname = fx_param_str(NULL, "fast_kde_output", NULL)) != NULL) {
if((fname = fx_param_str(module_, "fast_kde_output", NULL)) != NULL) {
stream = fopen(fname, "w+");
}
for(index_t q = 0; q < qset_.n_cols(); q++) {
+28 -20
View File
@@ -9,6 +9,13 @@ int main(int argc, char *argv[]) {
////////// READING PARAMETERS AND LOADING DATA /////////////////////
// FASTexec organizes parameters and results into submodules. Think
// of this as creating a new folder named "kde_module" under the
// root directory (NULL) for the Kde object to work inside. Here,
// we initialize it with all parameters defined "--kde/...=...".
struct datanode* kde_module =
fx_submodule(NULL, "kde", "kde_module");
// The reference data file is a required parameter.
const char* references_file_name = fx_param_str_req(NULL, "data");
@@ -17,10 +24,9 @@ int main(int argc, char *argv[]) {
fx_param_str(NULL, "query", references_file_name);
// flag for determining whether to compute naively
bool do_naive = fx_param_exists(NULL, "do_naive");
bool do_naive = fx_param_exists(kde_module, "do_naive");
// FASTlib classes only poison data in their default constructors;
// declarations must be followed by Init or an equivalent function.
// query and reference datasets
Matrix references;
Matrix queries;
@@ -36,26 +42,27 @@ int main(int argc, char *argv[]) {
else {
data::Load(queries_file_name, &queries);
}
// confirm whether the user asked for scaling of the dataset
if(!strcmp(fx_param_str(NULL, "scaling", "none"), "range")) {
DatasetScaler::ScaleDataByMinMax(queries, references,
queries_equal_references);
if(!strcmp(fx_param_str(kde_module, "scaling", "none"), "range")) {
DatasetScaler::ScaleDataByMinMax(queries, references,
queries_equal_references);
}
if(!strcmp(fx_param_str(NULL, "kernel", "gaussian"), "gaussian")) {
if(!strcmp(fx_param_str(kde_module, "kernel", "gaussian"), "gaussian")) {
Vector fast_kde_results;
// for O(p^D) expansion
if(fx_param_exists(NULL, "multiplicative_expansion")) {
if(fx_param_exists(kde_module, "multiplicative_expansion")) {
printf("O(p^D) expansion KDE\n");
FastKde<GaussianKernelMultAux> fast_kde;
fast_kde.Init(queries, references, queries_equal_references);
fast_kde.Init(queries, references, queries_equal_references,
kde_module);
fast_kde.Compute();
if(fx_param_exists(NULL, "fast_kde_output")) {
if(fx_param_exists(kde_module, "fast_kde_output")) {
fast_kde.PrintDebug();
}
@@ -67,10 +74,11 @@ int main(int argc, char *argv[]) {
printf("O(D^p) expansion KDE\n");
FastKde<GaussianKernelAux> fast_kde;
fast_kde.Init(queries, references, queries_equal_references);
fast_kde.Init(queries, references, queries_equal_references,
kde_module);
fast_kde.Compute();
if(fx_param_exists(NULL, "fast_kde_output")) {
if(fx_param_exists(kde_module, "fast_kde_output")) {
fast_kde.PrintDebug();
}
@@ -79,22 +87,22 @@ int main(int argc, char *argv[]) {
if(do_naive) {
NaiveKde<GaussianKernel> naive_kde;
naive_kde.Init(queries, references);
naive_kde.Init(queries, references, kde_module);
naive_kde.Compute();
if(fx_param_exists(NULL, "naive_kde_output")) {
if(fx_param_exists(kde_module, "naive_kde_output")) {
naive_kde.PrintDebug();
}
naive_kde.ComputeMaximumRelativeError(fast_kde_results);
}
}
else if(!strcmp(fx_param_str(NULL, "kernel", "epan"), "epan")) {
else if(!strcmp(fx_param_str(kde_module, "kernel", "epan"), "epan")) {
FastKde<EpanKernelAux> fast_kde;
fast_kde.Init(queries, references, queries_equal_references);
fast_kde.Init(queries, references, queries_equal_references, kde_module);
fast_kde.Compute();
if(fx_param_exists(NULL, "fast_kde_output")) {
if(fx_param_exists(kde_module, "fast_kde_output")) {
fast_kde.PrintDebug();
}
Vector fast_kde_results;
@@ -102,10 +110,10 @@ int main(int argc, char *argv[]) {
if(do_naive) {
NaiveKde<EpanKernel> naive_kde;
naive_kde.Init(queries, references);
naive_kde.Init(queries, references, kde_module);
naive_kde.Compute();
if(fx_param_exists(NULL, "naive_kde_output")) {
if(fx_param_exists(kde_module, "naive_kde_output")) {
naive_kde.PrintDebug();
}
naive_kde.ComputeMaximumRelativeError(fast_kde_results);
+15 -11
View File
@@ -8,6 +8,9 @@ class NaiveKde {
private:
/** pointer to the module */
struct datanode *module_;
/** query dataset */
Matrix qset_;
@@ -22,16 +25,18 @@ class NaiveKde {
public:
NaiveKde() {
/** constructor - does not do anything */
NaiveKde() {
}
/** destructor - does not do anything */
~NaiveKde() {
}
void Compute() {
printf("\nStarting naive KDE...\n");
fx_timer_start(NULL, "naive_kde_compute");
fx_timer_start(module_, "naive_kde_compute");
// compute unnormalized sum
for(index_t q = 0; q < qset_.n_cols(); q++) {
@@ -51,22 +56,21 @@ class NaiveKde {
for(index_t q = 0; q < qset_.n_cols(); q++) {
densities_[q] /= norm_const;
}
fx_timer_stop(NULL, "naive_kde_compute");
fx_timer_stop(module_, "naive_kde_compute");
printf("\nNaive KDE completed...\n");
}
void Init() {
densities_.SetZero();
}
void Init(Matrix &qset, Matrix &rset, struct datanode *module_in) {
void Init(Matrix &qset, Matrix &rset) {
// set the datanode module to be the incoming one
module_ = module_in;
// get datasets
qset_.Copy(qset);
rset_.Copy(rset);
// get bandwidth
kernel_.Init(fx_param_double_req(NULL, "bandwidth"));
kernel_.Init(fx_param_double_req(module_, "bandwidth"));
// allocate density storage
densities_.Init(qset.n_cols());
@@ -78,8 +82,8 @@ class NaiveKde {
FILE *stream = stdout;
const char *fname = NULL;
if(fx_param_exists(NULL, "naive_kde_output")) {
fname = fx_param_str(NULL, "naive_kde_output", NULL);
if(fx_param_exists(module_, "naive_kde_output")) {
fname = fx_param_str(module_, "naive_kde_output", NULL);
stream = fopen(fname, "w+");
}
for(index_t q = 0; q < qset_.n_cols(); q++) {
@@ -103,7 +107,7 @@ class NaiveKde {
}
}
fx_format_result(NULL, "maxium_relative_error_for_fast_KDE", "%g",
fx_format_result(module_, "maximum_relative_error_for_fast_KDE", "%g",
max_rel_err);
}
+42 -2
View File
@@ -1,11 +1,51 @@
/**
* @file thor_kde.h
*
* This file contains an implementation of kernel density estimation
* (vanilla finite-difference only) for a linkable library component
* using the THOR library by Ryan and Garry. Currently, it supports a
* fixed-bandwidth, uniform weight kernel density estimation with no
* multi-bandwidth optimizations. We assume that users will be able to
* cross-validate for the optimal bandwidth using a black-box
* optimizer which is not implemented in this code.
*
* For more details on mathematical details, please take a look at the
* published conference papers (in chronological order):
*
* @inproceedings{DBLP:conf/sdm/GrayM03,
* author = {Alexander G. Gray and
* Andrew W. Moore},
* title = {Nonparametric Density Estimation: Toward Computational
* Tractability},
* booktitle = {SDM},
* year = {2003},
* ee = {http://www.siam.org/meetings/sdm03/proceedings/sdm03_19.pdf},
* crossref = {DBLP:conf/sdm/2003},
* bibsource = {DBLP, http://dblp.uni-trier.de}
* }
*
* @misc{ gray03rapid,
* author = "A. Gray and A. Moore",
* title = "Rapid evaluation of multiple density models",
* booktitle = "In C. M. Bishop and B. J. Frey, editors,
* Proceedings of the Ninth International Workshop on
* Artificial Intelligence and Statistics",
* year = "2003",
* url = "citeseer.ist.psu.edu/gray03rapid.html"
* }
*
* @author Dongryeol Lee (dongryel)
* @see thor_kde_main.cc
* @bugs No known bugs.
*/
#ifndef THOR_KDE_H
#define THOR_KDE_H
#include "fastlib/fastlib_int.h"
#include <fastlib/fastlib.h>
#include "thor/thor.h"
#include "u/dongryel/series_expansion/kernel_aux.h"
/**
* THOR-based KDE
*/