public static List<Tuple> createBalancedTrainingData(final List<Tuple> trainingData) {
        Map<String, Long> tagCount = trainingData.parallelStream()
                .map(x -> new AbstractMap.SimpleImmutableEntry<>(x.label, 1))
                .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.counting()));

        Map.Entry<String, Long> minCountEntry = tagCount.entrySet().stream()
                .min(Comparator.comparing(Map.Entry::getValue))
                .orElse(null);

        tagCount.clear();

        List<Tuple> newData = new ArrayList<>();
        for (Tuple t : trainingData) {
            String label = t.label;
            if (!tagCount.containsKey(label)) {
                tagCount.put(t.label, 0L);
            }

            if (tagCount.get(label) < minCountEntry.getValue()) {
                tagCount.put(label, tagCount.get(label) + 1);
                newData.add(t);
            }
        }

        return newData;
    }
public static List < Tuple > createBalancedTrainingData ( final List < Tuple > trainingData ) { Map < String , Long > tagCount = trainingData . parallelStream ( ) . map ( x -> new AbstractMap . SimpleImmutableEntry < > ( x . label , 1 ) ) . collect ( Collectors . groupingBy ( Map . Entry :: getKey , Collectors . counting ( ) ) ) ; Map . Entry < String , Long > minCountEntry = tagCount . entrySet ( ) . stream ( ) . min ( Comparator . comparing ( Map . Entry :: getValue ) ) . orElse ( null ) ; tagCount . clear ( ) ; List < Tuple > newData = new ArrayList < > ( ) ; for ( Tuple t : trainingData ) { String label = t . label ; if ( ! tagCount . containsKey ( label ) ) { tagCount . put ( t . label , 0L ) ; } if ( tagCount . get ( label ) < minCountEntry . getValue ( ) ) { tagCount . put ( label , tagCount . get ( label ) + 1 ) ; newData . add ( t ) ; } } return newData ; }
Regardless of the label, just consider isPosExample and !isPosExample

@param trainingData input training data.
@return List of balanced tuples.