source: trunk/c++_tools/classifier/NCC.cc @ 584

Last change on this file since 584 was 584, checked in by Markus Ringnér, 15 years ago

Fixed so NCC and IGP works when there are NaNs? in centroids.

File size: 4.0 KB
Line 
1// $Id$
2
3#include <c++_tools/classifier/NCC.h>
4
5#include <c++_tools/classifier/DataLookup1D.h>
6#include <c++_tools/classifier/DataLookup2D.h>
7#include <c++_tools/classifier/MatrixLookup.h>
8#include <c++_tools/classifier/InputRanker.h>
9#include <c++_tools/classifier/Target.h>
10#include <c++_tools/gslapi/vector.h>
11#include <c++_tools/statistics/Distance.h>
12#include <c++_tools/utility/stl_utility.h>
13
14#include<iostream>
15#include<iterator>
16#include <map>
17#include <cmath>
18
19namespace theplu {
20namespace classifier {
21
22  NCC::NCC(const MatrixLookup& data, const Target& target, 
23           const statistics::Distance& distance) 
24    : SupervisedClassifier(target), distance_(distance), matrix_(data)
25  {   
26  }
27
28  NCC::NCC(const MatrixLookup& data, const Target& target, 
29           const statistics::Distance& distance, 
30           statistics::Score& score, size_t nof_inputs) 
31    : SupervisedClassifier(target, &score, nof_inputs), 
32      distance_(distance), matrix_(data)
33  {
34  }
35
36  NCC::~NCC()   
37  {
38  }
39
40
41  SupervisedClassifier* 
42  NCC::make_classifier(const DataLookup2D& data, 
43                       const Target& target) const 
44  {     
45    const MatrixLookup& tmp = dynamic_cast<const MatrixLookup&>(data);
46
47    NCC* ncc= new NCC(tmp,target,this->distance_);
48    ncc->score_=this->score_;
49    ncc->nof_inputs_=this->nof_inputs_;
50    return ncc;
51  }
52
53
54  bool NCC::train()
55  {
56    // If score is set calculate centroids only for nof_inputs_ number
57    // of top ranked inputs. Otherwise calculate centroids based on
58    // all inputs ( = all rows in data matrix).
59    if(ranker_)
60      delete ranker_;
61    size_t rows=matrix_.rows();
62    if(score_) {
63      // Markus: missing values should not be handled here, but a weight matrix
64      // should be supported throughout the classifier class structure.
65      gslapi::matrix weight(matrix_.rows(),matrix_.columns(),0.0);
66      for(size_t i=0; i<matrix_.rows(); i++) 
67        for(size_t j=0; j<matrix_.columns(); j++) 
68          if(!std::isnan(matrix_(i,j))) 
69            weight(i,j)=1.0;
70      MatrixLookup weightview(weight);
71      ranker_=new InputRanker(matrix_, target_, *score_, weightview);
72      rows=nof_inputs_;
73    }
74    centroids_=gslapi::matrix(rows, target_.nof_classes());
75    gslapi::matrix nof_in_class(rows, target_.nof_classes());
76    for(size_t i=0; i<rows; i++) {
77      for(size_t j=0; j<matrix_.columns(); j++) {
78        double value=matrix_(i,j);
79        if(score_)
80          value=matrix_(ranker_->id(i),j);
81        if(!std::isnan(value)) {
82          centroids_(i,target_(j)) += value;
83          nof_in_class(i,target_(j))++;
84        }
85      }
86    }
87    centroids_.div_elements(nof_in_class);
88    trained_=true;
89    return trained_;
90  }
91
92
93  void NCC::predict(const DataLookup1D& input, 
94                    gslapi::vector& prediction) const
95  {
96    prediction=gslapi::vector(centroids_.columns());   
97    size_t size=input.size();
98    if(ranker_)
99      size=nof_inputs_;
100    gslapi::vector w(size,0);
101    gslapi::vector value(size,0);
102    for(size_t i=0; i<size; i++)  { // take care of missing values
103      value(i)=input(i);
104      if(ranker_)
105        value(i)=input(ranker_->id(i));
106      if(!std::isnan(value(i)))
107        w(i)=1.0;
108    }
109    for(size_t j=0; j<centroids_.columns(); j++) {
110      gslapi::vector centroid=gslapi::vector(centroids_,j,false);
111      gslapi::vector wc(centroid.size(),0);
112      for(size_t i=0; i<centroid.size(); i++)  { // take care of missing values
113        if(!std::isnan(centroid(i)))
114          wc(i)=1.0;
115      }
116      prediction(j)=distance_(value,centroid,w,wc);   
117    }
118  }
119
120
121  void NCC::predict(const DataLookup2D& input,                   
122                    gslapi::matrix& prediction) const
123  {
124    prediction=gslapi::matrix(centroids_.columns(), input.columns());   
125    for(size_t j=0; j<input.columns();j++) {     
126      DataLookup1D in(input,j,false);
127      gslapi::vector out;
128      predict(in,out);
129      prediction.set_column(j,out);
130    }
131  }
132
133 
134  // additional operators
135
136//  std::ostream& operator<< (std::ostream& s, const NCC& ncc) {
137//    std::copy(ncc.classes().begin(), ncc.classes().end(),
138//              std::ostream_iterator<std::map<double, u_int>::value_type>
139//              (s, "\n"));
140//    s << "\n" << ncc.centroids() << "\n";
141//    return s;
142//  }
143
144}} // of namespace classifier and namespace theplu
Note: See TracBrowser for help on using the repository browser.