X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=src%2Frelevance.c;h=b9fc0e1b1a4ec06ebc20f1edd29cf61763541213;hb=f1200fd1cab4fa57feacd43046997ce2d23edbd5;hp=7f1943a9da5c139883ac538bb7cc634292352169;hpb=3371e5ba3a8d62b6edbb338984ac333bec6df01b;p=pazpar2-moved-to-github.git diff --git a/src/relevance.c b/src/relevance.c index 7f1943a..b9fc0e1 100644 --- a/src/relevance.c +++ b/src/relevance.c @@ -34,6 +34,7 @@ struct relevance int vec_len; struct word_entry *entries; pp2_charset_token_t prt; + int rank_cluster; NMEM nmem; }; @@ -45,18 +46,23 @@ struct word_entry { }; static int word_entry_match(struct word_entry *entries, const char *norm_str, - const char *frank, int *local_mult) + const char *rank, int *mult) { for (; entries; entries = entries->next) { if (!strcmp(norm_str, entries->norm_str)) { const char *cp = 0; - if (frank && (cp = strchr(frank, ' '))) + int no_read = 0; + sscanf(rank, "%d%n", mult, &no_read); + rank += no_read; + while (*rank == ' ') + rank++; + if (no_read > 0 && (cp = strchr(rank, ' '))) { - if ((cp - frank) == strlen(entries->ccl_field) && - memcmp(entries->ccl_field, frank, cp - frank) == 0) - *local_mult = atoi(cp + 1); + if ((cp - rank) == strlen(entries->ccl_field) && + memcmp(entries->ccl_field, rank, cp - rank) == 0) + *mult = atoi(cp + 1); } return entries->termno; } @@ -65,8 +71,8 @@ static int word_entry_match(struct word_entry *entries, const char *norm_str, } void relevance_countwords(struct relevance *r, struct record_cluster *cluster, - const char *words, int multiplier, const char *name, - const char *frank) + const char *words, const char *rank, + const char *name) { int *mult = cluster->term_frequency_vec_tmp; const char *norm_str; @@ -75,10 +81,11 @@ void relevance_countwords(struct relevance *r, struct record_cluster *cluster, for (i = 1; i < r->vec_len; i++) mult[i] = 0; + assert(rank); while ((norm_str = pp2_charset_token_next(r->prt))) { - int local_mult = multiplier; - int res = word_entry_match(r->entries, norm_str, frank, &local_mult); + int local_mult = 0; + int res = word_entry_match(r->entries, norm_str, rank, &local_mult); if (res) { assert(res < r->vec_len); @@ -141,7 +148,8 @@ static void pull_terms(struct relevance *res, struct ccl_rpn_node *n) } struct relevance *relevance_create_ccl(pp2_charset_fact_t pft, - struct ccl_rpn_node *query) + struct ccl_rpn_node *query, + int rank_cluster) { NMEM nmem = nmem_create(); struct relevance *res = nmem_malloc(nmem, sizeof(*res)); @@ -150,6 +158,7 @@ struct relevance *relevance_create_ccl(pp2_charset_fact_t pft, res->nmem = nmem; res->entries = 0; res->vec_len = 1; + res->rank_cluster = rank_cluster; res->prt = pp2_charset_token_create(pft, "relevance"); pull_terms(res, query); @@ -222,15 +231,9 @@ void relevance_prepare_read(struct relevance *rel, struct reclist *reclist) idfvec[i] = 0; else { - // This conditional may be terribly wrong - // It was there to address the situation where vec[0] == vec[i] - // which leads to idfvec[i] == 0... not sure about this - // Traditional TF-IDF may assume that a word that occurs in every - // record is irrelevant, but this is actually something we will - // see a lot - if ((idfvec[i] = log((float) rel->doc_frequency_vec[0] / - rel->doc_frequency_vec[i])) < 0.0000001) - idfvec[i] = 1; + /* add one to nominator idf(t,D) to ensure a value > 0 */ + idfvec[i] = log((float) (1 + rel->doc_frequency_vec[0]) / + rel->doc_frequency_vec[i]); } } // Calculate relevance for each document @@ -244,7 +247,17 @@ void relevance_prepare_read(struct relevance *rel, struct reclist *reclist) for (t = 1; t < rel->vec_len; t++) { float termfreq = (float) rec->term_frequency_vecf[t]; - relevance += 100000 * (termfreq * idfvec[t] + 0.0000005); + relevance += 100000 * termfreq * idfvec[t]; + } + if (!rel->rank_cluster) + { + struct record *record; + int cluster_size = 0; + + for (record = rec->records; record; record = record->next) + cluster_size++; + + relevance /= cluster_size; } rec->relevance_score = relevance; }