00001 #ifndef Impala_Core_Trec_SearchResult_h
00002 #define Impala_Core_Trec_SearchResult_h
00003
00004 #include "Core/Trec/SearchJudge.h"
00005
00006 namespace Impala
00007 {
00008 namespace Core
00009 {
00010 namespace Trec
00011 {
00012
00013
00014 class SearchResult
00015 {
00016 public:
00017
00018 SearchResult()
00019 {
00020 }
00021
00022 SearchResult(std::string fileName)
00023 {
00024 Load(fileName);
00025 }
00026
00027 SearchResult(std::string topic, std::vector<std::string> shots)
00028 {
00029 mTopic = topic;
00030 mShot = shots;
00031 }
00032
00033 void
00034 Load(std::string fileName)
00035 {
00036 File f(fileName, "r");
00037 if (! f.Valid())
00038 return;
00039 Util::StringParser first(f.ReadLine(true));
00040 first.Advance('"');
00041 mTopic = first.GetString();
00042 f.ReadLine(true);
00043 while (! f.Eof())
00044 {
00045 std::string line = f.ReadLine(true);
00046 if (! line[0])
00047 continue;
00048 Util::StringParser p(line);
00049 std::string str = p.GetString(' ', false);
00050 if (str != std::string("<item"))
00051 continue;
00052 p.Advance('"', 3);
00053 str = p.GetString();
00054 mShot.push_back(str);
00055 }
00056 }
00057
00058 void
00059 Load(std::string topic, std::vector<std::string> shots)
00060 {
00061 mShot.clear();
00062 mTopic = topic;
00063 mShot = shots;
00064 }
00065
00066 void
00067 Judge(SearchJudge* theJudge, bool verbose = false)
00068 {
00069 mJudgement.clear();
00070 mHits.clear();
00071 mPrecision.clear();
00072 int nrRelevant = theJudge->GetNrRelevant(mTopic);
00073 int hits = 0;
00074 double accumPrecision = 0;
00075 for (int i=0 ; i<mShot.size() ; i++)
00076 {
00077 int judgement = theJudge->Judge(mTopic, mShot[i]);
00078 int nr = i+1;
00079 if (judgement == 1)
00080 {
00081 if (verbose && (nr <= 10))
00082 std::cout << " Hit at " << nr << std::endl;
00083 hits++;
00084 accumPrecision += (double) hits / nr;
00085 }
00086 double precision = (double) hits / nr;
00087 if (verbose && (nr == 10))
00088 std::cout << "Hits at 10 : " << hits << ", precision : "
00089 << precision << std::endl;
00090 if (verbose && (nr == 30))
00091 std::cout << "Hits at 30 : " << hits << ", precision : "
00092 << precision << std::endl;
00093 if (verbose && (nr == 100))
00094 std::cout << "Hits at 100 : " << hits << ", precision : "
00095 << precision << std::endl;
00096 if (verbose && (nr == 1000))
00097 std::cout << "Hits at 1000 : " << hits << ", precision : "
00098 << precision << std::endl;
00099 mJudgement.push_back(judgement);
00100 mHits.push_back(hits);
00101 mPrecision.push_back(precision);
00102 }
00103 mAp = accumPrecision / nrRelevant;
00104 if (verbose)
00105 std::cout << "average precision : " << mAp << std::endl;
00106 }
00107
00108 double
00109 GetAveragePrecision()
00110 {
00111 return mAp;
00112 }
00113
00114 int
00115 NrElements()
00116 {
00117 return mShot.size();
00118 }
00119
00120 std::string
00121 GetShot(int idx)
00122 {
00123 return mShot[idx];
00124 }
00125
00126 int
00127 GetJudgement(int idx)
00128 {
00129 return mJudgement[idx];
00130 }
00131
00132 int
00133 GetHits(int idx)
00134 {
00135 return mHits[idx];
00136 }
00137
00138 double
00139 GetPrecision(int idx)
00140 {
00141 return mPrecision[idx];
00142 }
00143
00144 std::string
00145 Describe(int idx)
00146 {
00147 std::string jString("no judgement");
00148 if (mJudgement[idx] == 0)
00149 jString = std::string("not relevant");
00150 if (mJudgement[idx] == 1)
00151 jString = std::string("is relevant");
00152 return std::string("nr ") + MakeString(idx+1) + " " + mShot[idx] + ", "
00153 + jString + ", hits = " + MakeString(mHits[idx])
00154 + ", precision = " + MakeString(mPrecision[idx]);
00155 }
00156
00157 private:
00158
00159 std::string mTopic;
00160 std::vector<std::string> mShot;
00161 std::vector<int> mJudgement;
00162 std::vector<int> mHits;
00163 std::vector<double> mPrecision;
00164 double mAp;
00165
00166 };
00167
00168 }
00169 }
00170 }
00171
00172 #endif