SHOGUN
3.2.1
首页
相关页面
模块
类
文件
文件列表
文件成员
全部
类
命名空间
文件
函数
变量
类型定义
枚举
枚举值
友元
宏定义
组
页
src
shogun
statistics
MMDKernelSelectionComb.cpp
浏览该文件的文档.
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 3 of the License, or
5
* (at your option) any later version.
6
*
7
* Written (W) 2012-2013 Heiko Strathmann
8
*/
9
10
#include <
shogun/statistics/MMDKernelSelectionComb.h
>
11
#include <
shogun/statistics/KernelTwoSampleTest.h
>
12
#include <
shogun/kernel/CombinedKernel.h
>
13
14
using namespace
shogun;
15
16
CMMDKernelSelectionComb::CMMDKernelSelectionComb
() :
17
CMMDKernelSelection
()
18
{
19
init();
20
}
21
22
CMMDKernelSelectionComb::CMMDKernelSelectionComb
(
23
CKernelTwoSampleTest
* mmd) :
CMMDKernelSelection
(mmd)
24
{
25
init();
26
}
27
28
CMMDKernelSelectionComb::~CMMDKernelSelectionComb
()
29
{
30
}
31
32
void
CMMDKernelSelectionComb::init()
33
{
34
#ifdef HAVE_LAPACK
35
SG_ADD
(&
m_opt_max_iterations
,
"opt_max_iterations"
,
"Maximum number of "
36
"iterations for qp solver"
,
MS_NOT_AVAILABLE
);
37
SG_ADD
(&
m_opt_epsilon
,
"opt_epsilon"
,
"Stopping criterion for qp solver"
,
38
MS_NOT_AVAILABLE
);
39
SG_ADD
(&
m_opt_low_cut
,
"opt_low_cut"
,
"Low cut value for optimization "
40
"kernel weights"
,
MS_NOT_AVAILABLE
);
41
42
/* sensible values for optimization */
43
m_opt_max_iterations
=10000;
44
m_opt_epsilon
=10E-15;
45
m_opt_low_cut
=10E-7;
46
#endif
47
}
48
49
#ifdef HAVE_LAPACK
50
/* no reference counting, use the static context constructor of SGMatrix */
51
SGMatrix<float64_t>
CMMDKernelSelectionComb::m_Q
=
SGMatrix<float64_t>
(
false
);
52
53
const
float64_t
*
CMMDKernelSelectionComb::get_Q_col
(uint32_t i)
54
{
55
return
&
m_Q
[
m_Q
.
num_rows
*i];
56
}
57
59
void
CMMDKernelSelectionComb::print_state
(libqp_state_T state)
60
{
61
SG_SDEBUG
(
"CMMDKernelSelectionComb::print_state: libqp state:"
62
" primal=%f\n"
, state.QP);
63
}
64
65
CKernel
*
CMMDKernelSelectionComb::select_kernel
()
66
{
67
/* cast is safe due to assertion in constructor */
68
CCombinedKernel
* combined=(
CCombinedKernel
*)
m_mmd
->
get_kernel
();
69
70
/* optimise for kernel weights and set them */
71
SGVector<float64_t>
weights=
compute_measures
();
72
combined->
set_subkernel_weights
(weights);
73
74
/* note that kernel is SG_REF'ed from getter above */
75
return
combined;
76
}
77
78
SGVector<float64_t>
CMMDKernelSelectionComb::solve_optimization
(
79
SGVector<float64_t>
mmds)
80
{
81
/* readability */
82
index_t
num_kernels=mmds.
vlen
;
83
84
/* compute sum of mmds to generate feasible point for convex program */
85
float64_t
sum_mmds=0;
86
for
(
index_t
i=0; i<mmds.
vlen
; ++i)
87
sum_mmds+=mmds[i];
88
89
/* QP: 0.5*x'*Q*x + f'*x
90
* subject to
91
* mmds'*x = b
92
* LB[i] <= x[i] <= UB[i] for all i=1..n */
93
SGVector<float64_t>
Q_diag(num_kernels);
94
SGVector<float64_t>
f(num_kernels);
95
SGVector<float64_t>
lb(num_kernels);
96
SGVector<float64_t>
ub(num_kernels);
97
SGVector<float64_t>
weights(num_kernels);
98
99
/* init everything, there are two cases possible: i) at least one mmd is
100
* is positive, ii) all mmds are negative */
101
bool
one_pos=
false
;
102
for
(
index_t
i=0; i<mmds.
vlen
; ++i)
103
{
104
if
(mmds[i]>0)
105
{
106
SG_DEBUG
(
"found at least one positive MMD\n"
)
107
one_pos=
true
;
108
break
;
109
}
110
}
111
112
if
(!one_pos)
113
{
114
SG_WARNING
(
"CMMDKernelSelectionComb::solve_optimization(): all mmd "
115
"estimates are negative. This is techically possible, although "
116
"extremely rare. Consider using different kernels. "
117
"This combination will lead to a bad two-sample test. Since any"
118
"combination is bad, will now just return equally distributed "
119
"kernel weights\n"
);
120
121
/* if no element is positive, we can choose arbritary weights since
122
* the results will be bad anyway */
123
weights.
set_const
(1.0/num_kernels);
124
}
125
else
126
{
127
SG_DEBUG
(
"one MMD entry is positive, performing optimisation\n"
)
128
/* do optimisation, init vectors */
129
for
(
index_t
i=0; i<num_kernels; ++i)
130
{
131
Q_diag[i]=
m_Q
(i,i);
132
f[i]=0;
133
lb[i]=0;
134
ub[i]=
CMath::INFTY
;
135
136
/* initial point has to be feasible, i.e. mmds'*x = b */
137
weights[i]=1.0/sum_mmds;
138
}
139
140
/* start libqp solver with desired parameters */
141
SG_DEBUG
(
"starting libqp optimization\n"
)
142
libqp_state_T qp_exitflag=libqp_gsmo_solver(&
get_Q_col
, Q_diag.
vector
,
143
f.
vector
, mmds.
vector
,
144
one_pos ? 1 : -1,
145
lb.
vector
, ub.
vector
,
146
weights.
vector
, num_kernels,
m_opt_max_iterations
,
147
m_opt_epsilon
, &(
CMMDKernelSelectionComb::print_state
));
148
149
SG_DEBUG
(
"libqp returns: nIts=%d, exit_flag: %d\n"
, qp_exitflag.nIter,
150
qp_exitflag.exitflag);
151
152
/* set really small entries to zero and sum up for normalization */
153
float64_t
sum_weights=0;
154
for
(
index_t
i=0; i<weights.
vlen
; ++i)
155
{
156
if
(weights[i]<
m_opt_low_cut
)
157
{
158
SG_DEBUG
(
"lowcut: weight[%i]=%f<%f setting to zero\n"
, i, weights[i],
159
m_opt_low_cut
);
160
weights[i]=0;
161
}
162
163
sum_weights+=weights[i];
164
}
165
166
/* normalize (allowed since problem is scale invariant) */
167
for
(
index_t
i=0; i<weights.
vlen
; ++i)
168
weights[i]/=sum_weights;
169
}
170
171
return
weights;
172
}
173
#else
174
CKernel
*
CMMDKernelSelectionComb::select_kernel
()
175
{
176
SG_ERROR
(
"CMMDKernelSelectionComb::select_kernel(): LAPACK needs to be "
177
"installed in order to use weight optimisation for combined "
178
"kernels!\n"
);
179
return
NULL;
180
}
181
182
SGVector<float64_t>
CMMDKernelSelectionComb::compute_measures
()
183
{
184
SG_ERROR
(
"CMMDKernelSelectionComb::select_kernel(): LAPACK needs to be "
185
"installed in order to use weight optimisation for combined "
186
"kernels!\n"
);
187
return
SGVector<float64_t>
();
188
}
189
190
SGVector<float64_t>
CMMDKernelSelectionComb::solve_optimization
(
191
SGVector<float64_t>
mmds)
192
{
193
SG_ERROR
(
"CMMDKernelSelectionComb::solve_optimization(): LAPACK needs to be "
194
"installed in order to use weight optimisation for combined "
195
"kernels!\n"
);
196
return
SGVector<float64_t>
();
197
}
198
#endif
SHOGUN
机器学习工具包 - 项目文档