    001package javax.visrec.ml.data;
    002
    003import java.util.Collection;
    004import java.util.Collections;
    005import java.util.List;
    006import java.util.Objects;
    007import java.util.Random;
    008
    009/**
    010 * Generic interface for all data sets for machine learning, independent of type of elements.
    011 *
    012 * @author Zoran Sevarac
    013 * @param <E> type of data set elements
    014 * @since 1.0
    015 */
    016public interface DataSet<E> extends Iterable<E> {
    017
    018    // TODO: add stream for filtering elements in data set
    019
    020    /**
    021     * Get a collection of the items in the {@link DataSet}
    022     * @return {@link Collection}
    023     */
    024    List<E> getItems();
    025
    026    /**
    027     * Adds an element to this data set.
    028     *
    029     * @param item data set item to add to the data set
    030     * @return current instance of {@link DataSet}
    031     */
    032    default DataSet<E> add(E item) {
    033        Objects.requireNonNull(item, "Null items are not allowed in dataset");
    034        getItems().add(item);
    035        return this;
    036    }
    037
    038    /**
    039     * Add an existing {@link DataSet} to the current {@link DataSet}
    040     * @param dataSet existing {@link DataSet}
    041     * @return current instance of {@link DataSet}
    042     */
    043    default DataSet<E> addAll(DataSet<E> dataSet) {
    044        Objects.requireNonNull(dataSet, "Dataset is null. Cannot add items from null dataset");
    045        getItems().addAll(dataSet.getItems());
    046        return this;
    047    }
    048
    049    /**
    050     * Get an item from the {@link DataSet}
    051     * @param index index as {@code int} which corresponds with
    052     *              the index of the {@link DataSet}
    053     * @return item from the {@link DataSet}
    054     */
    055    default E get(int index) {
    056        return getItems().get(index);
    057    }
    058
    059    /**
    060     * Clear items of the {@link DataSet}
    061     */
    062    default  void clear() {
    063        getItems().clear();
    064    }
    065
    066    /**
    067     * Determines whether the {@link DataSet} is empty or not.
    068     * @return {@code true} if the {@link DataSet} is empty, otherwise {@code false}
    069     */
    070    default boolean isEmpty() {
    071        return getItems().isEmpty();
    072    }
    073
    074    /**
    075     * Get the number of elements in {@link DataSet}
    076     * @return size in {@code int}
    077     */
    078    default int size() {
    079        return getItems().size();
    080    }
    081
    082    /**
    083     * Split dataset into specified number of equally sized parts.
    084     *
    085     * @param numParts number of parts to be returned
    086     * @return multiple {@link DataSet} in an array.
    087     */
    088    DataSet<E>[] split(int numParts);
    089
    090    /**
    091     * Split dataset into specified number of equally sized parts, using specified random generator.
    092     * @param numParts number of parts/subsets to return
    093     * @param rnd random number generator
    094     * @return multiple {@link DataSet} in an array.
    095     */
    096    DataSet<E>[] split(int numParts, Random rnd);
    097
    098    /**
    099     * Split data set in two parts, one with size of specified percentage, and other with rest of the data set
    100     *
    101     * @param part specified percentage of the first {@link DataSet}
    102     * @return multiple {@link DataSet} in an array.
    103     */
    104    default DataSet<E>[] split(double part) {
    105        return split(part, 1-part);
    106    }
    107
    108    /**
    109     * Split data set into parts of specified sizes
    110     * @param parts specific sizes of {@link DataSet}
    111     * @return array of {@link DataSet}
    112     */
    113    DataSet<E>[] split(double... parts);
    114
    115    /**
    116     * Split data set into parts of specified sizes using specified random generator
    117     * @param rnd random generator
    118     * @param parts specific sizes of {@link DataSet}
    119     * @return array of {@link DataSet}
    120     */
    121    DataSet<E>[] split(Random rnd, double... parts);
    122
    123
    124    /**
    125     * Shuffles the data set.
    126     */
    127    default void shuffle() {
    128        Collections.shuffle(getItems());
    129    }
    130
    131    /**
    132     * Shuffles the data set using the specified random number generator.
    133     * @param rnd random generator
    134     */
    135    default void shuffle(Random rnd) {
    136        Collections.shuffle(getItems(), rnd);
    137    }
    138
    139//    TODO String[] getOutputLabels();
    140//    TODO void setColumnNames(String[] labels);
    141
    142    class Column {
    143        private final String name;
    144        private final ColumnType type;
    145        private final boolean isTarget;
    146
    147        public Column(String name, ColumnType type, boolean isTarget) {
    148            this.name = name;
    149            this.type = type;
    150            this.isTarget = isTarget;
    151        }
    152
    153        public String getName() {
    154            return name;
    155        }
    156
    157        public ColumnType getType() {
    158            return type;
    159        }
    160
    161        public boolean isTarget() {
    162            return isTarget;
    163        }
    164    }
    165
    166    enum ColumnType {
    167        DECIMAL, INTEGER, BINARY, STRING;
    168    }
    169
    170}