package org.algorithm.core.neural.dataset;

import java.util.HashMap;
import java.util.Map;

/**
 * 神经网络用数据处理模块
 * @Author: bijl
 * @Date: 2018年7月20日-下午4:01:34
 * @Description:
 */
public abstract class NNDataSet {
    protected final int NUM_FEATURE;
    private final int NUM_LABEL;
    protected final Map<String, Integer> FEATURE_DICT = new HashMap<>();
    
    // 新版本新加的三种关键词
    protected final Map<String, Integer> PARTBODY_DICT = new HashMap<>();
    protected final Map<String, Integer> PROPERTY_DICT = new HashMap<>();
    protected final Map<String, Integer> DURATION_DICT = new HashMap<>();
    
    protected final Map<String, Integer> LABEL_DICT = new HashMap<>();
    protected final Map<String, Integer> NEGATIVE_DICT = new HashMap<>();
    private final String[] FEATURE_DICT_ARRAY;
    private final String[] LABEL_DICT_ARRAY;


    public NNDataSet(String modelAndVersion) {
        this.readDict(modelAndVersion);
        this.NUM_FEATURE = this.FEATURE_DICT.size();
        this.NUM_LABEL = this.LABEL_DICT.size();
        this.FEATURE_DICT_ARRAY = new String[this.NUM_FEATURE];
        this.LABEL_DICT_ARRAY = new String[this.NUM_LABEL];
        this.makeDictArr();
    }
    
    /**
     * 装外部输入转为特征向量
     * @param inputs
     * @return
     */
    public abstract float[] toFeatureVector(Map<String, Map<String, String>> inputs);

    /**
     * 读取特征和类别字典
     */
    public abstract void readDict(String modelAndVersion);
    
    /**
     * 生成字典列表
     */
    private void makeDictArr() {
        for (Map.Entry<String, Integer> entry : this.FEATURE_DICT.entrySet()) 
            this.FEATURE_DICT_ARRAY[entry.getValue()] = entry.getKey();
        
        for (Map.Entry<String, Integer> entry : this.LABEL_DICT.entrySet()) 
            this.LABEL_DICT_ARRAY[entry.getValue()] = entry.getKey();
        
    }

    /**
     * 打包模型输出结果给调用者
     * 
     * @param predict 模型输出
     * @return
     */
    public Map<String, Float> wrap(float[][] predict) {
        Map<String, Float> result = new HashMap<>();
        for (int i=0; i<predict[0].length; i++) {  // 只返回一维向量
            result.put(this.LABEL_DICT_ARRAY[i], predict[0][i]);
        }
        return result;
    }

    /**
     * @return
     */
    public int getNumFeature() {
        return this.NUM_FEATURE;
    }

    /**
     * @return
     */
    public int getNumLabel() {
        return this.NUM_LABEL;
    }

}
