All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.expleague.ml.data.tools.FeatureSet Maven / Gradle / Ivy

There is a newer version: 1.4.9
Show newest version
package com.expleague.ml.data.tools;

import com.expleague.commons.math.vectors.Vec;
import com.expleague.commons.math.vectors.VecTools;
import com.expleague.commons.math.vectors.impl.vectors.ArrayVec;
import com.expleague.commons.math.vectors.impl.vectors.VecBuilder;
import com.expleague.ml.data.tools.impl.JoinedFeatureSet;
import com.expleague.ml.meta.DSItem;
import com.expleague.ml.meta.FeatureMeta;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public interface FeatureSet extends Consumer {
  void accept(T item);
  Vec advance();
  Vec advanceTo(Vec v);
  Vec advanceTo(Vec v, FeatureMeta... features);
  int dim();
  FeatureMeta meta(int index);

  @SafeVarargs
  static  FeatureSet join(FeatureSet... fs) {
    return new JoinedFeatureSet<>(fs);
  }

  int index(FeatureMeta meta);

  Stream> components();

  abstract class Stub implements FeatureSet {
    private TObjectIntMap metaIndex;
    private FeatureMeta[] metas;
    private BitSet assigned;

    private Vec current;

    protected Stub() {
      init(Stream.of(getClass().getFields())
          .filter(fld -> (fld.getModifiers() & Modifier.STATIC) != 0)
          .map(fld -> FeatureMeta.class.isAssignableFrom(fld.getType()) ? fld : null)
          .filter(Objects::nonNull)
          .map(fld -> {
            try {
              return fld.get(null);
            }
            catch (IllegalAccessException e) {
              throw new RuntimeException(e);
            }
          })
          .toArray(FeatureMeta[]::new));
    }

    protected Stub(FeatureMeta... metas) {
      init(metas);
    }

    @Override
    public void accept(T item) {
    }

    private void init(FeatureMeta[] metas) {
      this.metas = metas;
      metaIndex = new TObjectIntHashMap<>(metas.length * 2, 0.7f, -1);
      IntStream.range(0, metas.length).forEach(idx -> metaIndex.put(metas[idx], idx));
      current = new ArrayVec(metas.length);
      assigned = new BitSet(metas.length);
    }

    protected void set(FeatureMeta meta, double value) {
      final int idx = metaIndex.get(meta);
      if (idx < 0)
        return;

      assigned.set(idx);
      current.set(idx, value);
    }

    @Override
    public Vec advanceTo(Vec to) {
      if (assigned.cardinality() < metas.length)
        throw new IllegalStateException("Not all features are set " + assigned);
      assigned.clear();
      VecTools.assign(to, current);
      return to;
    }

    @Override
    public Vec advanceTo(Vec to, FeatureMeta... features) {
      advanceTo(current);
      for (int i = 0; i < features.length; i++) {
        to.set(i, current.get(index(features[i])));
      }
      return to;
    }

    @Override
    public Vec advance() {
      return advanceTo(new ArrayVec(dim()));
    }

    @Override
    public int dim() {
      return metas.length;
    }

    @Override
    public FeatureMeta meta(int index) {
      return metas[index];
    }

    @Override
    public int index(FeatureMeta meta) {
      return this.metaIndex.get(meta);
    }

    @Override
    public Stream> components() {
      return Stream.of(this);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy