-
Notifications
You must be signed in to change notification settings - Fork 11
/
runtree.m
157 lines (126 loc) · 5.51 KB
/
runtree.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
function fitness = runtree(gp,ID,knockout)
%RUNTREE Run the fitness function on an individual in the current population.
%
% RUNTREE(GP,ID) runs the fitness function using a user selected
% individual with numeric identifier ID from the current population.
% Despite the name RUNTREE will run either a single or a multigene
% individual.
%
% RUNTREE(GP,'best') runs the fitness function using the 'best'
% individual in the current population.
%
% RUNTREE(GP,'valbest') runs the fitness function using the best
% individual on the validation data set (if it exists - for symbolic
% regression problems that use the fitness function REGRESSMULTI_FITFUN).
%
% RUNTREE(GP,'testbest') runs the fitness function using the best
% individual on the test data set (if it exists - for symbolic
% regression problems that use the fitness function REGRESSMULTI_FITFUN).
%
% RUNTREE(GP,GPMODEL) runs the fitness function using the GPMODEL struct
% representing a multigene regression model, i.e. the struct returned by
% the functions GPMODEL2STRUCT or GENES2GPMODEL.
%
% FITNESS = RUNTREE(GP,ID) also returns the FITNESS value as returned by
% the fitness function specified in gp.fitness.fitfun
%
% Additional functionality:
%
% RUNTREE can also accept an optional third argument KNOCKOUT which
% should be a boolean vector the with same number of entries as genes in
% the individual to be run. This evaluates the individual with the
% indicated genes removed ('knocked out').
%
% E.g. RUNTREE(GP,'best',[1 0 0 1]) knocks out the 1st and 4th genes from
% the best individual of run. In the case of multigene symbolic
% regression (i.e. if the fitness function is REGRESSMULTI_FITFUN) the
% weights for the remaining genes are recomputed by least squares
% regression on the training data.
%
% Copyright (c) 2009-2015 Dominic Searson
%
% GPTIPS 2
%
% See also EVALFITNESS, GPMODELREPORT
if nargin < 2 || isempty(ID)
disp('Basic usage is RUNTREE(GP,ID) where ID is the population identifier of the selected individual.');
disp('or RUNTREE(GP,''best'') to run the best individual in the population.');
if nargout > 0
fitness = [];
end
return;
elseif nargin < 3
knockout = 0;
end
if isempty(knockout) || ~any(knockout)
doknockout = false;
else
doknockout = true;
end
i = ID;
if isnumeric(ID)
if i > 0 && i <= gp.runcontrol.pop_size
%set this in case the fitness function needs to retrieve
%the right returnvalues
gp.state.current_individual = i;
treestrs = tree2evalstr(gp.pop{i},gp);
%if genes are being knocked out then remove appropriate gene
if doknockout
treestrs = kogene(treestrs, knockout);
gp.state.force_compute_theta = true; %need to recompute gene weights if doing symbolic regression
gp.userdata.showgraphs = true; %if using symbolic regression, plot graphs
end
fitness = feval(gp.fitness.fitfun,treestrs,gp);
else
error('A valid population member ID must be entered, e.g. 1, 99 or ''best''');
end
elseif ischar(ID) && strcmpi(ID,'best')
gp.fitness.returnvalues{gp.state.current_individual} = gp.results.best.returnvalues;
treestrs = gp.results.best.eval_individual;
if doknockout
treestrs = kogene(treestrs, knockout);
gp.state.force_compute_theta = true;
gp.userdata.showgraphs = true;
end
fitness = feval(gp.fitness.fitfun,treestrs,gp);
elseif ischar(ID) && strcmpi(ID,'valbest')
% check that validation results/data present
if ~isfield(gp.results,'valbest')
disp('No validation results/data were found. Try runtree(gp,''best'') instead.');
return;
end
%copy "valbest" return values to a slot in the "current" return values
gp.fitness.returnvalues{gp.state.current_individual} = gp.results.valbest.returnvalues;
treestrs = gp.results.valbest.eval_individual;
if doknockout
treestrs = kogene(treestrs, knockout);
gp.state.force_compute_theta = true;
gp.userdata.showgraphs = true;
end
fitness=feval(gp.fitness.fitfun,treestrs,gp);
elseif ischar(ID) && strcmpi(ID,'testbest')
% check that test data results are present
if ~isfield(gp.results,'testbest')
disp('No test results/data were found. Try runtree(gp,''best'') instead.');
return;
end
%copy "testbest" return values to a slot in the "current" return values
gp.fitness.returnvalues{gp.state.current_individual} = gp.results.testbest.returnvalues;
treestrs = gp.results.testbest.eval_individual;
if doknockout
treestrs = kogene(treestrs, knockout);
gp.state.force_compute_theta = true;
gp.userdata.showgraphs = true;
end
fitness=feval(gp.fitness.fitfun,treestrs,gp);
%if the selected individual is a GPMODEL struct (NB knockout disabled
%for this form)
elseif isa(ID,'struct') && isfield(ID,'source') && ...
(strcmpi(ID.source,'gpmodel2struct') || strcmpi(ID.source,'genes2gpmodel') );
treestrs = ID.genes.geneStrs;
treestrs = tree2evalstr(treestrs,gp);
gp.fitness.returnvalues{gp.state.current_individual} = ID.genes.geneWeights;
fitness = feval(gp.fitness.fitfun,treestrs,gp);
else
error('Invalid argument.');
end