Skip to content
Snippets Groups Projects
dtree_learner.py 4.75 KiB
Newer Older
from typing import List, Tuple
import numpy as np
from learner_base import LearnerBase
import grammar_generation_utils
class DTreeLearner(LearnerBase):
    def __init__(self, state_dim: int, perc_dim: int,
                 timeout: int = 10000) -> None:
        super().__init__()
        #C50exact/c5.0dbg  -I 1 -m 1 -f tempLocation/pre
        self._state_dim: int = state_dim
        self._perc_dim: int = perc_dim

        self._s2f_func_list: List = []

        #check tempLocation dir exists, if not create it.
        self.dir_name = "tempLocation"
        check_temp_dir: bool = os.path.isdir(self.dir_name)
        if not check_temp_dir:
            os.makedirs(self.dir_name)
        # create empty files
        self.data_file = self.dir_name+"/pre.data"
        self.names_file = self.dir_name+"/pre.names"
        open(self.data_file,'w').close() 
        open(self.names_file,'w').close()

    @property
    def state_dim(self) -> int:
        return self._state_dim

    @property
    def perc_dim(self) -> int:
        return self._perc_dim

    def set_grammar(self, grammar) -> None:
        count = 1
        numerical_vars = []
        for a_mat, b_vec in grammar:
            self._s2f_func_list.append(
                construct_sample_to_feature_func(a_mat, b_vec))
            numerical_vars.append("dbar"+f'A{count}B{count}')
            numerical_vars.append("psibar"+f'A{count}B{count}')
            count += 1
        
        grammar_generation_utils.generateInputLanguageFile(self.names_file, numerical_vars, [])
    def add_implication_examples(self, *args) -> None:
        return super().add_implication_examples(*args)

    def add_positive_examples(self, *args) -> None:
        feature_vec_list = []
        for sample in args:
            feature_vec = []
            for sample_to_feature_vec in self._s2f_func_list:
                feature_vec.extend(sample_to_feature_vec(sample))
            feature_vec_list.append(feature_vec)

        print("Positive feature vectors (dbar, psibar):", feature_vec_list)
        self.write_to_file(self.data_file,feature_vec_list, "true")

    def add_negative_examples(self, *args) -> None:
        feature_vec_list = []
        for sample in args:
            feature_vec = []
            for sample_to_feature_vec in self._s2f_func_list:
                feature_vec.extend(sample_to_feature_vec(sample))
            feature_vec_list.append(feature_vec)

        print("Negative feature vectors (dbar, psibar):", feature_vec_list)
        self.write_to_file(self.data_file, feature_vec_list, "false")

    def write_to_file(self, file:str, feature_vec_list, label:str ):
        with open(file, 'a') as d_file:
            data_out = csv.writer(d_file)
            for f in feature_vec_list:
                print(f)
                data_out.writerow(f+[label])


    def learn(self) -> Tuple:
        # TODO read result from Dtree learner

        pass

def construct_sample_to_feature_func(a_mat: np.ndarray, b_vec: np.ndarray):
    perc_dim, state_dim = a_mat.shape

    def sample_to_feature_vec(sample):
        assert len(sample) == state_dim + perc_dim
        state = sample[0: state_dim]
        perc = sample[state_dim: state_dim+perc_dim]
        perc_bar = perc - (np.dot(state, a_mat.T) + b_vec)
        return perc_bar
    return sample_to_feature_vec

def test_dtree_learner():
    a_mat = np.array([[0., -1., 0.],
                      [0., 0., -1]])
    b_vec = np.zeros(2)

    learner = DTreeLearner(state_dim=3, perc_dim=2)
    learner.set_grammar([(a_mat, b_vec)])

    pos_examples = [
        (1., 2., 3., -2., -3.),
        (1., 2., 3., -1., -2.)
    ]
    learner.add_positive_examples(*pos_examples)
    neg_examples = [
        (10., 1.0, 1.0, 0.5, 0.5),
        (10., 1.0, 1.0, 1.5, 1.5),
        (10., 9.0, 9.0, 5.0, 5.0),
    ]
    learner.add_negative_examples(*neg_examples)

def test_sample_to_feature():
    # tuple
    a_mat = np.array([[0., -1., 0.],
                      [0., 0., -1]])
    b_vec = np.zeros(2)

    #construct_sample_to_feature_func: returns a function
    #map: lin_trans(a_mat and b_vec pair) -> func
    sample_to_feature_func = construct_sample_to_feature_func(a_mat, b_vec)
                                
    #map = {name1:sample_to_feature_func}
    sample = np.array([1., 2., 3., -2., -3.])
    # sample_to_feature_func will compute dBar and psiBar
    feature_vec = sample_to_feature_func(sample)
    print("sample: "+ str(feature_vec))
    assert np.array_equal(feature_vec, np.array([0., 0.]))

    sample = np.array([1., 2., 3., -1., -2.])
    feature_vec = sample_to_feature_func(sample)
    print("sample: "+ str(feature_vec))
    assert np.array_equal(feature_vec, np.array([1., 1.]))


if __name__ == "__main__":
    #test_sample_to_feature()
    test_dtree_learner()