Fast KDE is now using submodule for organizing parameters
This commit is contained in:
@@ -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 {
|
||||
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user