SHOGUN
v2.0.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2011 Hidekazu Oiwa 00008 */ 00009 00010 #include <shogun/classifier/AveragedPerceptron.h> 00011 #include <shogun/labels/Labels.h> 00012 #include <shogun/mathematics/Math.h> 00013 #include <shogun/labels/BinaryLabels.h> 00014 00015 using namespace shogun; 00016 00017 CAveragedPerceptron::CAveragedPerceptron() 00018 : CLinearMachine(), learn_rate(0.1), max_iter(1000) 00019 { 00020 } 00021 00022 CAveragedPerceptron::CAveragedPerceptron(CDotFeatures* traindat, CLabels* trainlab) 00023 : CLinearMachine(), learn_rate(.1), max_iter(1000) 00024 { 00025 set_features(traindat); 00026 set_labels(trainlab); 00027 } 00028 00029 CAveragedPerceptron::~CAveragedPerceptron() 00030 { 00031 } 00032 00033 bool CAveragedPerceptron::train_machine(CFeatures* data) 00034 { 00035 ASSERT(m_labels); 00036 ASSERT(m_labels->get_label_type() == LT_BINARY); 00037 00038 if (data) 00039 { 00040 if (!data->has_property(FP_DOT)) 00041 SG_ERROR("Specified features are not of type CDotFeatures\n"); 00042 set_features((CDotFeatures*) data); 00043 } 00044 ASSERT(features); 00045 bool converged=false; 00046 int32_t iter=0; 00047 SGVector<int32_t> train_labels=((CBinaryLabels*) m_labels)->get_int_labels(); 00048 int32_t num_feat=features->get_dim_feature_space(); 00049 int32_t num_vec=features->get_num_vectors(); 00050 00051 ASSERT(num_vec==train_labels.vlen); 00052 w=SGVector<float64_t>(num_feat); 00053 float64_t* tmp_w=SG_MALLOC(float64_t, num_feat); 00054 float64_t* output=SG_MALLOC(float64_t, num_vec); 00055 00056 //start with uniform w, bias=0, tmp_bias=0 00057 bias=0; 00058 float64_t tmp_bias=0; 00059 for (int32_t i=0; i<num_feat; i++) 00060 w[i]=1.0/num_feat; 00061 00062 //loop till we either get everything classified right or reach max_iter 00063 00064 while (!converged && iter<max_iter) 00065 { 00066 converged=true; 00067 for (int32_t i=0; i<num_vec; i++) 00068 { 00069 output[i]=apply_one(i); 00070 00071 if (CMath::sign<float64_t>(output[i]) != train_labels.vector[i]) 00072 { 00073 converged=false; 00074 bias+=learn_rate*train_labels.vector[i]; 00075 features->add_to_dense_vec(learn_rate*train_labels.vector[i], i, w.vector, w.vlen); 00076 } 00077 00078 // Add current w to tmp_w, and current bias to tmp_bias 00079 // To calculate the sum of each iteration's w, bias 00080 for (int32_t j=0; j<num_feat; j++) 00081 tmp_w[j]+=w[j]; 00082 tmp_bias+=bias; 00083 } 00084 iter++; 00085 } 00086 00087 if (converged) 00088 SG_INFO("Averaged Perceptron algorithm converged after %d iterations.\n", iter); 00089 else 00090 SG_WARNING("Averaged Perceptron algorithm did not converge after %d iterations.\n", max_iter); 00091 00092 // calculate and set the average paramter of w, bias 00093 for (int32_t i=0; i<num_feat; i++) 00094 w[i]=tmp_w[i]/(num_vec*iter); 00095 bias=tmp_bias/(num_vec*iter); 00096 00097 SG_FREE(output); 00098 SG_FREE(tmp_w); 00099 00100 return converged; 00101 }