yat/classifier/KernelLookup.h

Code
Comments
Other
Rev Date Author Line
680 11 Oct 06 jari 1 #ifndef _theplu_yat_classifier_kernel_lookup_
680 11 Oct 06 jari 2 #define _theplu_yat_classifier_kernel_lookup_
330 01 Jun 05 peter 3
675 10 Oct 06 jari 4 // $Id$
675 10 Oct 06 jari 5
675 10 Oct 06 jari 6 /*
4359 23 Aug 23 peter 7   Copyright (C) 2005, 2006 Jari Häkkinen, Peter Johansson
4359 23 Aug 23 peter 8   Copyright (C) 2007 Peter Johansson
4359 23 Aug 23 peter 9   Copyright (C) 2008 Jari Häkkinen, Peter Johansson
4359 23 Aug 23 peter 10   Copyright (C) 2010, 2012, 2020 Peter Johansson
675 10 Oct 06 jari 11
1437 25 Aug 08 peter 12   This file is part of the yat library, http://dev.thep.lu.se/yat
675 10 Oct 06 jari 13
675 10 Oct 06 jari 14   The yat library is free software; you can redistribute it and/or
675 10 Oct 06 jari 15   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 16   published by the Free Software Foundation; either version 3 of the
675 10 Oct 06 jari 17   License, or (at your option) any later version.
675 10 Oct 06 jari 18
675 10 Oct 06 jari 19   The yat library is distributed in the hope that it will be useful,
675 10 Oct 06 jari 20   but WITHOUT ANY WARRANTY; without even the implied warranty of
675 10 Oct 06 jari 21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
675 10 Oct 06 jari 22   General Public License for more details.
675 10 Oct 06 jari 23
675 10 Oct 06 jari 24   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 25   along with yat. If not, see <http://www.gnu.org/licenses/>.
675 10 Oct 06 jari 26 */
675 10 Oct 06 jari 27
680 11 Oct 06 jari 28 #include "Kernel.h"
1110 19 Feb 08 peter 29 #include "yat/utility/Container2DIterator.h"
1134 23 Feb 08 peter 30 #include "yat/utility/Index.h"
1080 13 Feb 08 peter 31 #include "yat/utility/iterator_traits.h"
1066 10 Feb 08 peter 32 #include "yat/utility/StrideIterator.h"
675 10 Oct 06 jari 33
4019 06 Nov 20 peter 34 #include <memory>
2861 03 Oct 12 peter 35
330 01 Jun 05 peter 36 namespace theplu {
680 11 Oct 06 jari 37 namespace yat {
450 15 Dec 05 peter 38 namespace classifier {
330 01 Jun 05 peter 39
330 01 Jun 05 peter 40   class KernelFunction;
1133 23 Feb 08 peter 41   class MatrixLookup;
1133 23 Feb 08 peter 42   class MatrixLookupWeighted;
330 01 Jun 05 peter 43
517 21 Feb 06 peter 44   ///
592 24 Aug 06 peter 45   /// @brief Lookup into Kernel
517 21 Feb 06 peter 46   ///
592 24 Aug 06 peter 47   /// This is the KernelLookup class to be used together with kernel
592 24 Aug 06 peter 48   /// methods such as Support Vector Machines (SVM). The class does
592 24 Aug 06 peter 49   /// not contain any data or values, but rather is a lookup into a
592 24 Aug 06 peter 50   /// Kernel object. Each row and each column corresponds to a row and
1206 05 Mar 08 peter 51   /// a column in the Kernel, respectively. This design allows for fast
592 24 Aug 06 peter 52   /// creation of sub-kernels, which is a common operation in most
592 24 Aug 06 peter 53   /// traning/validation procedures.
592 24 Aug 06 peter 54   ///
1206 05 Mar 08 peter 55   /// A KernelLookup can be created directly from a Kernel or from
1206 05 Mar 08 peter 56   /// another KernelLookup. In the latter case, the resulting
592 24 Aug 06 peter 57   /// KernelLookup is looking directly into the underlying Kernel to
592 24 Aug 06 peter 58   /// avoid multiple lookups.
592 24 Aug 06 peter 59   ///
592 24 Aug 06 peter 60   /// There is a possibility to set the KernelLookup as owner of the
826 19 Mar 07 peter 61   /// underlying kernel. This implies that underlying kernel is deleted
826 19 Mar 07 peter 62   /// in destructor of MatrixLookup, but only if there is no other
826 19 Mar 07 peter 63   /// owner of the underlying kernel. A reference counter is used to
826 19 Mar 07 peter 64   /// keep track of number of owners. Ownership is copied in copy
826 19 Mar 07 peter 65   /// constructors and assignments.
592 24 Aug 06 peter 66   ///
1132 23 Feb 08 peter 67   class KernelLookup
517 21 Feb 06 peter 68   {
517 21 Feb 06 peter 69
517 21 Feb 06 peter 70   public:
1549 06 Oct 08 peter 71     /**
1552 06 Oct 08 peter 72        value_type is double
1552 06 Oct 08 peter 73
1552 06 Oct 08 peter 74        \since New in yat 0.5
1552 06 Oct 08 peter 75      */
1552 06 Oct 08 peter 76     typedef double value_type;
1552 06 Oct 08 peter 77
1552 06 Oct 08 peter 78     /**
1549 06 Oct 08 peter 79        const_reference type is const double
1549 06 Oct 08 peter 80
1549 06 Oct 08 peter 81        \since New in yat 0.5
1549 06 Oct 08 peter 82      */
1549 06 Oct 08 peter 83     typedef const double const_reference;
1549 06 Oct 08 peter 84
1066 10 Feb 08 peter 85     /// 'Read Only' iterator
1080 13 Feb 08 peter 86     typedef utility::StrideIterator<
2374 12 Dec 10 peter 87     utility::Container2DIterator<const KernelLookup, const double,
1565 10 Oct 08 peter 88                                  const_reference> >
1066 10 Feb 08 peter 89     const_iterator;
720 26 Dec 06 jari 90
1125 22 Feb 08 peter 91     /**
1125 22 Feb 08 peter 92        'Read only' iterator intended to iterate over a column
1125 22 Feb 08 peter 93      */
1105 18 Feb 08 peter 94     typedef const_iterator const_column_iterator;
1125 22 Feb 08 peter 95
1125 22 Feb 08 peter 96     /**
1125 22 Feb 08 peter 97        'Read only' iterator intended to iterate over a row
1125 22 Feb 08 peter 98      */
1105 18 Feb 08 peter 99     typedef const_iterator const_row_iterator;
1105 18 Feb 08 peter 100
463 16 Dec 05 peter 101     ///
592 24 Aug 06 peter 102     /// @brief Constructor a Lookup into a Kernel
463 16 Dec 05 peter 103     ///
592 24 Aug 06 peter 104     /// Constructs a KernelLookup corresponding to the Kernel @a
592 24 Aug 06 peter 105     /// kernel. By default @a owner is set to false, which means
826 19 Mar 07 peter 106     /// KernelLookup does not own the underlying Kernel.
545 06 Mar 06 peter 107     ///
536 03 Mar 06 peter 108     /// @note If underlying Kernel goes out of scope or is deleted, the
592 24 Aug 06 peter 109     /// KernelLookup becomes invalid and the result of further use is
536 03 Mar 06 peter 110     /// undefined.
536 03 Mar 06 peter 111     ///
640 07 Sep 06 peter 112     /// @note Do not construct two KernelLookups from the same @a
640 07 Sep 06 peter 113     /// kernel with @a owner set to true because that will cause
640 07 Sep 06 peter 114     /// multiple deletion of @a kernel.
640 07 Sep 06 peter 115     ///
592 24 Aug 06 peter 116     KernelLookup(const Kernel& kernel, const bool owner=false);
463 16 Dec 05 peter 117
4200 19 Aug 22 peter 118     ///
592 24 Aug 06 peter 119     /// @brief Constructing a Lookup into a subKernel
330 01 Jun 05 peter 120     ///
592 24 Aug 06 peter 121     /// Creating a Lookup into parts of the Kernel. In the created
597 28 Aug 06 markus 122     /// Lookup the element in the \f$ i \f$ th row in the \f$ j \f$ th
592 24 Aug 06 peter 123     /// column is identical to the element in row row[i] and columns
592 24 Aug 06 peter 124     /// column[j] in the underlying @a kernel. If @a owner is set to
592 24 Aug 06 peter 125     /// true yhe underlying @a kernel is destroyed in the destructor.
592 24 Aug 06 peter 126     ///
536 03 Mar 06 peter 127     /// @note If @a kernel goes out of scope or is deleted, the
536 03 Mar 06 peter 128     /// returned pointer becomes invalid and the result of further use is
536 03 Mar 06 peter 129     /// undefined.
536 03 Mar 06 peter 130     ///
1127 22 Feb 08 peter 131     /// @note For training usage row index shall always be equal to
1127 22 Feb 08 peter 132     /// column index.
461 16 Dec 05 peter 133     ///
4200 19 Aug 22 peter 134     KernelLookup(const Kernel& kernel, const utility::Index& row,
1134 23 Feb 08 peter 135                  const utility::Index& column, const bool owner=false);
720 26 Dec 06 jari 136
537 05 Mar 06 peter 137     ///
4200 19 Aug 22 peter 138     /// @brief Copy constructor.
4200 19 Aug 22 peter 139     ///
592 24 Aug 06 peter 140     /// A Lookup is created looking into the
4200 19 Aug 22 peter 141     /// same underlying Kernel as @a kl is looking into.
592 24 Aug 06 peter 142     ///
826 19 Mar 07 peter 143     /// If \a kl is owner of underlying data, constructed
826 19 Mar 07 peter 144     /// KernelLookup will also be set as owner of underlying data.
826 19 Mar 07 peter 145     ///
592 24 Aug 06 peter 146     KernelLookup(const KernelLookup& kl);
537 05 Mar 06 peter 147
537 05 Mar 06 peter 148
592 24 Aug 06 peter 149     ///
4200 19 Aug 22 peter 150     /// @brief Contructing a sub-KernelLookup.
4200 19 Aug 22 peter 151     ///
482 02 Jan 06 peter 152     /// Contructor building a sub-KernelLookup from a KernelLookup
1127 22 Feb 08 peter 153     /// defined by row index vector and column index vector. In the
597 28 Aug 06 markus 154     /// created Lookup the element in the \f$ i \f$ th row in the
597 28 Aug 06 markus 155     /// \f$ j \f$ th column is identical to the element in row row[i] and
592 24 Aug 06 peter 156     /// columns column[j] in the copied @a kl. The resulting
592 24 Aug 06 peter 157     /// KernelLookup is independent of the old KernelLookup, but is
592 24 Aug 06 peter 158     /// undefined in case underlying Kernel is destroyed.
482 02 Jan 06 peter 159     ///
826 19 Mar 07 peter 160     /// If \a kl is owner of underlying data, constructed
826 19 Mar 07 peter 161     /// KernelLookup will also be set as owner of underlying data.
826 19 Mar 07 peter 162     ///
482 02 Jan 06 peter 163     /// @note For training usage row index shall always be equal to
482 02 Jan 06 peter 164     /// column index.
482 02 Jan 06 peter 165     ///
4200 19 Aug 22 peter 166     KernelLookup(const KernelLookup& kl, const utility::Index& row,
1134 23 Feb 08 peter 167                  const utility::Index& column);
720 26 Dec 06 jari 168
654 22 Sep 06 peter 169     ///
1206 05 Mar 08 peter 170     /// Constructor taking the column (default) or row index as
654 22 Sep 06 peter 171     /// input. If @a row is false the created KernelLookup will have
654 22 Sep 06 peter 172     /// equally many rows as @a kernel.
654 22 Sep 06 peter 173     ///
826 19 Mar 07 peter 174     /// If \a kl is owner of underlying data, constructed
826 19 Mar 07 peter 175     /// KernelLookup will also be set as owner of underlying data.
826 19 Mar 07 peter 176     ///
592 24 Aug 06 peter 177     /// @note If underlying kernel goes out of scope or is deleted, the
559 11 Mar 06 peter 178     /// KernelLookup becomes invalid and the result of further use is
559 11 Mar 06 peter 179     /// undefined.
330 01 Jun 05 peter 180     ///
4200 19 Aug 22 peter 181     KernelLookup(const KernelLookup& kl, const utility::Index&,
559 11 Mar 06 peter 182                  const bool row=false);
559 11 Mar 06 peter 183
559 11 Mar 06 peter 184     ///
537 05 Mar 06 peter 185     /// @brief Destructor
537 05 Mar 06 peter 186     ///
826 19 Mar 07 peter 187     /// Deletes underlying Kernel if KernelLookup owns it and there is
826 19 Mar 07 peter 188     /// no other owner.
537 05 Mar 06 peter 189     ///
537 05 Mar 06 peter 190     virtual ~KernelLookup(void);
330 01 Jun 05 peter 191
1066 10 Feb 08 peter 192     /**
1066 10 Feb 08 peter 193        Iterator iterates along a row. When end of row is reached it
1066 10 Feb 08 peter 194        jumps to beginning of next row.
1066 10 Feb 08 peter 195
1066 10 Feb 08 peter 196        \return const_iterator pointing to upper-left element.
1066 10 Feb 08 peter 197      */
1066 10 Feb 08 peter 198     const_iterator begin(void) const;
1066 10 Feb 08 peter 199
1066 10 Feb 08 peter 200     /**
1066 10 Feb 08 peter 201        Iterator iterates along a column.
1066 10 Feb 08 peter 202
1066 10 Feb 08 peter 203        \return iterator pointing to first element of column \a i.
1066 10 Feb 08 peter 204      */
1105 18 Feb 08 peter 205     const_column_iterator begin_column(size_t) const;
1066 10 Feb 08 peter 206
1066 10 Feb 08 peter 207     /**
1066 10 Feb 08 peter 208        Iterator iterates along a column.
1066 10 Feb 08 peter 209
1066 10 Feb 08 peter 210        \return const_iterator pointing to first element of column \a i.
1066 10 Feb 08 peter 211      */
1105 18 Feb 08 peter 212     const_row_iterator begin_row(size_t) const;
1066 10 Feb 08 peter 213
1132 23 Feb 08 peter 214     /**
1132 23 Feb 08 peter 215        \return number of columns
1132 23 Feb 08 peter 216     */
1132 23 Feb 08 peter 217     size_t columns(void) const;
1132 23 Feb 08 peter 218
330 01 Jun 05 peter 219     ///
826 19 Mar 07 peter 220     /// Each column in returned DataLookup corresponds to the column
720 26 Dec 06 jari 221     /// in KernelLookup.
482 02 Jan 06 peter 222     ///
826 19 Mar 07 peter 223     /// \return data that KernelLookup is built upon.
826 19 Mar 07 peter 224     ///
1165 26 Feb 08 peter 225     /// \throw if KernelLookup is weighted
482 02 Jan 06 peter 226     ///
1206 05 Mar 08 peter 227     MatrixLookup data(void) const;
482 02 Jan 06 peter 228
1165 26 Feb 08 peter 229     ///
1165 26 Feb 08 peter 230     /// Each column in returned DataLookup corresponds to the column
1165 26 Feb 08 peter 231     /// in KernelLookup.
1165 26 Feb 08 peter 232     ///
1165 26 Feb 08 peter 233     /// \return data that KernelLookup is built upon.
1165 26 Feb 08 peter 234     ///
1165 26 Feb 08 peter 235     /// \throw if KernelLookup is unweighted
1165 26 Feb 08 peter 236     ///
1206 05 Mar 08 peter 237     MatrixLookupWeighted data_weighted(void) const;
1165 26 Feb 08 peter 238
720 26 Dec 06 jari 239     /**
720 26 Dec 06 jari 240        Function to calculate a new Kernel element using the underlying
826 19 Mar 07 peter 241        KernelFunction. The value is calculated between @a vec and the
826 19 Mar 07 peter 242        data vector of the \a i th sample, in other words, the
826 19 Mar 07 peter 243        sample corresponding to the \a i th row.
720 26 Dec 06 jari 244     */
720 26 Dec 06 jari 245     double element(const DataLookup1D& vec, size_t i) const;
482 02 Jan 06 peter 246
720 26 Dec 06 jari 247     /**
720 26 Dec 06 jari 248        Function to calculate a new Kernel element using the underlying
720 26 Dec 06 jari 249        KernelFunction. The value is calulated between @a vec and the
720 26 Dec 06 jari 250        data vector of the \f$ i \f$ th sample, in other words, the
720 26 Dec 06 jari 251        sample corresponding to the \f$ i \f$ th row or \f$ i \f$ th
720 26 Dec 06 jari 252        column. In case KernelLookup is a sub-Kernel and not symmetric,
720 26 Dec 06 jari 253        the kernel value is calculated between @a vec and the data
720 26 Dec 06 jari 254        vector corresponding to \f$ i \f$ th row.
720 26 Dec 06 jari 255     */
720 26 Dec 06 jari 256     double element(const DataLookupWeighted1D& vec, size_t i) const;
482 02 Jan 06 peter 257
658 25 Sep 06 peter 258     /**
1066 10 Feb 08 peter 259        \return const_iterator pointing to end of matrix
1066 10 Feb 08 peter 260      */
1066 10 Feb 08 peter 261     const_iterator end(void) const;
1066 10 Feb 08 peter 262
1066 10 Feb 08 peter 263     /**
1066 10 Feb 08 peter 264        \return const_iterator pointing to end of column \a i
1066 10 Feb 08 peter 265      */
1105 18 Feb 08 peter 266     const_column_iterator end_column(size_t) const;
1066 10 Feb 08 peter 267
1066 10 Feb 08 peter 268     /**
1066 10 Feb 08 peter 269        \return const_iterator pointing to end of row \a i
1066 10 Feb 08 peter 270      */
1105 18 Feb 08 peter 271     const_row_iterator end_row(size_t) const;
1066 10 Feb 08 peter 272
1066 10 Feb 08 peter 273     /**
1132 23 Feb 08 peter 274        \return number of rows
1132 23 Feb 08 peter 275     */
1132 23 Feb 08 peter 276     size_t rows(void) const;
1132 23 Feb 08 peter 277
1132 23 Feb 08 peter 278     /**
720 26 Dec 06 jari 279        Each element in returned KernelLookup is calculated using only
720 26 Dec 06 jari 280        selected features (defined by @a index). Each element
720 26 Dec 06 jari 281        corresponds to the same pair of samples as in the original
720 26 Dec 06 jari 282        KernelLookup.
720 26 Dec 06 jari 283     */
1206 05 Mar 08 peter 284     KernelLookup selected(const utility::Index& index) const;
4200 19 Aug 22 peter 285
720 26 Dec 06 jari 286     /**
826 19 Mar 07 peter 287        This function is useful when predicting on an independent data
658 25 Sep 06 peter 288        set using a kernel-based classifier. In returned KernelLookup
658 25 Sep 06 peter 289        column \f$ i \f$ corresponds to column \f$ i \f$ in @a
658 25 Sep 06 peter 290        data. Row \f$ i \f$ in returned KernelLookup corresponds to
658 25 Sep 06 peter 291        same sample as row \f$ i \f$ in @a this. In other words, this
658 25 Sep 06 peter 292        function returns a KernelLookup containing the kernel elements
658 25 Sep 06 peter 293        between the passed @a data and the internal underlying data @a
658 25 Sep 06 peter 294        this was built from.
658 25 Sep 06 peter 295     */
1206 05 Mar 08 peter 296     KernelLookup test_kernel(const MatrixLookup& data) const;
607 29 Aug 06 peter 297
658 25 Sep 06 peter 298     /**
826 19 Mar 07 peter 299        This function is useful when predicting on an independent data
658 25 Sep 06 peter 300        set using a kernel-based classifier. In returned KernelLookup
658 25 Sep 06 peter 301        column \f$ i \f$ corresponds to column \f$ i \f$ in @a
658 25 Sep 06 peter 302        data. Row \f$ i \f$ in returned KernelLookup corresponds to
658 25 Sep 06 peter 303        same sample as row \f$ i \f$ in @a this. In other words, this
658 25 Sep 06 peter 304        function returns a KernelLookup containing the kernel elements
658 25 Sep 06 peter 305        between the passed @a data and the internal underlying data @a
658 25 Sep 06 peter 306        this was built from.
658 25 Sep 06 peter 307     */
1206 05 Mar 08 peter 308     KernelLookup test_kernel(const MatrixLookupWeighted& data) const;
658 25 Sep 06 peter 309
720 26 Dec 06 jari 310     /**
720 26 Dec 06 jari 311        \return true if underlying Kernel is weighted
720 26 Dec 06 jari 312     */
720 26 Dec 06 jari 313     bool weighted(void) const;
545 06 Mar 06 peter 314
720 26 Dec 06 jari 315     /**
720 26 Dec 06 jari 316        \return element at position (\a row, \a column) in the Kernel
720 26 Dec 06 jari 317        matrix
720 26 Dec 06 jari 318     */
1549 06 Oct 08 peter 319     const_reference operator()(size_t row, size_t column) const;
545 06 Mar 06 peter 320
446 15 Dec 05 peter 321   private:
555 08 Mar 06 peter 322     const KernelLookup& operator=(const KernelLookup&);
1134 23 Feb 08 peter 323     bool validate(const utility::Index&) const;
446 15 Dec 05 peter 324
1134 23 Feb 08 peter 325     utility::Index column_index_;
4019 06 Nov 20 peter 326     std::shared_ptr<const Kernel> kernel_;
1134 23 Feb 08 peter 327     utility::Index row_index_;
720 26 Dec 06 jari 328   }; // class KernelLookup
330 01 Jun 05 peter 329
680 11 Oct 06 jari 330 }}} // of namespace classifier, yat, and theplu
330 01 Jun 05 peter 331
330 01 Jun 05 peter 332 #endif