[db7908]: / Ensemble Learning / Boosting / gradient_boosting_train.m

Download this file

93 lines (85 with data), 4.3 kB

 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
% Practicum, Task #3, 'Compositions of algorithms'.
%
% FUNCTION:
% [model] = gradient_boosting_train (X, y, num_iterations, base_algorithm, loss, ...
% param_name1, param_value1, param_name2, param_value2, ...
% param_name3, param_value3, param_name3, param_value3)
%
% DESCRIPTION:
% This function train the composition of algorithms using gradient boosting method.
%
% INPUT:
% X --- matrix of objects, N x K double matrix, N --- number of objects,
% K --- number of features.
% y --- vector of answers, N x 1 double vector, N --- number of objects. y
% can have only two values --- +1 and -1 in case of classification
% and all possible double values in case of regression.
% num_iterations --- the number ob algorithms in composition, scalar.
% base_algorithm --- the base algorithm, string. Can have one of two
% values: 'regression_tree' or 'epsilon_svr'.
% loss --- the loss function, string. Can have one of two values:
% 'logistic' (for classification) or 'absolute' (for regression).
% param_name1 --- learning rate, scalar.
% param_name2 --- parameter of base_algorithm. For 'regression_tree' it
% is a 'min_parent' --- min number of objects in the leaf of
% regression tree. For 'epsilon_svr' it is 'epsilon' parameter.
% param_name3 --- parameter, that exists only for 'epsilon_svr', it is a
% 'gamma' parameter.
% param_name4 --- parameter, that exists only for 'epsilon_svr', it is a
% 'C' parameter.
% param_value1, param_value2, param_value3, param_value4 --- values of
% corresponding parametres, scalar.
% OUTPUT:
% model --- trained composition, structure with three fields
% - b_0 --- the base of composition, scalar
% - weights --- double array of weights, 1 x num_iterations
% - models --- cell array with trained models, 1 x num_iterations
% - algorithm --- string, 'epsilon_svr' or 'regression_tree'
% - loss --- loss parameter (from INPUT).
%
% AUTHOR:
% Murat Apishev (great-mel@yandex.ru)
%
function [model] = gradient_boosting_train (X, y, num_iterations, base_algorithm, loss, ...
param_name1, param_value1, param_name2, param_value2, ...
param_name3, param_value3, param_name4, param_value4)
no_objects = size(X, 1);
if ~strcmp(base_algorithm, 'epsilon_svr') && ~strcmp(base_algorithm, 'regression_tree')
error('Incorrect type of algorithm!')
end
if strcmp(loss, 'logistic')
loss_function = @(a, b) log(1 + exp(-a .* b));
grad_a_loss_function = @(a, b) -b .* exp(-a .* b) ./ ((1 + exp(-a .* b)));
elseif strcmp(loss, 'absolute')
loss_function = @(a, b) abs(a - b);
grad_a_loss_function = @(a, b) -sign(b - a);
else
error('Incorrect type of loss function!');
end
func = @(c) sum(loss_function(y, c));
b_0 = fminsearch(func, 0);
model.b_0 = b_0;
model.algorithm = base_algorithm;
model.models = cell([1 num_iterations]);
model.loss = loss;
% the length of model is number of finite weights, not number of models!
model.weights = repmat(+Inf, 1, num_iterations);
z = zeros([no_objects 1]) + b_0;
delta = zeros([no_objects 1]);
for iter = 1 : num_iterations
for obj = 1 : no_objects
delta(obj) = -grad_a_loss_function(z(obj), y(obj));
end
if strcmp(base_algorithm, 'epsilon_svr')
model.models{iter} = svmtrain(delta, X, [' -s 3 -g ', num2str(param_value3), ...
' -c ', num2str(param_value4), ' -e ', num2str(param_value2)]);
value = svmpredict(y, X, model.models{iter});
elseif strcmp(base_algorithm, 'regression_tree')
model.models{iter} = RegressionTree.fit(X, delta, 'minparent', param_value2);
value = predict(model.models{iter}, X);
end
func = @(g) sum(loss_function(z + g * value, y));
model.weights(iter) = fminsearch(func, 0);
z = z + model.weights(iter) * value * param_value1;
end
end