Main Page · Modules · All Classes · Class Hierarchy
MAClassifierSamples.cpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #include <ml/MAClassifierSamples.hpp>
23 
24 #include <MCBinaryData.hpp>
25 #include <MCDataContainer.hpp>
26 #include <MCDataStorage.hpp>
27 #include <MCLog.hpp>
28 
30 {
31 }
32 
33 
34 const MC::FloatTable& MAClassifierSamples::GetFeatureVectors() const
35 {
36  return FeatureVectors;
37 }
38 
39 
40 const MC::FloatList& MAClassifierSamples::GetLabels() const
41 {
42  return Labels;
43 }
44 
45 
46 void MAClassifierSamples::AddSample(const MC::FloatList& feature_vector, const float label)
47 {
48  if (feature_vector.empty())
49  {
50  MC_WARNING("Empty feature vector.");
51  return;
52  }
53  if (FeatureVectors.size() > 0 && feature_vector.size() != FeatureVectors[0].size())
54  {
55  MC_WARNING("Feature count does not match with the stored vectors (%d != %d).",
56  feature_vector.size(), FeatureVectors[0].size());
57  return;
58  }
59  FeatureVectors.push_back(feature_vector);
60  Labels.push_back(label);
61 }
62 
63 
64 void MAClassifierSamples::AddSamples(const MC::FloatTable& feature_vectors, const MC::FloatList& labels)
65 {
66  if (feature_vectors.empty())
67  {
68  MC_WARNING("No feature vectors.");
69  return;
70  }
71  if (!MCIsConsistentTable(feature_vectors))
72  {
73  MC_WARNING("Feature vectors are not consistent.");
74  return;
75  }
76  if (feature_vectors.size() != labels.size())
77  {
78  MC_WARNING("Feature vector count does not match with the label count (%d != %d).",
79  feature_vectors.size(), labels.size());
80  return;
81  }
82  for (unsigned int i = 0; i < feature_vectors.size(); ++i)
83  AddSample(feature_vectors[i], labels[i]);
84 }
85 
86 
88 {
89  if (index >= FeatureVectors.size())
90  {
91  MC_WARNING("Invalid index to remove a sample (%d >= %d)", index, FeatureVectors.size());
92  return;
93  }
94  FeatureVectors.erase(FeatureVectors.begin()+index);
95  Labels.erase(Labels.begin()+index);
96 }
97 
98 
100 {
101  MC::DataStorageSPtr DataStorage(new MCDataStorage("FeatureVectors", true));
102  MC::DataContainerSPtr DataContainer(DataStorage->CreateContainer("FeatureVectors"));
103 
104  // Add the feature vectors to the storage
105  for (unsigned int i = 0; i < FeatureVectors.size(); ++i)
106  {
107  MCDataItemBase* FeatureVectorsItem = DataContainer->GetData(MCToStr((int)Labels[i]));
108 
109  if (!FeatureVectorsItem)
110  {
111  FeatureVectorsItem = new MCDataItem<MC::FloatTable>(MC::FloatTable(), MCToStr((int)Labels[i]));
112  DataContainer->AddData(*FeatureVectorsItem);
113  }
114  reinterpret_cast<MC::FloatTable*>(FeatureVectorsItem->DataPtr)->push_back(FeatureVectors[i]);
115  }
116  return DataStorage->Encode();
117 }
118 
119 
121 {
122  MC::DataStorageSPtr DataStorage(MCDataStorage::Decode(data, true));
123  MC::DataContainerSPtr DataContainer;
124 
125  if (!DataStorage.get())
126  return nullptr;
127 
128  DataContainer = DataStorage->GetContainer("FeatureVectors");
129  if (!DataContainer.get())
130  return nullptr;
131 
132  const MC::DataItemBasePtrList& Items = DataContainer->GetAllData();
133  MAClassifierSamples* ClassifierSamples = new MAClassifierSamples;
134 
135  for (auto& item : Items)
136  {
137  MC::FloatTable* FeatureVectors = reinterpret_cast<MC::FloatTable*>(item->DataPtr);
138 
139  MCMergeContainers(ClassifierSamples->FeatureVectors, *FeatureVectors);
140  for (unsigned int i = 0; i < FeatureVectors->size(); ++i)
141  ClassifierSamples->Labels.push_back(MCStrConvert<float>(item->DataName));
142  }
143  return ClassifierSamples;
144 }
145 
146 
148 {
149  MC::BinaryDataSPtr BinaryData(new MCBinaryData);
150 
151  if (BinaryData->LoadFromFile(file_name))
152  {
153  return Decode(*BinaryData);
154  }
155  return nullptr;
156 }
157 
158 
159 bool MAClassifierSamples::SaveToFile(const std::string& file_name) const
160 {
161  MC::BinaryDataSPtr BinaryData(Encode());
162 
163  if (BinaryData->SaveToFile(file_name))
164  {
165  return true;
166  }
167  return false;
168 }
bool SaveToFile(const std::string &file_name) const
Save data to a file.
A helper class to fill the type info to the base structure.
void RemoveSample(unsigned int index)
Remove a sample.
MAClassifierSamples()
Class constructor.
Binary data class.
static MAClassifierSamples * Decode(const MCBinaryData &data)
Decode from binary data.
const MC::FloatTable & GetFeatureVectors() const
Get all feature vectors.
#define MC_WARNING(...)
Warning macro.
Definition: MCLog.hpp:43
Data container item base structure to store basic type info.
std::string MCToStr(const T value, bool hex_manipulator=false)
Convert an other type to string with std::stringstream.
Definition: MCDefs.hpp:360
Indexer< T > index(T &t)
Iterator magic for for loops to get the index while iterating through.
Definition: MCDefs.hpp:146
static MCDataStorage * Decode(const MCBinaryData &data, bool portable=false)
Load the data storage from binary form.
static MAClassifierSamples * LoadFromFile(const std::string &file_name)
Load data from a file.
Collected data with portable storage functions.
Data storage with file support.
bool MCIsConsistentTable(V &table)
Check the consistency of a table.
void AddSample(const MC::FloatList &feature_vector, float label)
Add a sample.
void AddSamples(const MC::FloatTable &feature_vectors, const MC::FloatList &labels)
Add more samples.
void MCMergeContainers(U &target, const U &other)
Merge two containers.
MC::FloatList Labels
Labels.
MC::FloatTable FeatureVectors
Feature vectors.
const MC::FloatList & GetLabels() const
Get all labels.
MCBinaryData * Encode() const
Encode into binary data.