Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lexicase survival #23

Merged
merged 9 commits into from Aug 2, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions few/few.py
Expand Up @@ -57,7 +57,7 @@ def __init__(self, population_size=50, generations=100,
random_state=np.random.randint(9999999), verbosity=0,
scoring_function=None, disable_update_check=False,
elitism=True, boolean = False,classification=False,clean=False,
track_diversity=False,mdr=False,otype='f',c=True, weight_parents=False):
track_diversity=False,mdr=False,otype='f',c=True, weight_parents=False, lex_size=False):
# sets up GP.

# Save params to be recalled later by get_params()
Expand Down Expand Up @@ -92,6 +92,7 @@ def __init__(self, population_size=50, generations=100,
self.op_weight = op_weight
self.max_stall = max_stall
self.weight_parents = weight_parents
self.lex_size = lex_size
self.seed_with_ml = seed_with_ml
self.erc = erc
self.random_state = random_state
Expand Down Expand Up @@ -824,6 +825,9 @@ def main():
parser.add_argument('--weight_parents', action='store_true',dest='WEIGHT_PARENTS',default=False,
help='Feature importance determines parent pressure for selection.')

parser.add_argument('--lex_size', action='store_true',dest='LEX_SIZE',default=False,
help='Size mediated parent selection for lexicase survival.')

parser.add_argument('-sel', action='store', dest='SEL',
default='epsilon_lexicase',
choices = ['tournament','lexicase','epsilon_lexicase',
Expand Down Expand Up @@ -951,7 +955,7 @@ def main():
fit_choice = args.FIT_CHOICE,boolean=args.BOOLEAN,
classification=args.CLASSIFICATION,clean = args.CLEAN,
track_diversity=args.TRACK_DIVERSITY,mdr=args.MDR,
otype=args.OTYPE,c=args.c, weight_parents = args.WEIGHT_PARENTS)
otype=args.OTYPE,c=args.c, weight_parents = args.WEIGHT_PARENTS, lex_size = args.LEX_SIZE)

learner.fit(training_features, training_labels)
# pdb.set_trace()
Expand Down
29 changes: 21 additions & 8 deletions few/lib/epsilon_lexicase.h
Expand Up @@ -81,7 +81,7 @@ static random_device rd;
static mt19937 gen(rd());
//extern "C"
void epsilon_lexicase(const ExtMat & F, int n, int d,
int num_selections, ExtVec& locs)
int num_selections, ExtVec& locs, bool lex_size, ExtVec& sizes)
{
// training cases
// ExtMat T (F, n, d);
Expand All @@ -96,15 +96,28 @@ void epsilon_lexicase(const ExtMat & F, int n, int d,
for (int i = 0; i<epsilon.size(); ++i)
epsilon(i) = mad(F.col(i));



// individual locations
vector<int> ind_locs(n);
iota(ind_locs.begin(),ind_locs.end(),0);
vector<int> ind_locs(n);
if(lex_size){
char message[200];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get rid of this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. removed message array declaration

//randomly select a size from sizes
int max_index = sizes.size();
int random_index = rand() % max_index;

// individual locations
int j=0;
for(int i=0;i<max_index;i++){
if(sizes[i]<=sizes[random_index])
ind_locs.push_back(i);
}

}
else{
// individual locations
iota(ind_locs.begin(),ind_locs.end(),0);
}

// temporary winner pool
vector<int> winner;

for (int i = 0; i<num_selections; ++i){
//cout << "selection " << i << "\n";
// perform selection
Expand All @@ -121,7 +134,7 @@ void epsilon_lexicase(const ExtMat & F, int n, int d,
winner.resize(0);
// minimum error on case
double minfit;
for (int j = 0; j< can_locs.size(); ++j){
for (int j = 0; j<can_locs.size(); ++j){
if (j==0 || F(can_locs[j],cases.back())<minfit )
minfit = F(can_locs[j],cases.back());
}
Expand Down
7 changes: 4 additions & 3 deletions few/lib/few_lib.pyx
Expand Up @@ -2,16 +2,17 @@
from eigency.core cimport *
cimport numpy as np
from libcpp.vector cimport vector
from libcpp cimport bool

cdef extern from "epsilon_lexicase.h":
cdef void _epsilon_lexicase "epsilon_lexicase"(Map[ArrayXXd] & F, int n,
int d, int num_selections,
Map[ArrayXi] & locs)
Map[ArrayXi] & locs, bool lex_size, Map[ArrayXi] &sizes)

# This will be exposed to Python
def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs):
def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs, bool lex_size, np.ndarray sizes):
return _epsilon_lexicase(Map[ArrayXXd](F), n, d, num_selections,
Map[ArrayXi](locs))
Map[ArrayXi](locs), lex_size, Map[ArrayXi](sizes))
# WIP
# cdef extern from "evaluation.h":
# cdef void _evaluate "evaluate"(node n, Map[ArrayXXd] & features,
Expand Down
16 changes: 12 additions & 4 deletions few/selection.py
Expand Up @@ -25,8 +25,13 @@ def survival(self,parents,offspring,elite=None,elite_index=None,X=None,F=None,F_
survivors, survivor_index = self.lexicase(parents + offspring, num_selections = len(parents), survival = True)
elif self.sel == 'epsilon_lexicase':
# survivors, survivor_index = self.epsilon_lexicase(parents + offspring, num_selections = len(parents), survival = True)
survivor_index = self.epsilon_lexicase(np.vstack((F,F_offspring)), num_selections = F.shape[0], survival = True)
survivors = [(parents+ offspring)[s] for s in survivor_index]
if self.lex_size:
sizes = [len(i.stack) for i in (parents + offspring)]
survivor_index = self.epsilon_lexicase(np.vstack((F,F_offspring)), sizes, num_selections = F.shape[0], survival = True)
survivors = [(parents+ offspring)[s] for s in survivor_index]
else:
survivor_index = self.epsilon_lexicase(np.vstack((F,F_offspring)), [], num_selections = F.shape[0], survival = True)
survivors = [(parents+ offspring)[s] for s in survivor_index]
elif self.sel == 'deterministic_crowding':
survivors, survivor_index = self.deterministic_crowding(parents,offspring,X,X_offspring)
elif self.sel == 'random':
Expand Down Expand Up @@ -108,14 +113,17 @@ def lexicase(self,individuals, num_selections=None, epsilon = False, survival =

return winners, locs

def epsilon_lexicase(self, F, num_selections=None, survival = False):
def epsilon_lexicase(self, F, sizes, num_selections=None, survival = False):
"""conducts epsilon lexicase selection for de-aggregated fitness vectors"""
# pdb.set_trace()
if self.c: # use c library
# define c types
locs = np.empty(num_selections,dtype='int32',order='F')
# self.lib.epsilon_lexicase(F,F.shape[0],F.shape[1],num_selections,locs)
ep_lex(F,F.shape[0],F.shape[1],num_selections,locs)
if self.lex_size:
ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,np.array(sizes))
else:
ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,np.array([]))
return locs
else: # use python version
if num_selections is None:
Expand Down