⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 barrel.c

📁 良好的代码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Managing the connection between document-vectors (wi2dvf's) and cdocs   Copyright (C) 1997 Andrew McCallum   Written by:  Andrew Kachites McCallum <mccallum@cs.cmu.edu>   This file is part of the Bag-Of-Words Library, `libbow'.   This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public License   as published by the Free Software Foundation, version 2.      This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this library; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA */#include <bow/libbow.h>static int _bow_barrel_version = -1;#define BOW_DEFAULT_BARREL_VERSION 3/* Old, deprecated identifiers for methods. *//* Identifiers for methods */typedef enum _bow_method_id {  bow_method_id_tfidf_words,	/* TFIDF/Rocchio */  bow_method_id_tfidf_log_words,  bow_method_id_tfidf_log_occur,  bow_method_id_tfidf_prtfidf,  bow_method_id_naivebayes,	/* Naive Bayes */  bow_method_id_prind,		/* Fuhr's Probabilistic Indexing */  bow_method_id_max} bow_method_id;bow_method* _old_bow_methods[bow_method_id_max] = {  [bow_method_id_tfidf_words] = &bow_method_tfidf_words,  [bow_method_id_tfidf_log_words] = &bow_method_tfidf_log_words,  [bow_method_id_tfidf_log_occur] = &bow_method_tfidf_log_occur,  [bow_method_id_naivebayes] = &bow_method_naivebayes,  [bow_method_id_prind] = &bow_method_prind};/* Create a new, empty `bow_barrel', with cdoc's of size ENTRY_SIZE   and cdoc free function FREE_FUNC.*/bow_barrel *bow_barrel_new (int word_capacity, 		int class_capacity, int entry_size, void (*free_func)()){  bow_barrel *ret;  ret = bow_malloc (sizeof (bow_barrel));  ret->cdocs = bow_array_new (class_capacity, entry_size, free_func);  ret->wi2dvf = bow_wi2dvf_new (word_capacity);  ret->method = (bow_argp_method 		 ? : bow_method_at_name (bow_default_method_name));  return ret;}static void_bow_barrel_cdoc_free (bow_cdoc *cdoc){  if (cdoc->filename)    free ((void*)(cdoc->filename));}/* Add statistics about the document described by CDOC and WV to the   BARREL. */intbow_barrel_add_document (bow_barrel *barrel,			 bow_cdoc *cdoc,			 bow_wv *wv){  int di;  /* Add the CDOC.  (This makes a new copy of CDOC in the array.) */  di = bow_array_append (barrel->cdocs, cdoc);  /* Add the words in WV. */  bow_wi2dvf_add_di_wv (&(barrel->wi2dvf), di, wv);  return di;}/* Add statistics to the barrel BARREL by indexing all the documents   found when recursively decending directory DIRNAME.  Return the number   of additional documents indexed. */intbow_barrel_add_from_text_dir (bow_barrel *barrel, 			      const char *dirname, 			      const char *except_name,			      int class){  int text_file_count, binary_file_count;  int barrel_index_file (const char *filename, void *context)    {      FILE *fp;      bow_cdoc cdoc;      int di;			/* a document index */      /* If the filename matches the exception name, return immediately. */      if (except_name && !strcmp (filename, except_name))	return 0;      if (!(fp = fopen (filename, "r")))	bow_error ("Couldn't open file `%s' for reading.", filename);      if (bow_fp_is_text (fp))	{	  /* The file contains text; snarf the words and put them in	     the WI2DVF map. */	  cdoc.type = model;	  cdoc.class = class;	  cdoc.prior = 1.0f;	  assert (cdoc.class >= 0);	  cdoc.filename = strdup (filename);	  assert (cdoc.filename);	  /* Add the CDOC to CDOCS, and determine the "index" of this             document. */	  di = bow_array_append (barrel->cdocs, &cdoc);	  /* Add all the words in this document. */	  bow_wi2dvf_add_di_text_fp (&(barrel->wi2dvf), di, fp);	  text_file_count++;	}      else	{	  bow_verbosify (bow_progress,			 "\nFile `%s' skipped because not text\n",			 filename);	  binary_file_count++;	}      fclose (fp);      bow_verbosify (bow_progress,		     "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"		     "%6d : %6d", 		     text_file_count, bow_num_words ());      return 1;    }  bow_verbosify (bow_progress,		 "Gathering stats... files : unique-words :: "		 "                 ");  text_file_count = binary_file_count = 0;  bow_map_filenames_from_dir (barrel_index_file, 0, dirname, "");  bow_verbosify (bow_progress, "\n");  if (binary_file_count > text_file_count)    bow_verbosify (bow_quiet,		   "Found mostly binary files, which were ignored.\n");  return text_file_count;}/* Call this on a vector-per-document barrel to set the CDOC->PRIOR's   so that the CDOC->PRIOR's for all documents of the same class sum   to 1. */voidbow_barrel_set_cdoc_priors_to_class_uniform (bow_barrel *barrel){  int *ci2dc;			/* class index 2 document count */  int ci2dc_size = 100;  int ci;  int di;  bow_cdoc *cdoc;  int total_model_docs = 0;  int num_non_zero_ci2dc_entries = 0;    ci2dc = bow_malloc (sizeof (int) * ci2dc_size);  for (ci = 0; ci < ci2dc_size; ci++)    ci2dc[ci] = 0;  for (di = 0; di < barrel->cdocs->length; di++)    {      cdoc = bow_array_entry_at_index (barrel->cdocs, di);      if (cdoc->class >= ci2dc_size)	{	  /* CI2DC must grow to accommodate larger "class index" */	  int old_size = ci2dc_size;	  ci2dc_size *= 2;	  ci2dc = bow_realloc (ci2dc, sizeof (int) * ci2dc_size);	  for ( ; old_size < ci2dc_size; old_size++)	    ci2dc[old_size] = 0;	}      if (cdoc->type == model)	{	  if (ci2dc[cdoc->class] == 0)	    num_non_zero_ci2dc_entries++;	  ci2dc[cdoc->class]++;	  total_model_docs++;	}    }  for (di = 0; di < barrel->cdocs->length; di++)    {      cdoc = bow_array_entry_at_index (barrel->cdocs, di);      if (cdoc->type == model)	{	  cdoc->prior = (1.0 /			 (num_non_zero_ci2dc_entries * ci2dc[cdoc->class]));	  assert (cdoc->prior >= 0);	}    }#if 0  fprintf (stderr, "Infogain post-prior-setting\n");  bow_infogain_per_wi_print (stderr, barrel, num_non_zero_ci2dc_entries, 5);#endif  /* Do some sanity checks. */  {    float prior_total = 0;    for (di = 0; di < barrel->cdocs->length; di++)      {	cdoc = bow_array_entry_at_index (barrel->cdocs, di);	if (cdoc->type == model)	  prior_total += cdoc->prior;      }    assert (prior_total < 1.1 && prior_total > 0.9);  }  free (ci2dc);}/* Modify the BARREL by removing those entries for words that are not   in the int/str mapping MAP. */voidbow_barrel_prune_words_not_in_map (bow_barrel *barrel,				   bow_int4str *map){  int wi;  int max_wi = MIN (barrel->wi2dvf->size, bow_num_words());    assert (max_wi);  /* For each word in MAP. */  for (wi = 0; wi < max_wi; wi++)    {      if (bow_str2int_no_add (map, bow_int2word (wi)) == -1)	{	  /* Word WI is not in MAP.  Remove it from the BARREL. */	  bow_wi2dvf_remove_wi (barrel->wi2dvf, wi);	}    }}/* Modify the BARREL by removing those entries for words that are not   among the NUM_WORDS_TO_KEEP top words, by information gain.  This   function is similar to BOW_WORDS_KEEP_TOP_BY_INFOGAIN(), but this   one doesn't change the word-int mapping. */voidbow_barrel_keep_top_words_by_infogain (int num_words_to_keep, 				       bow_barrel *barrel, int num_classes){  float *wi2ig;  int wi2ig_size;  int wi, i;  struct wiig_list_entry {    float ig;    int wi;  } *wiig_list;  /* For sorting the above entries. */  int compare_wiig_list_entry (const void *e1, const void *e2)    {      if (((struct wiig_list_entry*)e1)->ig >	  ((struct wiig_list_entry*)e2)->ig)	return -1;      else if (((struct wiig_list_entry*)e1)->ig ==	  ((struct wiig_list_entry*)e2)->ig)	return 0;      else return 1;    }  if (num_words_to_keep == 0)    return;  /* Unhide "document vectors" for all WI's */  bow_wi2dvf_unhide_all_wi (barrel->wi2dvf);  /* Get the information gain of all the words. */  wi2ig = bow_infogain_per_wi_new (barrel, num_classes, &wi2ig_size);  /* Make a list of the info gain numbers paired with their WI's,     in prepartion for sorting. */  wiig_list = alloca (sizeof (struct wiig_list_entry) * wi2ig_size);  for (wi = 0; wi < wi2ig_size; wi++)    {      wiig_list[wi].wi = wi;      wiig_list[wi].ig = wi2ig[wi];    }  /* Sort the list */  qsort (wiig_list, wi2ig_size, sizeof (struct wiig_list_entry), 	 compare_wiig_list_entry);#if 1  for (i = 0; i < 5; i++)    fprintf (stderr,	     "%20.10f %s\n", wiig_list[i].ig, bow_int2word (wiig_list[i].wi));#endif  bow_verbosify (bow_progress, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -