added recent C++ code
This commit is contained in:
@@ -23,6 +23,10 @@ std::string getClass(const std::vector<ClassifiedFeature>& nns) {
|
||||
return "";
|
||||
}
|
||||
|
||||
struct ClassStats {
|
||||
int counts[6] = {};
|
||||
};
|
||||
|
||||
struct Stats{
|
||||
int match;
|
||||
int error;
|
||||
@@ -31,23 +35,178 @@ struct Stats{
|
||||
float getSum() {return match+error+unknown;}
|
||||
};
|
||||
|
||||
|
||||
|
||||
std::vector<ClassifiedPattern> removePatterns(const std::vector<ClassifiedPattern>& patAll, const std::string& fileName) {
|
||||
std::vector<ClassifiedPattern> res;
|
||||
for (const ClassifiedPattern& pat : patAll) {
|
||||
if (pat.belongsToFile(fileName)) {
|
||||
continue;
|
||||
} else {
|
||||
res.push_back(pat);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <int numFeatures> struct PCA {
|
||||
|
||||
aKNN<ClassifiedFeature, numFeatures> knn;
|
||||
TrainPCA::Matrices m;
|
||||
|
||||
};
|
||||
|
||||
class Plot {
|
||||
|
||||
K::Gnuplot gp;
|
||||
K::GnuplotSplot splot;
|
||||
K::GnuplotSplotElementLines lines[5];
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Plot() {
|
||||
for (int i = 0; i < 5; ++i) {lines[i].setColorHex(COLORS[i]);}
|
||||
for (int i = 0; i < 5; ++i) {splot.add(&lines[i]);}
|
||||
}
|
||||
|
||||
void add(int idx, std::vector<float>& vec) {
|
||||
K::GnuplotPoint3 p3(vec[0], vec[1], vec[2]);
|
||||
lines[idx].add(p3);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (int i = 0; i < 5; ++i) {lines[i].clear();}
|
||||
}
|
||||
|
||||
void show() {
|
||||
gp.setDebugOutput(false);
|
||||
gp.draw(splot);
|
||||
gp.flush();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
|
||||
omp_set_dynamic(false);
|
||||
omp_set_num_threads(3);
|
||||
|
||||
const int numFeatures = 3;
|
||||
const int numFeatures = 10;
|
||||
|
||||
TrainPCA::Settings setTrain;
|
||||
TrainPCA::Settings setClass; setClass.regionStart_ms += 25;
|
||||
|
||||
Data::getAllDataFiles();
|
||||
Plot p;
|
||||
|
||||
// convert all provided datasets into patterns
|
||||
std::vector<ClassifiedPattern> srcTrain = TrainPCA::getAllData(setTrain);
|
||||
std::vector<ClassifiedPattern> srcClass = TrainPCA::getAllData(setClass);
|
||||
std::cout << "windows: " << srcTrain.size() << std::endl;
|
||||
|
||||
// error calculation
|
||||
std::unordered_map<std::string, Stats> stats;
|
||||
std::unordered_map<std::string, ClassStats> classStats;
|
||||
//int xx = 0;
|
||||
std::unordered_map<std::string, PCA<numFeatures>*> pcas;
|
||||
|
||||
// try to classify each pattern
|
||||
for (const ClassifiedPattern& patClassify : srcClass) {
|
||||
|
||||
// construct knn search for this leave-one-out ONLY ONCE
|
||||
if (pcas.find(patClassify.fileName) == pcas.end()) {
|
||||
|
||||
std::cout << "constructing PCA for all files but " << patClassify.fileName << std::endl;
|
||||
|
||||
// remove all training patterns belonging to the same source file as the to be classifed pattern
|
||||
std::vector<ClassifiedPattern> srcTrainLOO = removePatterns(srcTrain, patClassify.fileName);
|
||||
|
||||
// sanity check (have we removed all patterns?)
|
||||
int diff = srcTrain.size() - srcTrainLOO.size();
|
||||
if (diff < 200) {throw 1;}
|
||||
|
||||
p.clear();
|
||||
PCA<numFeatures>* pca = new PCA<numFeatures>();
|
||||
pcas[patClassify.fileName] = pca;
|
||||
|
||||
// train PCA using all pattern without those belonging to the same source file as the to-be-classified one
|
||||
pca->m = TrainPCA::getMatrices(srcTrainLOO, numFeatures);
|
||||
|
||||
// calculate features and add them to the KNN
|
||||
for (const ClassifiedPattern& pat : srcTrainLOO) {
|
||||
K::DynColVector<float> vec = pca->m.A1 * K::PCAHelper<float>::toVector(pat.pattern);
|
||||
std::vector<float> arr;
|
||||
for (int i = 0; i < numFeatures; ++i) {arr.push_back(vec(i));}
|
||||
pca->knn.add(ClassifiedFeature(pat.className, arr));
|
||||
|
||||
const int idx = Settings::classToInt(pat.className);
|
||||
p.add(idx, arr);
|
||||
|
||||
}
|
||||
pca->knn.build();
|
||||
//p.show();
|
||||
//sleep(100);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
PCA<numFeatures>* pca = pcas[patClassify.fileName];
|
||||
|
||||
// calculate features for the to-be-classified pattern
|
||||
//const int idx = Settings::classToInt(pat.className);
|
||||
K::DynColVector<float> vec = pca->m.A1 * K::PCAHelper<float>::toVector(patClassify.pattern);
|
||||
|
||||
// get KNN's answer
|
||||
std::vector<float> arr;
|
||||
for (int i = 0; i < numFeatures; ++i) {arr.push_back(vec(i));}
|
||||
std::vector<ClassifiedFeature> neighbors = pca->knn.get(arr.data(), 5);
|
||||
std::string gotClass = getClass(neighbors);
|
||||
|
||||
if (patClassify.className == gotClass) {stats["all"].match++; stats[patClassify.fileName].match++; stats[patClassify.className].match++;}
|
||||
else if (gotClass == "") {stats["all"].unknown++; stats[patClassify.fileName].unknown++; stats[patClassify.className].unknown++;}
|
||||
else {stats["all"].error++; stats[patClassify.fileName].error++; stats[patClassify.className].error++;}
|
||||
|
||||
int gotIdx = (gotClass == "") ? (5) : Settings::classToInt(gotClass);
|
||||
++classStats[patClassify.className].counts[gotIdx];
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (auto& it : stats) {
|
||||
Stats& stats = it.second;
|
||||
std::cout << "'" <<it.first << "',";
|
||||
std::cout << stats.match/stats.getSum() << ",";
|
||||
std::cout << stats.error/stats.getSum() << ",";
|
||||
std::cout << stats.unknown/stats.getSum();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (auto& it : classStats) {
|
||||
ClassStats& stats = it.second;
|
||||
std::cout << "'" << it.first << "',";
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
std::cout << stats.counts[i] << ",";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
std::vector<ClassifiedPattern> patTrain = TrainPCA::getTrainData();
|
||||
TrainPCA::Matrices m = TrainPCA::getMatrices(patTrain, numFeatures);
|
||||
|
||||
std::vector<ClassifiedPattern> patTest = TrainPCA::getTestData();
|
||||
|
||||
// construct knn
|
||||
aKNN<ClassifiedFeature, 3> knn;
|
||||
aKNN<ClassifiedFeature, numFeatures> knn;
|
||||
for (const ClassifiedPattern& pat : patTrain) {
|
||||
K::DynColVector<float> vec = m.A1 * K::PCAHelper<float>::toVector(pat.pattern);
|
||||
const std::vector<float> arr = {vec(0), vec(1), vec(2)};
|
||||
std::vector<float> arr;
|
||||
for (int i = 0; i < numFeatures; ++i) {arr.push_back(vec(i));}
|
||||
knn.add(ClassifiedFeature(pat.className, arr));
|
||||
}
|
||||
knn.build();
|
||||
@@ -65,7 +224,8 @@ int main(void) {
|
||||
K::DynColVector<float> vec = m.A1 * K::PCAHelper<float>::toVector(pat.pattern);
|
||||
|
||||
// get KNN's answer
|
||||
std::vector<float> arr = {vec(0), vec(1), vec(2)};
|
||||
std::vector<float> arr;
|
||||
for (int i = 0; i < numFeatures; ++i) {arr.push_back(vec(i));}
|
||||
std::vector<ClassifiedFeature> neighbors = knn.get(arr.data(), 10);
|
||||
std::string gotClass = getClass(neighbors);
|
||||
|
||||
@@ -93,7 +253,7 @@ int main(void) {
|
||||
|
||||
sleep(10000);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user