Go to the documentation of this file.00001
00002 #include "clsfy_rbf_parzen.h"
00003
00004
00005
00006
00007
00008 #include <vcl_string.h>
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cmath.h>
00011 #include <vcl_cassert.h>
00012 #include <vsl/vsl_binary_io.h>
00013 #include <vsl/vsl_vector_io.h>
00014 #include <vnl/io/vnl_io_vector.h>
00015
00016
00017
00018 unsigned clsfy_rbf_parzen::classify(const vnl_vector<double> &input) const
00019 {
00020 const unsigned nTrainingVecs = trainInputs_.size();
00021 double sumWeightings=0.0, sumPredictions=0.0, weight;
00022
00023 if (power_ == 2)
00024 for (unsigned i = 0; i < nTrainingVecs; i++)
00025 {
00026 weight = vcl_exp(gamma_ * vnl_vector_ssd(input, trainInputs_[i]));
00027
00028 sumWeightings += weight;
00029 sumPredictions += weight * trainOutputs_[i];
00030 }
00031 else
00032 {
00033 double gamma = - 0.5 * vcl_pow(-2*gamma_, 0.5*power_);
00034 double p = power_ / 2.0;
00035 for (unsigned i = 0; i < nTrainingVecs; i++)
00036 {
00037 weight = vcl_exp(gamma * vcl_pow(vnl_vector_ssd(input, trainInputs_[i]), p) );
00038
00039 sumWeightings += weight;
00040 sumPredictions += weight * trainOutputs_[i];
00041 }
00042 }
00043 return sumPredictions * 2 > sumWeightings ? 1 : 0;
00044 }
00045
00046
00047
00048 void clsfy_rbf_parzen::set(const vcl_vector<vnl_vector<double> > &inputs,
00049 const vcl_vector<unsigned> &outputs)
00050 {
00051 assert(*vcl_max_element(outputs.begin(), outputs.end()) <= 1);
00052 assert(inputs.size() == outputs.size());
00053 trainInputs_ = inputs;
00054 trainOutputs_ = outputs;
00055 }
00056
00057
00058
00059
00060 void clsfy_rbf_parzen::class_probabilities(vcl_vector<double>& outputs,
00061 vnl_vector<double>const& input) const
00062 {
00063 const unsigned nTrainingVecs = trainInputs_.size();
00064 double sumWeightings=0.0, sumPredictions=0.0, weight;
00065
00066 if (power_ == 2)
00067 for (unsigned i = 0; i < nTrainingVecs; i++)
00068 {
00069 weight = vcl_exp(gamma_ * vnl_vector_ssd(input, trainInputs_[i]));
00070
00071 sumWeightings += weight;
00072 sumPredictions += weight * trainOutputs_[i];
00073 }
00074 else
00075 {
00076 double gamma = - 0.5 * vcl_pow(-2*gamma_, 0.5*power_);
00077 double p = power_ / 2.0;
00078 for (unsigned i = 0; i < nTrainingVecs; i++)
00079 {
00080 weight = vcl_exp(gamma * vcl_pow(vnl_vector_ssd(input, trainInputs_[i]), p) );
00081
00082 sumWeightings += weight;
00083 sumPredictions += weight * trainOutputs_[i];
00084 }
00085 }
00086 outputs.resize(1);
00087 outputs[0] = sumPredictions / sumWeightings;
00088 }
00089
00090
00091
00092 double clsfy_rbf_parzen::weightings(const vnl_vector<double> &input) const
00093 {
00094 const unsigned nTrainingVecs = trainInputs_.size();
00095 double sumWeightings=0.0;
00096
00097 if (power_ == 2)
00098 for (unsigned i = 0; i < nTrainingVecs; i++)
00099 sumWeightings += vcl_exp(gamma_ * vnl_vector_ssd(input, trainInputs_[i]));
00100 else
00101 {
00102 double gamma = - 0.5 * vcl_pow(-2*gamma_, 0.5*power_);
00103 double p = power_ / 2.0;
00104 for (unsigned i = 0; i < nTrainingVecs; i++)
00105 sumWeightings += vcl_exp(gamma * vcl_pow(vnl_vector_ssd(input, trainInputs_[i]), p) );
00106 }
00107
00108 return sumWeightings;
00109 }
00110
00111
00112
00113 unsigned clsfy_rbf_parzen::n_dims() const
00114 {
00115 if (trainInputs_.size() == 0)
00116 return 0;
00117 else
00118 return trainInputs_[0].size();
00119 }
00120
00121
00122
00123
00124 double clsfy_rbf_parzen::log_l(const vnl_vector<double> &input) const
00125 {
00126 vcl_vector<double> outputs(1);
00127 class_probabilities(outputs, input);
00128 double prob = outputs[0];
00129 return vcl_log(prob/(1.0-prob));
00130 }
00131
00132
00133
00134
00135 void clsfy_rbf_parzen::set_rbf_width(double sigma)
00136 {
00137 assert(sigma > 0.0);
00138 width_ = sigma;
00139 gamma_ = -0.5/(sigma*sigma);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149 void clsfy_rbf_parzen::set_power(double p)
00150 {
00151 assert(p > 0.0);
00152 power_ = p;
00153 }
00154
00155
00156
00157
00158 vcl_string clsfy_rbf_parzen::is_a() const
00159 {
00160 return vcl_string("clsfy_rbf_parzen");
00161 }
00162
00163
00164
00165 bool clsfy_rbf_parzen::is_class(vcl_string const& s) const
00166 {
00167 return s == clsfy_rbf_parzen::is_a() || clsfy_classifier_base::is_class(s);
00168 }
00169
00170
00171
00172 short clsfy_rbf_parzen::version_no() const
00173 {
00174 return 2;
00175 }
00176
00177
00178
00179 clsfy_classifier_base* clsfy_rbf_parzen::clone() const
00180 {
00181 return new clsfy_rbf_parzen(*this);
00182 }
00183
00184
00185
00186 void clsfy_rbf_parzen::print_summary(vcl_ostream& os) const
00187 {
00188 os << trainInputs_.size() << " training samples, "
00189 << "Gaussian Width=" << rbf_width() << ", power=" << power_ << '\n';
00190 }
00191
00192
00193
00194 void clsfy_rbf_parzen::b_write(vsl_b_ostream& bfs) const
00195 {
00196 vsl_b_write(bfs,version_no());
00197 vsl_b_write(bfs,width_);
00198 vsl_b_write(bfs,power_);
00199 vsl_b_write(bfs,trainOutputs_);
00200 vsl_b_write(bfs,trainInputs_);
00201 }
00202
00203
00204
00205 void clsfy_rbf_parzen::b_read(vsl_b_istream& bfs)
00206 {
00207 if (!bfs) return;
00208
00209 short version;
00210 vsl_b_read(bfs,version);
00211 switch (version)
00212 {
00213 case (1):
00214 vsl_b_read(bfs,gamma_);
00215 width_ = vcl_sqrt(-0.5/gamma_);
00216 vsl_b_read(bfs,power_);
00217 vsl_b_read(bfs,trainOutputs_);
00218 vsl_b_read(bfs,trainInputs_);
00219 break;
00220 case(2):
00221 vsl_b_read(bfs,width_);
00222 gamma_ = -0.5/(width_*width_);
00223 vsl_b_read(bfs,power_);
00224 vsl_b_read(bfs,trainOutputs_);
00225 vsl_b_read(bfs,trainInputs_);
00226 break;
00227 default:
00228 vcl_cerr << "I/O ERROR: clsfy_rbf_parzen::b_read(vsl_b_istream&)\n"
00229 << " Unknown version number "<< version << "\n";
00230 bfs.is().clear(vcl_ios::badbit);
00231 }
00232 }