12 #include <Eigen/Dense>
40 std::shared_ptr<const GenericFeatureMatrix> local_features,
52 Eigen::LLT<types::DenseRowMajor<real_t>>
m_LLT;
71 [[nodiscard]] std::unique_ptr<WeightsInitializer>
72 make_initializer(
const std::shared_ptr<const GenericFeatureMatrix>& features)
const override;
82 std::shared_ptr<const GenericFeatureMatrix> local_features,
int max_pos,
85 m_MaxPos(max_pos), m_LLT(max_pos + 1)
96 Eigen::Ref<DenseRealVector> target,
99 m_DataSet->get_labels(label_id, m_LabelBuffer);
101 int num_pos = m_DataSet->num_positives(label_id);
102 if(num_pos > m_MaxPos) {
105 for(
int i = 0; i < m_LabelBuffer.size(); ++i) {
106 if(m_LabelBuffer.coeff(i) > 0.0) {
111 auto [p, a] = calculate_factors(label_id, target);
112 target = target * p + m_MeanOfAll * a;
114 real_t num_samples = m_DataSet->num_examples();
115 extract_sub_dataset(label_id);
118 m_GramMatrix.resize(num_pos + 1, num_pos + 1);
119 m_Target.resize(num_pos + 1);
120 m_Target.coeffRef(0) = m_NegTarget;
121 for (
int i = 1; i < num_pos + 1; ++i) {
122 m_Target.coeffRef(i) = m_PosTarget;
127 m_GramMatrix.coeffRef(0, 0) = m_MeanAllNormSquared;
130 for (
int i = 0; i < num_pos; ++i) {
131 for (
int j = i; j < num_pos; ++j) {
132 auto& a = m_PositiveInstances[i];
133 auto& b = m_PositiveInstances[j];
135 m_GramMatrix.coeffRef(i + 1, j + 1) = dot;
136 m_GramMatrix.coeffRef(j + 1, i + 1) = dot;
140 m_GramMatrix.coeffRef(0, 0) += m_GramMatrix.coeffRef(i + 1, i + 1) / num_samples / num_samples;
141 real_t xTa = m_PositiveInstances[i].dot(m_MeanOfAll);
142 m_GramMatrix.coeffRef(0, i+1) = xTa;
143 m_GramMatrix.coeffRef(0, 0) -= 2*xTa / num_samples;
148 for (
int i = 0; i < num_pos; ++i) {
149 for (
int j = 0; j < num_pos; ++j) {
150 m_GramMatrix.coeffRef(0, i + 1) -= m_GramMatrix.coeffRef(j, i + 1) / num_samples;
152 m_GramMatrix.coeffRef(i + 1, 0) = m_GramMatrix.coeff(0, i + 1);
155 m_GramMatrix.coeffRef(i + 1, i + 1) += m_Lambda;
157 m_GramMatrix.coeffRef(0, 0) += m_Lambda;
159 m_LLT.compute(m_GramMatrix);
160 m_AlphaVector = m_LLT.solve(m_Target);
163 target = m_AlphaVector[0] * m_MeanOfAll;
164 for (
int i = 1; i < num_pos + 1; ++i) {
165 target += (m_AlphaVector[i] - m_AlphaVector[0] / num_samples) * m_PositiveInstances[i - 1];
169 record(STAT_NUM_POS, [&]() ->
long {
return m_DataSet->num_positives(label_id); });
170 record(STAT_LOSS_REDUCTION, [&]() {
173 temp.modify().setZero();
175 return 100.f * (obj_at_zero - obj_at_new) / obj_at_zero;
179 template<
bool Sparse>
181 assert( m_DataSet->num_positives(label_id) <= m_MaxPos);
183 m_DataSet->get_labels(label_id, m_LabelBuffer);
186 for(
int i = 0; i < m_LabelBuffer.size(); ++i) {
187 if(m_LabelBuffer.coeff(i) <= 0.0) {
191 m_PositiveInstances[pos_count] = m_LocalFeatures->get<
MatrixType>().row(i);
197 std::unique_ptr<WeightsInitializer>
199 if(features->is_sparse()) {
200 return std::make_unique<MultiPosMeanInitializer<true>>(
203 return std::make_unique<MultiPosMeanInitializer<false>>(
213 return std::make_shared<MultiPosMeanStrategy>(std::move(data), pos, neg, max_pos);
An Eigen vector with versioning information, to implement simple caching of results.
void get_initial_weight(label_id_t label_id, Eigen::Ref< DenseRealVector > target, objective::Objective &objective) override
Generate an initial vector for the given label. The result should be placed in target.
MultiPosMeanInitializer(std::shared_ptr< const DatasetBase > data, const DenseRealVector &mean_of_all, std::shared_ptr< const GenericFeatureMatrix > local_features, int max_pos, real_t pos, real_t neg)
types::DenseRowMajor< real_t > m_GramMatrix
Eigen::LLT< types::DenseRowMajor< real_t > > m_LLT
typename TypeLookup< Sparse >::MatrixType MatrixType
stats::stat_id_t STAT_LOSS_REDUCTION
stats::stat_id_t STAT_NUM_POS
DenseRealVector m_AlphaVector
std::vector< VectorType > m_PositiveInstances
typename TypeLookup< Sparse >::VectorType VectorType
void extract_sub_dataset(label_id_t label_id)
MultiPosMeanStrategy(std::shared_ptr< const DatasetBase > data, real_t negative_target, real_t positive_target, int max_positives)
std::unique_ptr< WeightsInitializer > make_initializer(const std::shared_ptr< const GenericFeatureMatrix > &features) const override
Creats a new, thread local WeightsInitializer.
std::shared_ptr< const DatasetBase > m_DataSet
DenseRealVector m_MeanOfAllInstances
Strong typedef for an int to signify a label id.
Class that models an optimization objective.
void declare_stat(stat_id_t index, StatisticMetaData meta)
Declares a new statistics. This function just forwards all its arguments to the internal StatisticsCo...
constexpr stat_id_t STAT_DURATION
std::shared_ptr< WeightInitializationStrategy > create_multi_pos_mean_strategy(std::shared_ptr< DatasetBase > data, int max_pos, real_t pos=1, real_t neg=-2)
Creates an initialization strategy based on the mean of positive and negative features.
outer_const< T, dense_row_major_h > DenseRowMajor
types::DenseRowMajor< real_t > DenseFeatures
Dense Feature Matrix in Row Major format.
types::SparseVector< real_t > SparseRealVector
types::DenseVector< real_t > DenseRealVector
Any dense, real values vector.
types::SparseRowMajor< real_t > SparseFeatures
Sparse Feature Matrix in Row Major format.
float real_t
The default type for floating point values.
DenseRealVector VectorType
SparseFeatures MatrixType
SparseRealVector VectorType