Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

Commit

Permalink
Merge pull request #31 from spectre-team/develop
Browse files Browse the repository at this point in the history
Master release with wavelet denoising finished
  • Loading branch information
gmrukwa authored Mar 1, 2018
2 parents 272d470 + c2a5ffe commit e5e4a65
Show file tree
Hide file tree
Showing 104 changed files with 4,007 additions and 351 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ environment:
configuration:
- Debug
- Release
version: 3.5.2.{build}
version: 3.14.0.{build}

init:
- cmd: echo Project - %APPVEYOR_PROJECT_NAME%
Expand Down
3 changes: 2 additions & 1 deletion scripts/restore_nugets.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ if errorlevel 1 (
echo Connection to GMrukwaAppVeyorFeed failed.
EXIT /B 1
)
nuget restore >nul 2>&1
nuget restore >nuget.log 2>&1
if errorlevel 1 (
echo NuGet failed to restore packages.
type nuget.log
EXIT /B 1
)
cd ..
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{B6B8D608-32E7-4F09-B91D-EA5832D74C07}</ProjectGuid>
<RootNamespace>SpectrelibClassifierTests</RootNamespace>
<RootNamespace>Spectre::libClassifierTests</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
Expand Down
23 changes: 23 additions & 0 deletions src/Spectre.libClassifier.Tests/SvmTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ limitations under the License.
#include "Spectre.libClassifier/OpenCvDataset.h"
#include "Spectre.libClassifier/Svm.h"
#include "Spectre.libClassifier/UntrainedClassifierException.h"
#include "Spectre.libClassifier/InsufficientDataException.h"

namespace
{
Expand Down Expand Up @@ -71,6 +72,28 @@ TEST_F(SvmTest, predicts_sign)
}
}

TEST_F(SvmTest, predicts_small_data)
{
const std::vector<Label> tempLabels = { 1 };
const std::vector<DataType> tempFeatures = {
1., 1.
};
OpenCvDataset tempData(tempFeatures, tempLabels);
Svm svm;
EXPECT_THROW(svm.Fit(tempData), InsufficientDataException);
}

TEST_F(SvmTest, fit_with_non_binary_labels_throw_not_a_binary_exception)
{
const std::vector<Label> tempLabels = { 2 };
const std::vector<DataType> tempFeatures = {
1., 1.
};
OpenCvDataset tempData(tempFeatures, tempLabels);
Svm svm;
EXPECT_THROW(svm.Fit(tempData), NotABinaryLabelException);
}

TEST_F(SvmTest, get_support_vector_number_test)
{
Svm svm;
Expand Down
1 change: 1 addition & 0 deletions src/Spectre.libClassifier/IClassifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ limitations under the License.
#include <vector>
#include "Spectre.libDataset/IReadOnlyDataset.h"
#include "Spectre.libClassifier/Types.h"
#include "Spectre.libDataset/Empty.h"

namespace spectre::supervised
{
Expand Down
25 changes: 25 additions & 0 deletions src/Spectre.libClassifier/InsufficientDataException.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* InsufficientDataException.cpp
* Throws when data does not cover all classes.
*
Copyright 2018 Spectre Team
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "InsufficientDataException.h"

namespace spectre::supervised::exception
{
InsufficientDataException::InsufficientDataException(Label missingClass): ExceptionBase("Dataset is missing " + std::to_string(missingClass) + " label") {}
}
38 changes: 38 additions & 0 deletions src/Spectre.libClassifier/InsufficientDataException.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* InsufficientDataException.h
* Throws when data does not cover all classes.
*
Copyright 2018 Spectre Team
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once
#include "Spectre.libException/ExceptionBase.h"
#include "NotABinaryLabelException.h"

namespace spectre::supervised::exception
{
/// <summary>
/// Throws when data does not cover all classes.
/// </summary>
class InsufficientDataException final : public core::exception::ExceptionBase
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="InsufficientDataException"/> class.
/// </summary>
/// <param name="actual">The missing class .</param>
explicit InsufficientDataException(Label missingClass);
};
}
10 changes: 2 additions & 8 deletions src/Spectre.libClassifier/RandomSplitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,11 @@ RandomSplitter::RandomSplitter(double trainingRate, Seed rngSeed)
: m_trainingRate(trainingRate),
m_Seed(rngSeed)
{
if (trainingRate >= 0)
{
}
else
if (trainingRate < 0)
{
throw exception::NegativeTrainingRateException(trainingRate);
}
if (trainingRate <= 1)
{
}
else
if (trainingRate > 1)
{
throw exception::ExcessiveTrainingRateException(trainingRate);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Spectre.libClassifier/Spectre.libClassifier.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
<ItemGroup>
<ClCompile Include="EmptyOpenCvDatasetException.cpp" />
<ClCompile Include="ExcessiveTrainingRateException.cpp" />
<ClCompile Include="InsufficientDataException.cpp" />
<ClCompile Include="NegativeTrainingRateException.cpp" />
<ClCompile Include="NotABinaryLabelException.cpp" />
<ClCompile Include="ObservationExtractor.cpp" />
Expand All @@ -157,6 +158,7 @@
<ClInclude Include="EmptyOpenCvDatasetException.h" />
<ClInclude Include="ExcessiveTrainingRateException.h" />
<ClInclude Include="IClassifier.h" />
<ClInclude Include="InsufficientDataException.h" />
<ClInclude Include="NegativeTrainingRateException.h" />
<ClInclude Include="NotABinaryLabelException.h" />
<ClInclude Include="ObservationExtractor.h" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<ClCompile Include="Svm.cpp">
<Filter>Source Files\Classifiers</Filter>
</ClCompile>
<ClCompile Include="InsufficientDataException.cpp">
<Filter>Source Files\Exceptions</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="OpenCvDataset.h">
Expand Down Expand Up @@ -107,6 +110,9 @@
<ClInclude Include="NotABinaryLabelException.h">
<Filter>Header Files\Exceptions</Filter>
</ClInclude>
<ClInclude Include="InsufficientDataException.h">
<Filter>Header Files\Exceptions</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down
17 changes: 17 additions & 0 deletions src/Spectre.libClassifier/Svm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ limitations under the License.
#include "Spectre.libClassifier/OpenCvDataset.h"
#include "Spectre.libClassifier/UnsupportedDatasetTypeException.h"
#include "Spectre.libClassifier/UntrainedClassifierException.h"
#include "InsufficientDataException.h"

namespace spectre::supervised
{
Expand All @@ -35,6 +36,22 @@ Svm::Svm(unsigned int iterationsLimit, double tolerance)

void Svm::Fit(LabeledDataset dataset)
{
auto sum = 0u;
const auto positive = 1u;
const auto negative = 0u;
for (size_t i = 0u; i < dataset.size(); ++i)
{
const auto label = dataset.GetSampleMetadata(i);
if (label != negative && label != positive)
{
throw exception::NotABinaryLabelException(label, i, "dataset");
}
sum += label;
}
if (sum == 0u || sum == dataset.size())
{
throw exception::InsufficientDataException(sum == 0u ? positive : negative);
}
const auto& data = asSupported(dataset);
m_Svm->clear();
m_Svm->train(data.getMatData(), cv::ml::ROW_SAMPLE, data.getMatLabels());
Expand Down
1 change: 0 additions & 1 deletion src/Spectre.libClassifier/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ limitations under the License.
#include <random>
#include <opencv2/core/mat.hpp>
#include <span.h>
#include "Spectre.libDataset/Empty.h"

namespace spectre::supervised
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* AllLabelTypesIncludedConditionTest.cpp
* Tests AllLabelTypesIncludedCondition class.
*
Copyright 2018 Spectre Team
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <gtest/gtest.h>
#include "Spectre.libGaClassifier/AllLabelTypesIncludedCondition.h"

namespace
{
using namespace spectre::supervised;

TEST(AllLabelTypesIncludedConditionInitialization, initializes_with_one_parameter)
{
const std::vector<spectre::supervised::Label> labels{ true, true, true, true, true };
EXPECT_NO_THROW(AllLabelTypesIncludedCondition condition(labels));
}

class AllLabelTypesIncludedConditionTest : public ::testing::Test
{
public:
AllLabelTypesIncludedConditionTest() {}
protected:
const spectre::algorithm::genetic::Individual individual = spectre::algorithm::genetic::Individual({ true, true, true, true, false });
const std::vector<spectre::supervised::Label> allTrueLabels{ true, true, true, true, false };
const std::vector<spectre::supervised::Label> allFalseLabels{ false, false, false, false, true };
const std::vector<spectre::supervised::Label> trueFalseLabels{ true, false, true, true, false };
const std::vector<spectre::supervised::Label> nonBinalyLabels{ 0, 1, 2, 1, 1, 5, 3, 3, 9, 0, 0, 2, 1, 1, 5, 5, 1 };
const spectre::algorithm::genetic::Individual nonBinaryIndividualThree =
spectre::algorithm::genetic::Individual({ true, false, true, false, false, false, true, true, false, false, false, true, false, false, false, false, false});
const spectre::algorithm::genetic::Individual nonBinaryIndividualSix =
spectre::algorithm::genetic::Individual({ true, true, true, false, true, false, true, true, true, false, true, true, true, false, true, false, false });
};

TEST_F(AllLabelTypesIncludedConditionTest, return_true_for_correct_label)
{
AllLabelTypesIncludedCondition condition(trueFalseLabels);
auto result = condition.checkCurrentCondition(individual);
EXPECT_TRUE(result);
}

TEST_F(AllLabelTypesIncludedConditionTest, return_false_for_only_true_label_individual)
{
AllLabelTypesIncludedCondition condition(allTrueLabels);
auto result = condition.checkCurrentCondition(individual);
EXPECT_FALSE(result);
}

TEST_F(AllLabelTypesIncludedConditionTest, return_false_for_only_false_label_individual)
{
AllLabelTypesIncludedCondition condition(allFalseLabels);
auto result = condition.checkCurrentCondition(individual);
EXPECT_FALSE(result);
}

TEST_F(AllLabelTypesIncludedConditionTest, return_true_for_non_binary_label)
{
AllLabelTypesIncludedCondition condition(nonBinalyLabels);
auto result = condition.checkCurrentCondition(nonBinaryIndividualSix);
EXPECT_TRUE(result);
}

TEST_F(AllLabelTypesIncludedConditionTest, return_false_for_non_binary_label)
{
AllLabelTypesIncludedCondition condition(nonBinalyLabels);
auto result = condition.checkCurrentCondition(nonBinaryIndividualThree);
EXPECT_FALSE(result);
}
}
Loading

0 comments on commit e5e4a65

Please sign in to comment.