Skip to content

Commit

Permalink
splitData helper added
Browse files Browse the repository at this point in the history
  • Loading branch information
gyrdym committed Jun 22, 2020
1 parent a721e19 commit d2226de
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 20 deletions.
@@ -0,0 +1,4 @@
class EmptyRatioCollectionException implements Exception {
@override
String toString() => 'Ratio collection must contain at least one element';
}
@@ -0,0 +1,4 @@
class InvalidRatioSumException implements Exception {
@override
String toString() => 'Ratios sum is equal to or more than 1';
}
10 changes: 10 additions & 0 deletions lib/src/model_selection/exception/outranged_ratio_exception.dart
@@ -0,0 +1,10 @@
class OutRangedRatioException implements Exception {
OutRangedRatioException(double ratio)
: message = 'Ratio value must be within the range 0..1 (both exclusive), '
'$ratio given';

final String message;

@override
String toString() => message;
}
10 changes: 10 additions & 0 deletions lib/src/model_selection/exception/too_small_ratio_exception.dart
@@ -0,0 +1,10 @@
class TooSmallRatioException implements Exception {
TooSmallRatioException(double ratio, int dataSize) :
message = 'Ratio is too small comparing to the input data size: ratio '
'$ratio, min ratio value ${(1 / dataSize).toStringAsFixed(2)}';

final String message;

@override
String toString() => message;
}
17 changes: 9 additions & 8 deletions lib/src/model_selection/split_data.dart
@@ -1,8 +1,12 @@
import 'package:ml_algo/src/model_selection/exception/empty_ratio_collection_exception.dart';
import 'package:ml_algo/src/model_selection/exception/invalid_ratio_sum_exception.dart';
import 'package:ml_algo/src/model_selection/exception/outranged_ratio_exception.dart';
import 'package:ml_algo/src/model_selection/exception/too_small_ratio_exception.dart';
import 'package:ml_dataframe/ml_dataframe.dart';

List<DataFrame> splitData(DataFrame data, Iterable<num> ratios) {
List<DataFrame> splitData(DataFrame data, Iterable<double> ratios) {
if (ratios.isEmpty) {
throw Exception('Ratio collection must contain at least one element');
throw EmptyRatioCollectionException();
}

final inputRows = data
Expand All @@ -14,22 +18,19 @@ List<DataFrame> splitData(DataFrame data, Iterable<num> ratios) {
return ratios
.map((ratio) {
if (ratio <= 0 || ratio >= 1) {
throw Exception('Ratio value must be within the range 0..1 (both '
'exclusive), $ratio given');
throw OutRangedRatioException(ratio);
}

ratioSum += ratio;

if (ratioSum >= 1) {
throw Exception('Ratios sum is more than or equal to 1');
throw InvalidRatioSumException();
}

final rawSplitSize = inputRows.length * ratio;

if (rawSplitSize < 1) {
throw Exception('Ratio is too small comparing to the input data size: '
'ratio $ratio, min ratio value '
'${(1 / inputRows.length).toStringAsFixed(2)}');
throw TooSmallRatioException(ratio, inputRows.length);
}

final end = start + (rawSplitSize.ceil() == inputRows.length
Expand Down
39 changes: 27 additions & 12 deletions test/model_selection/split_data_test.dart
@@ -1,3 +1,7 @@
import 'package:ml_algo/src/model_selection/exception/empty_ratio_collection_exception.dart';
import 'package:ml_algo/src/model_selection/exception/invalid_ratio_sum_exception.dart';
import 'package:ml_algo/src/model_selection/exception/outranged_ratio_exception.dart';
import 'package:ml_algo/src/model_selection/exception/too_small_ratio_exception.dart';
import 'package:ml_algo/src/model_selection/split_data.dart';
import 'package:ml_dataframe/ml_dataframe.dart';
import 'package:test/test.dart';
Expand All @@ -15,26 +19,31 @@ void main() {
];
final data = DataFrame(source);

test('should throw an exception if ratio list is empty', () {
expect(() => splitData(data, []), throwsException);
test('should throw an exception if ratio collection is empty', () {
expect(() => splitData(data, []),
throwsA(isA<EmptyRatioCollectionException>()));
});

test('should throw an exception if at least one ratio value is negative', () {
expect(() => splitData(data, [0.2, -0.3]), throwsException);
expect(() => splitData(data, [0.2, -0.3]),
throwsA(isA<OutRangedRatioException>()));
});

test('should throw an exception if at least one ratio value is zero', () {
expect(() => splitData(data, [0.2, 0]), throwsException);
expect(() => splitData(data, [0.2, 0]),
throwsA(isA<OutRangedRatioException>()));
});

test('should throw an exception if at least one ratio value is equal '
'to 1', () {
expect(() => splitData(data, [1, 0.3]), throwsException);
expect(() => splitData(data, [1, 0.3]),
throwsA(isA<OutRangedRatioException>()));
});

test('should throw an exception if at least one ratio value is greater '
'than 1', () {
expect(() => splitData(data, [100, 0.3]), throwsException);
expect(() => splitData(data, [100, 0.3]),
throwsA(isA<OutRangedRatioException>()));
});

test('should split data', () {
Expand Down Expand Up @@ -86,11 +95,13 @@ void main() {
});

test('should throw exception if there is a too small ratio, case 1', () {
expect(() => splitData(data, [0.2, 0.3, 0.01]), throwsException);
expect(() => splitData(data, [0.2, 0.3, 0.01]),
throwsA(isA<TooSmallRatioException>()));
});

test('should throw exception if there is a too small ratio, case 2', () {
expect(() => splitData(data, [0.2, 0.3, 0.1]), throwsException);
expect(() => splitData(data, [0.2, 0.3, 0.1]),
throwsA(isA<TooSmallRatioException>()));
});

test('should split data into two parts, first part is less than the '
Expand Down Expand Up @@ -171,22 +182,26 @@ void main() {

test('should throw exception if ratios sum is equal to 1, '
'2 elements', () {
expect(() => splitData(data, [0.5, 0.5]), throwsException);
expect(() => splitData(data, [0.5, 0.5]),
throwsA(isA<InvalidRatioSumException>()));
});

test('should throw exception if ratios sum is equal to 1, '
'3 elements', () {
expect(() => splitData(data, [0.3, 0.3, 0.4]), throwsException);
expect(() => splitData(data, [0.3, 0.3, 0.4]),
throwsA(isA<InvalidRatioSumException>()));
});

test('should throw exception if ratios sum is greater than 1, '
'2 elements', () {
expect(() => splitData(data, [0.5, 0.6]), throwsException);
expect(() => splitData(data, [0.5, 0.6]),
throwsA(isA<InvalidRatioSumException>()));
});

test('should throw exception if ratios sum is greater than 1, '
'3 elements', () {
expect(() => splitData(data, [0.3, 0.5, 0.4]), throwsException);
expect(() => splitData(data, [0.3, 0.5, 0.4]),
throwsA(isA<InvalidRatioSumException>()));
});
});
}

0 comments on commit d2226de

Please sign in to comment.