Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <algorithm>
00012
00013 #include <shogun/lib/Time.h>
00014 #include <shogun/mathematics/Math.h>
00015 #include <shogun/multiclass/ShareBoost.h>
00016 #include <shogun/multiclass/ShareBoostOptimizer.h>
00017 #include <shogun/features/DenseSubsetFeatures.h>
00018 #include <shogun/labels/RegressionLabels.h>
00019
00020 using namespace shogun;
00021
00022 CShareBoost::CShareBoost()
00023 :CLinearMulticlassMachine(), m_nonzero_feas(0)
00024 {
00025 init_sb_params();
00026 }
00027
00028 CShareBoost::CShareBoost(CDenseFeatures<float64_t> *features, CMulticlassLabels *labs, int32_t num_nonzero_feas)
00029 :CLinearMulticlassMachine(new CMulticlassOneVsRestStrategy(), features, NULL, labs), m_nonzero_feas(num_nonzero_feas)
00030 {
00031 init_sb_params();
00032 }
00033
00034 void CShareBoost::init_sb_params()
00035 {
00036 SG_ADD(&m_nonzero_feas, "m_nonzero_feas", "Number of non-zero features", MS_NOT_AVAILABLE);
00037 }
00038
00039 SGVector<int32_t> CShareBoost::get_activeset()
00040 {
00041 return m_activeset.clone();
00042 }
00043
00044 bool CShareBoost::train_machine(CFeatures* data)
00045 {
00046 if (data)
00047 set_features(data);
00048
00049 if (m_features == NULL)
00050 SG_ERROR("No features given for training\n");
00051 if (m_labels == NULL)
00052 SG_ERROR("No labels given for training\n");
00053
00054 if (m_nonzero_feas <= 0)
00055 SG_ERROR("Set a valid (> 0) number of non-zero features to seek before training\n");
00056 if (m_nonzero_feas >= dynamic_cast<CDenseFeatures<float64_t>*>(m_features)->get_num_features())
00057 SG_ERROR("It doesn't make sense to use ShareBoost with num non-zero features >= num features in the data\n");
00058
00059 m_fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features)->get_feature_matrix();
00060 m_rho = SGMatrix<float64_t>(m_multiclass_strategy->get_num_classes(), m_fea.num_cols);
00061 m_rho_norm = SGVector<float64_t>(m_fea.num_cols);
00062 m_pred = SGMatrix<float64_t>(m_fea.num_cols, m_multiclass_strategy->get_num_classes());
00063 m_pred.zero();
00064
00065 m_activeset = SGVector<int32_t>(m_fea.num_rows);
00066 m_activeset.vlen = 0;
00067
00068 m_machines->reset_array();
00069 for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
00070 m_machines->push_back(new CLinearMachine());
00071
00072 CTime *timer = new CTime();
00073
00074 float64_t t_compute_pred = 0;
00075 for (int32_t t=0; t < m_nonzero_feas; ++t)
00076 {
00077 timer->start();
00078 compute_rho();
00079 int32_t i_fea = choose_feature();
00080 m_activeset.vector[m_activeset.vlen] = i_fea;
00081 m_activeset.vlen += 1;
00082 float64_t t_choose_feature = timer->cur_time_diff();
00083 timer->start();
00084 optimize_coefficients();
00085 float64_t t_optimize = timer->cur_time_diff();
00086
00087 SG_SPRINT(" SB[round %03d]: (%8.4f + %8.4f) sec.\n", t,
00088 t_compute_pred + t_choose_feature, t_optimize);
00089
00090 timer->start();
00091 compute_pred();
00092 t_compute_pred = timer->cur_time_diff();
00093 }
00094
00095 SG_UNREF(timer);
00096
00097
00098 m_fea = SGMatrix<float64_t>();
00099 m_rho = SGMatrix<float64_t>();
00100 m_rho_norm = SGVector<float64_t>();
00101 m_pred = SGMatrix<float64_t>();
00102
00103 return true;
00104 }
00105
00106 void CShareBoost::compute_pred()
00107 {
00108 CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(m_features);
00109 CDenseSubsetFeatures<float64_t> *subset_fea = new CDenseSubsetFeatures<float64_t>(fea, m_activeset);
00110 SG_REF(subset_fea);
00111 for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
00112 {
00113 CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
00114 CRegressionLabels *lab = machine->apply_regression(subset_fea);
00115 SGVector<float64_t> lab_raw = lab->get_labels();
00116 std::copy(lab_raw.vector, lab_raw.vector + lab_raw.vlen, m_pred.get_column_vector(i));
00117 SG_UNREF(machine);
00118 SG_UNREF(lab);
00119 }
00120 SG_UNREF(subset_fea);
00121 }
00122
00123 void CShareBoost::compute_pred(const float64_t *W)
00124 {
00125 int32_t w_len = m_activeset.vlen;
00126
00127 for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
00128 {
00129 CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
00130 SGVector<float64_t> w(w_len);
00131 std::copy(W + i*w_len, W + (i+1)*w_len, w.vector);
00132 machine->set_w(w);
00133 SG_UNREF(machine);
00134 }
00135 compute_pred();
00136 }
00137
00138 void CShareBoost::compute_rho()
00139 {
00140 CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
00141 for (int32_t i=0; i < m_rho.num_rows; ++i)
00142 {
00143 for (int32_t j=0; j < m_rho.num_cols; ++j)
00144 {
00145 int32_t label = lab->get_int_label(j);
00146
00147 m_rho(i,j) = CMath::exp((label == i) - m_pred(j, label) + m_pred(j, i));
00148 }
00149 }
00150
00151
00152 for (int32_t j=0; j < m_rho.num_cols; ++j)
00153 {
00154 m_rho_norm[j] = 0;
00155 for (int32_t i=0; i < m_rho.num_rows; ++i)
00156 m_rho_norm[j] += m_rho(i,j);
00157 }
00158 }
00159
00160 int32_t CShareBoost::choose_feature()
00161 {
00162 SGVector<float64_t> l1norm(m_fea.num_rows);
00163 for (int32_t j=0; j < m_fea.num_rows; ++j)
00164 {
00165 if (std::find(&m_activeset[0], &m_activeset[m_activeset.vlen], j) !=
00166 &m_activeset[m_activeset.vlen])
00167 {
00168 l1norm[j] = 0;
00169 }
00170 else
00171 {
00172 l1norm[j] = 0;
00173 CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
00174 for (int32_t k=0; k < m_multiclass_strategy->get_num_classes(); ++k)
00175 {
00176 float64_t abssum = 0;
00177 for (int32_t ii=0; ii < m_fea.num_cols; ++ii)
00178 {
00179 abssum += m_fea(j, ii)*(m_rho(k, ii)/m_rho_norm[ii] -
00180 (j == lab->get_int_label(ii)));
00181 }
00182 l1norm[j] += CMath::abs(abssum);
00183 }
00184 l1norm[j] /= m_fea.num_cols;
00185 }
00186 }
00187
00188 return SGVector<float64_t>::arg_max(l1norm.vector, 1, l1norm.vlen);
00189 }
00190
00191 void CShareBoost::optimize_coefficients()
00192 {
00193 ShareBoostOptimizer optimizer(this, false);
00194 optimizer.optimize();
00195 }
00196
00197 void CShareBoost::set_features(CFeatures *f)
00198 {
00199 CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(f);
00200 if (fea == NULL)
00201 SG_ERROR("Require DenseFeatures<float64_t>\n");
00202 CLinearMulticlassMachine::set_features(fea);
00203 }