1 /**
2  * @file tests/main_tests/preprocess_scale_test.cpp
3  * @author Jeffin Sam
4  *
5  * Test mlpackMain() of preprocess_scale_main.cpp.
6  *
7  * mlpack is free software; you may redistribute it and/or modify it under the
8  * terms of the 3-clause BSD license.  You should have received a copy of the
9  * 3-clause BSD license along with mlpack.  If not, see
10  * http://www.opensource.org/licenses/BSD-3-Clause for more information.
11  */
12 #define BINDING_TYPE BINDING_TYPE_TEST
13 
14 #include <mlpack/core.hpp>
15 static const std::string testName = "PreprocessScale";
16 
17 #include <mlpack/core/util/mlpack_main.hpp>
18 #include <mlpack/methods/preprocess/preprocess_scale_main.cpp>
19 
20 #include "test_helper.hpp"
21 #include "../test_catch_tools.hpp"
22 #include "../catch.hpp"
23 
24 using namespace mlpack;
25 
26 struct PreprocessScaleTestFixture
27 {
28  public:
29   static arma::mat dataset;
PreprocessScaleTestFixturePreprocessScaleTestFixture30   PreprocessScaleTestFixture()
31   {
32     // Cache in the options for this program.
33     IO::RestoreSettings(testName);
34   }
35 
~PreprocessScaleTestFixturePreprocessScaleTestFixture36   ~PreprocessScaleTestFixture()
37   {
38     // Clear the settings.
39     bindings::tests::CleanMemory();
40     IO::ClearSettings();
41   }
42 };
43 
44 arma::mat PreprocessScaleTestFixture::dataset = "-1 -0.5 0 1;"
45                                                 "2 6 10 18;";
46 
47 /**
48  * Check that two different scalers give two different output.
49  */
50 TEST_CASE_METHOD(PreprocessScaleTestFixture, "TwoScalerTest",
51                  "[PreprocessScaleMainTest][BindingTests]")
52 {
53   // Input custom data points.
54   std::string method = "max_abs_scaler";
55   SetInputParam("input", dataset);
56   SetInputParam("scaler_method", method);
57 
58   mlpackMain();
59   arma::mat maxAbsScalerOutput = IO::GetParam<arma::mat>("output");
60 
61   bindings::tests::CleanMemory();
62 
63   method = "standard_scaler";
64   SetInputParam("input", dataset);
65   SetInputParam("scaler_method", std::move(method));
66 
67   mlpackMain();
68   arma::mat standardScalerOutput = IO::GetParam<arma::mat>("output");
69 
70   CheckMatricesNotEqual(standardScalerOutput, maxAbsScalerOutput);
71 }
72 
73 /**
74  * Check that two different option for a particular scaler give two
75  * different output.
76  */
77 TEST_CASE_METHOD(PreprocessScaleTestFixture, "TwoOptionTest",
78                  "[PreprocessScaleMainTest][BindingTests]")
79 {
80   std::string method = "min_max_scaler";
81   // Input custom data points.
82   SetInputParam("input", dataset);
83   SetInputParam("scaler_method", method);
84 
85   mlpackMain();
86   arma::mat output = IO::GetParam<arma::mat>("output");
87 
88   bindings::tests::CleanMemory();
89 
90   SetInputParam("input", dataset);
91   SetInputParam("scaler_method", std::move(method));
92   SetInputParam("min_value", 2);
93   SetInputParam("max_value", 4);
94 
95   mlpackMain();
96   arma::mat output_with_param = IO::GetParam<arma::mat>("output");
97 
98   CheckMatricesNotEqual(output, output_with_param);
99 }
100 
101 /**
102  * Check that passing unrelated option don't change anything.
103  */
104 TEST_CASE_METHOD(PreprocessScaleTestFixture, "UnrelatedOptionTest",
105                  "[PreprocessScaleMainTest][BindingTests]")
106 {
107   std::string method = "standard_scaler";
108   // Input custom data points.
109   SetInputParam("input", dataset);
110   SetInputParam("scaler_method", method);
111 
112   mlpackMain();
113   arma::mat scaled = IO::GetParam<arma::mat>("output");
114 
115   bindings::tests::CleanMemory();
116 
117   SetInputParam("input", dataset);
118   SetInputParam("scaler_method", std::move(method));
119   SetInputParam("min_value", 2);
120   SetInputParam("max_value", 4);
121   SetInputParam("epsilon", 0.005);
122 
123   mlpackMain();
124   arma::mat output = IO::GetParam<arma::mat>("output");
125 
126   CheckMatrices(scaled, output);
127 }
128 
129 /**
130  * Check Inverse Scaling is working.
131  */
132 TEST_CASE_METHOD(PreprocessScaleTestFixture, "InverseScalingTest",
133                  "[PreprocessScaleMainTest][BindingTests]")
134 {
135   std::string method = "zca_whitening";
136   // Input custom data points.
137   SetInputParam("input", dataset);
138   SetInputParam("scaler_method", std::move(method));
139 
140   mlpackMain();
141   arma::mat scaled = IO::GetParam<arma::mat>("output");
142 
143   SetInputParam("input", scaled);
144   SetInputParam("input_model",
145                 IO::GetParam<ScalingModel*>("output_model"));
146   SetInputParam("inverse_scaling", true);
147 
148   mlpackMain();
149   arma::mat output = IO::GetParam<arma::mat>("output");
150   CheckMatrices(dataset, output);
151 }
152 
153 /**
154  * Check Saved model is working.
155  */
156 TEST_CASE_METHOD(PreprocessScaleTestFixture, "SavedModelTest",
157                  "[PreprocessScaleMainTest][BindingTests]")
158 {
159   std::string method = "pca_whitening";
160   // Input custom data points.
161   SetInputParam("input", dataset);
162   SetInputParam("scaler_method", std::move(method));
163 
164   mlpackMain();
165   arma::mat scaled = IO::GetParam<arma::mat>("output");
166 
167   SetInputParam("input", dataset);
168   SetInputParam("input_model",
169                 IO::GetParam<ScalingModel*>("output_model"));
170 
171   mlpackMain();
172   arma::mat output = IO::GetParam<arma::mat>("output");
173   CheckMatrices(scaled, output);
174 }
175 
176 /**
177  * Check different epsilon for PCA give two different output.
178  */
179 TEST_CASE_METHOD(PreprocessScaleTestFixture, "EpsilonTest",
180                  "[PreprocessScaleMainTest][BindingTests]")
181 {
182   std::string method = "pca_whitening";
183   // Input custom data points.
184   SetInputParam("input", dataset);
185   SetInputParam("scaler_method", method);
186 
187   mlpackMain();
188   arma::mat scaled = IO::GetParam<arma::mat>("output");
189 
190   bindings::tests::CleanMemory();
191 
192   SetInputParam("scaler_method", std::move(method));
193   SetInputParam("input", dataset);
194   SetInputParam("epsilon", 1.0);
195 
196   mlpackMain();
197   arma::mat output = IO::GetParam<arma::mat>("output");
198 
199   CheckMatricesNotEqual(scaled, output);
200 }
201 
202 /**
203  * Check for invalid epsilon.
204  */
205 TEST_CASE_METHOD(PreprocessScaleTestFixture, "InvalidEpsilonTest",
206                  "[PreprocessScaleMainTest][BindingTests]")
207 {
208   std::string method = "pca_whitening";
209   // Input custom data points.
210   SetInputParam("input", dataset);
211   SetInputParam("scaler_method", std::move(method));
212   SetInputParam("epsilon", -1.0);
213 
214   REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
215 }
216 
217 /**
218  * Check for invalid range in min_max_scaler.
219  */
220 TEST_CASE_METHOD(PreprocessScaleTestFixture, "InvalidRangeTest",
221                  "[PreprocessScaleMainTest][BindingTests]")
222 {
223   std::string method = "min_max_scaler";
224   // Input custom data points.
225   SetInputParam("input", dataset);
226   SetInputParam("scaler_method", std::move(method));
227   SetInputParam("min_value", 4);
228   SetInputParam("max_value", 2);
229 
230   REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
231 }
232 
233 /**
234  * Check for invalid scaler type.
235  */
236 TEST_CASE_METHOD(PreprocessScaleTestFixture, "InvalidScalerTest",
237                  "[PreprocessScaleMainTest][BindingTests]")
238 {
239   std::string method = "invalid_scaler";
240   // Input custom data points.
241   SetInputParam("input", dataset);
242   SetInputParam("scaler_method", std::move(method));
243   SetInputParam("min_value", 4);
244   SetInputParam("max_value", 2);
245 
246   Log::Fatal.ignoreInput = true;
247   REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
248   Log::Fatal.ignoreInput = false;
249 }
250 
251 /**
252  * Check for Standard scaler type.
253  */
254 TEST_CASE_METHOD(PreprocessScaleTestFixture, "StandardScalerBindingTest",
255                  "[PreprocessScaleMainTest][BindingTests]")
256 {
257   std::string method = "standard_scaler";
258   // Input custom data points.
259   SetInputParam("input", dataset);
260   SetInputParam("scaler_method", method);
261   REQUIRE_NOTHROW(mlpackMain());
262   SetInputParam("scaler_method", std::move(method));
263   SetInputParam("input", dataset);
264   SetInputParam("input_model",
265                 IO::GetParam<ScalingModel*>("output_model"));
266   SetInputParam("inverse_scaling", true);
267   REQUIRE_NOTHROW(mlpackMain());
268 }
269 
270 /**
271  * Check for MaxAbs scaler type.
272  */
273 TEST_CASE_METHOD(PreprocessScaleTestFixture, "MaxAbsScalerBindingTest",
274                  "[PreprocessScaleMainTest][BindingTests]")
275 {
276   std::string method = "max_abs_scaler";
277   // Input custom data points.
278   SetInputParam("input", dataset);
279   SetInputParam("scaler_method", method);
280   REQUIRE_NOTHROW(mlpackMain());
281   SetInputParam("scaler_method", std::move(method));
282   SetInputParam("input", dataset);
283   SetInputParam("input_model",
284                 IO::GetParam<ScalingModel*>("output_model"));
285   SetInputParam("inverse_scaling", true);
286   REQUIRE_NOTHROW(mlpackMain());
287 }
288 
289 /**
290  * Check for MinMax scaler type.
291  */
292 TEST_CASE_METHOD(PreprocessScaleTestFixture, "MinMaxScalerBindingTest",
293                  "[PreprocessScaleMainTest][BindingTests]")
294 {
295   std::string method = "min_max_scaler";
296   // Input custom data points.
297   SetInputParam("input", dataset);
298   SetInputParam("scaler_method", method);
299   SetInputParam("min_value", 2);
300   SetInputParam("max_value", 4);
301   REQUIRE_NOTHROW(mlpackMain());
302   SetInputParam("scaler_method", std::move(method));
303   SetInputParam("input", dataset);
304   SetInputParam("input_model",
305                 IO::GetParam<ScalingModel*>("output_model"));
306   SetInputParam("inverse_scaling", true);
307   REQUIRE_NOTHROW(mlpackMain());
308 }
309 
310 /**
311  * Check for PCA scaler type.
312  */
313 TEST_CASE_METHOD(PreprocessScaleTestFixture, "PCAScalerBindingTest",
314                  "[PreprocessScaleMainTest][BindingTests]")
315 {
316   std::string method = "pca_whitening";
317   // Input custom data points.
318   SetInputParam("input", dataset);
319   SetInputParam("scaler_method", method);
320   SetInputParam("epsilon", 1.0);
321   REQUIRE_NOTHROW(mlpackMain());
322   SetInputParam("scaler_method", std::move(method));
323   SetInputParam("input", dataset);
324   SetInputParam("input_model",
325                 IO::GetParam<ScalingModel*>("output_model"));
326   SetInputParam("inverse_scaling", true);
327   REQUIRE_NOTHROW(mlpackMain());
328 }
329 
330 /**
331  * Check for ZCA scaler type.
332  */
333 TEST_CASE_METHOD(PreprocessScaleTestFixture, "ZCAScalerBindingTest",
334                  "[PreprocessScaleMainTest][BindingTests]")
335 {
336   std::string method = "zca_whitening";
337   // Input custom data points.
338   SetInputParam("input", dataset);
339   SetInputParam("scaler_method", method);
340   SetInputParam("epsilon", 1.0);
341   REQUIRE_NOTHROW(mlpackMain());
342   SetInputParam("scaler_method", std::move(method));
343   SetInputParam("input", dataset);
344   SetInputParam("input_model",
345                 IO::GetParam<ScalingModel*>("output_model"));
346   SetInputParam("inverse_scaling", true);
347   REQUIRE_NOTHROW(mlpackMain());
348 }
349 
350 /**
351  * Check for Mean Normalization scaler type.
352  */
353 TEST_CASE_METHOD(PreprocessScaleTestFixture, "MeanNormalizationBindingTest",
354                  "[PreprocessScaleMainTest][BindingTests]")
355 {
356   std::string method = "mean_normalization";
357   // Input custom data points.
358   SetInputParam("input", dataset);
359   SetInputParam("scaler_method", method);
360   REQUIRE_NOTHROW(mlpackMain());
361   SetInputParam("scaler_method", std::move(method));
362   SetInputParam("input", dataset);
363   SetInputParam("input_model",
364                 IO::GetParam<ScalingModel*>("output_model"));
365   SetInputParam("inverse_scaling", true);
366   REQUIRE_NOTHROW(mlpackMain());
367 }
368