Skip to content

Commit

Permalink
Knn (#85)
Browse files Browse the repository at this point in the history
* knn

Signed-off-by: Andrey Parfenov <[email protected]>
  • Loading branch information
Andrey1994 committed Sep 5, 2020
1 parent 1fb2096 commit e51ee22
Show file tree
Hide file tree
Showing 21 changed files with 35,539 additions and 28 deletions.
9 changes: 2 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ set (ML_MODULE_SRC
${CMAKE_HOME_DIRECTORY}/src/ml/ml_module.cpp
${CMAKE_HOME_DIRECTORY}/src/ml/concentration_regression_classifier.cpp
${CMAKE_HOME_DIRECTORY}/third_party/libsvm/svm.cpp
${CMAKE_HOME_DIRECTORY}/src/ml/concentration_knn_classifier.cpp
)

add_library (
Expand Down Expand Up @@ -252,6 +253,7 @@ target_include_directories (
${CMAKE_HOME_DIRECTORY}/src/ml/inc
${CMAKE_HOME_DIRECTORY}/third_party/libsvm
${CMAKE_HOME_DIRECTORY}/third_party/json
${CMAKE_HOME_DIRECTORY}/third_party/kdtree
)

set_target_properties (${BOARD_CONTROLLER_NAME}
Expand Down Expand Up @@ -282,13 +284,6 @@ set_target_properties (${ML_MODULE_NAME}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/compiled
)

# link openmp if found
find_package (OpenMP)
if (OpenMP_CXX_FOUND)
target_link_libraries (${DATA_HANDLER_NAME} PRIVATE OpenMP::OpenMP_CXX)
target_link_libraries (${ML_MODULE_NAME} PRIVATE OpenMP::OpenMP_CXX)
endif()

# dont link pthread for Android
if (UNIX AND NOT ANDROID)
target_link_libraries (${BOARD_CONTROLLER_NAME} PRIVATE pthread dl)
Expand Down
1 change: 1 addition & 0 deletions csharp-package/brainflow/brainflow/ml_module_library.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum BrainFlowMetrics
public enum BrainFlowClassifiers
{
REGRESSION = 0,
KNN = 1
};

public static class MLModuleLibrary64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
public enum BrainFlowClassifiers
{

REGRESSION (0);
REGRESSION (0),
KNN (1);

private final int protocol;
private static final Map<Integer, BrainFlowClassifiers> cl_map = new HashMap<Integer, BrainFlowClassifiers> ();
Expand Down
1 change: 1 addition & 0 deletions julia-package/brainflow/src/ml_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ end
@enum BrainFlowClassifiers begin

REGRESSION = 0
KNN = 1

end

Expand Down
1 change: 1 addition & 0 deletions matlab-package/brainflow/BrainFlowClassifiers.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
classdef BrainFlowClassifiers < int32
enumeration
REGRESSION (0)
KNN (1)
end
end
1 change: 1 addition & 0 deletions python-package/brainflow/ml_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class BrainFlowClassifiers (enum.Enum):
"""Enum to store all supported classifiers"""

REGRESSION = 0 #:
KNN = 1 #:


class BrainFlowModelParams (object):
Expand Down
7 changes: 1 addition & 6 deletions src/data_handler/data_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
#include <string>
#include <vector>

#ifdef _OPENMP
#include <omp.h>
#endif

#include "brainflow_constants.h"
#include "data_handler.h"
#include "downsample_operators.h"
Expand Down Expand Up @@ -920,8 +916,7 @@ int get_avg_band_powers (double *raw_data, int rows, int cols, int sampling_rate
bands[i][j] = 0.0;
}
}

#pragma omp parallel for
// todo parallel using c++ threads
for (int i = 0; i < rows; i++)
{
double *ampls = new double[nfft / 2 + 1];
Expand Down
94 changes: 94 additions & 0 deletions src/ml/concentration_knn_classifier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <algorithm>
#include <cmath>
#include <stdlib.h>

#include "brainflow_constants.h"
#include "concentration_knn_classifier.h"
#include "focus_dataset.h"


int ConcentrationKNNClassifier::prepare ()
{
if (kdtree != NULL)
{
return (int)BrainFlowExitCodes::ANOTHER_CLASSIFIER_IS_PREPARED_ERROR;
}
if (!params.other_info.empty ())
{
try
{
num_neighbors = std::stoi (params.other_info);
}
catch (const std::exception &e)
{
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}
}
if ((num_neighbors < 1) || (num_neighbors > 100))
{
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}

int dataset_len = sizeof (brainflow_focus_y) / sizeof (brainflow_focus_y[0]);
for (int i = 0; i < dataset_len; i++)
{
FocusPoint point (brainflow_focus_x[i], 10, brainflow_focus_y[i]);
// decrease weight for stddev, 0.2 - experimental vlaue
for (int j = 5; j < 10; j++)
{
point[j] *= 0.2;
}
dataset.push_back (point);
}
kdtree = new kdt::KDTree<FocusPoint> (dataset);
return (int)BrainFlowExitCodes::STATUS_OK;
}

int ConcentrationKNNClassifier::predict (double *data, int data_len, double *output)
{
if ((data_len < 5) || (data == NULL) || (output == NULL))
{
return (int)BrainFlowExitCodes::INVALID_BUFFER_SIZE_ERROR;
}
if (kdtree == NULL)
{
return (int)BrainFlowExitCodes::CLASSIFIER_IS_NOT_PREPARED_ERROR;
}

double feature_vector[10] = {0.0};
for (int i = 0; i < data_len; i++)
{
if (i >= 5)
{
feature_vector[i] = data[i] * 0.2;
}
else
{
feature_vector[i] = data[i];
}
}

FocusPoint sample_to_predict (feature_vector, 10, 0.0);
const std::vector<int> knn_ids = kdtree->knnSearch (sample_to_predict, num_neighbors);
int num_ones = 0;
for (int i = 0; i < knn_ids.size (); i++)
{
if (dataset[knn_ids[i]].value == 1)
{
num_ones++;
}
}

double score = ((double)num_ones) / num_neighbors;
*output = score;

return (int)BrainFlowExitCodes::STATUS_OK;
}

int ConcentrationKNNClassifier::release ()
{
delete kdtree;
kdtree = NULL;
dataset.clear ();
return (int)BrainFlowExitCodes::STATUS_OK;
}
33 changes: 33 additions & 0 deletions src/ml/inc/concentration_knn_classifier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <vector>

#include "base_classifier.h"
#include "focus_point.h"

#include "kdtree.h"


class ConcentrationKNNClassifier : public BaseClassifier
{
public:
ConcentrationKNNClassifier (struct BrainFlowModelParams params) : BaseClassifier (params)
{
num_neighbors = 5;
kdtree = NULL;
}

virtual ~ConcentrationKNNClassifier ()
{
release ();
}

virtual int prepare ();
virtual int predict (double *data, int data_len, double *output);
virtual int release ();

private:
std::vector<FocusPoint> dataset;
kdt::KDTree<FocusPoint> *kdtree;
int num_neighbors;
};
Loading

0 comments on commit e51ee22

Please sign in to comment.