ContextStat.cpp
上传用户:sanxfzhen
上传日期:2014-12-28
资源大小:2324k
文件大小:9k
源码类别:

多国语言处理

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. //ICTCLAS简介:计算所汉语词法分析系统ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System),
  3. //             功能有:中文分词;词性标注;未登录词识别。
  4. //             分词正确率高达97.58%(973专家评测结果),
  5. //             未登录词识别召回率均高于90%,其中中国人名的识别召回率接近98%;
  6. //             处理速度为31.5Kbytes/s。
  7. //著作权:  Copyright?2002-2005中科院计算所 职务著作权人:张华平 刘群
  8. //遵循协议:自然语言处理开放资源许可证1.0
  9. //Email: zhanghp@software.ict.ac.cn
  10. //Homepage:www.nlp.org.cn;mtgroup.ict.ac.cn
  11. /****************************************************************************
  12.  *
  13.  * Copyright (c) 2000, 2001 
  14.  *     Machine Group
  15.  *     Software Research Lab.
  16.  *     Institute of Computing Tech.
  17.  *     Chinese Academy of Sciences
  18.  *     All rights reserved.
  19.  *
  20.  * This file is the confidential and proprietary property of 
  21.  * Institute of Computing Tech. and the posession or use of this file requires 
  22.  * a written license from the author.
  23.  * Filename: ContextStat.cpp
  24.  * Abstract:
  25.  *           implementation of the CContextStat class.
  26.  * Author:   Kevin Zhang 
  27.  *          (zhanghp@software.ict.ac.cn)
  28.  * Date:     2002-1-24
  29.  *
  30.  * Notes:
  31.  *                
  32.  ****************************************************************************/
  33. #include "stdafx.h"
  34. #include "ContextStat.h"
  35. #include "Utility.h"
  36. #include <memory.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. //////////////////////////////////////////////////////////////////////
  40. // Construction/Destruction
  41. //////////////////////////////////////////////////////////////////////
  42. CContextStat::CContextStat()
  43. {
  44. m_pSymbolTable=0;//new buffer for symbol
  45. m_pContext=0;//init with empty
  46. }
  47. CContextStat::~CContextStat()
  48. {
  49. delete [] m_pSymbolTable;
  50. PMYCONTEXT pCur=m_pContext,pTemp;
  51. while(pCur!=NULL)
  52. {//delete the context array
  53. pTemp=pCur->next;
  54. for(int i=0;i<m_nTableLen;i++)
  55.    delete [] pCur->aContextArray[i];
  56. delete [] pCur->aContextArray;
  57. delete [] pCur->aTagFreq;
  58. delete pCur;
  59. pCur=pTemp;
  60. }
  61. }
  62. bool CContextStat::SetSymbol(int *nSymbol)
  63. {
  64. memcpy(m_pSymbolTable,nSymbol,sizeof(int)*m_nTableLen);
  65. return true;
  66. }
  67. bool CContextStat::Add(int nKey, int nPrevSymbol, int nCurSymbol, int nFrequency)
  68. {//Add the context symbol to the array
  69. PMYCONTEXT pRetItem,pNew;
  70. int nPrevIndex,nCurIndex;
  71.     if(!GetItem(nKey,&pRetItem))//Not get it
  72. {
  73. pNew=new MYCONTEXT;
  74. pNew->nKey=nKey;
  75. pNew->nTotalFreq=0;
  76. pNew->next=NULL;
  77. pNew->aContextArray=new int*[m_nTableLen];
  78. pNew->aTagFreq=new int[m_nTableLen];
  79. memset(pNew->aTagFreq,0,sizeof(int)*m_nTableLen);
  80. for(int i=0;i<m_nTableLen;i++)
  81. {//new buffer for every dimension
  82. pNew->aContextArray[i]=new int[m_nTableLen];
  83. memset(pNew->aContextArray[i],0,sizeof(int)*m_nTableLen);//Init the frequency
  84. }
  85. if(pRetItem==NULL)//Empty, the new item is head
  86. m_pContext=pNew;
  87. else//Link the new item between pRetItem and its next item
  88. {
  89. pNew->next=pRetItem->next;
  90. pRetItem->next=pNew;
  91. }
  92. pRetItem=pNew;
  93. }
  94. nPrevIndex=BinarySearch(nPrevSymbol,m_pSymbolTable,m_nTableLen);
  95. if(nPrevSymbol>256&&nPrevIndex==-1)//Not find, just for 'nx' and other uncommon POS
  96. nPrevIndex=BinarySearch(nPrevSymbol-nPrevSymbol%256,m_pSymbolTable,m_nTableLen);
  97. nCurIndex=BinarySearch(nCurSymbol,m_pSymbolTable,m_nTableLen);
  98. if(nCurSymbol>256&&nCurIndex==-1)//Not find, just for 'nx' and other uncommon POS
  99. nCurIndex=BinarySearch(nCurSymbol-nCurSymbol%256,m_pSymbolTable,m_nTableLen);
  100.     if(nPrevIndex==-1||nCurIndex==-1)//error finding the symbol
  101. return false;
  102. pRetItem->aContextArray[nPrevIndex][nCurIndex]+=nFrequency;//Add the frequency
  103. pRetItem->aTagFreq[nPrevIndex]+=nFrequency;
  104. pRetItem->nTotalFreq+=nFrequency;
  105. return true;
  106. }
  107. bool CContextStat::Save(char *sFilename)
  108. {
  109. FILE *fp,*fp1;
  110. PMYCONTEXT pCur;
  111. char sFileShow[100];
  112. int i;
  113. if((fp=fopen(sFilename,"wb"))==NULL)
  114. {
  115. return false;
  116. }
  117. strcpy(sFileShow,sFilename);
  118. strcat(sFileShow,".shw");
  119. if((fp1=fopen(sFileShow,"wb"))==NULL)
  120. {
  121. return false;
  122. }
  123.     fwrite(&m_nTableLen,sizeof(m_nTableLen),1,fp);//write the table length
  124.     fwrite(m_pSymbolTable,sizeof(int),m_nTableLen,fp);//write the symbol table
  125.     fprintf(fp1,"Table Len=%dnSymbol:n",m_nTableLen);
  126.     for(i=0;i<m_nTableLen;i++)
  127.  fprintf(fp1,"%d ",m_pSymbolTable[i]);
  128. fprintf(fp1,"n");
  129. pCur=m_pContext;
  130. while(pCur!=NULL)
  131. {
  132. fwrite(&pCur->nKey,sizeof(int),1,fp);
  133. fwrite(&pCur->nTotalFreq,sizeof(int),1,fp);
  134. fprintf(fp1,"nKey=%d,Total frequency=%d:n",pCur->nKey,pCur->nTotalFreq);
  135. fwrite(pCur->aTagFreq,sizeof(int),m_nTableLen,fp);//the every POS frequency
  136.         for(i=0;i<m_nTableLen;i++)
  137. {
  138. fwrite(pCur->aContextArray[i],sizeof(int),m_nTableLen,fp);
  139. fprintf(fp1,"No.%2d=%3d: ",i,m_pSymbolTable[i]);
  140.             for(int j=0;j<m_nTableLen;j++)
  141. fprintf(fp1,"%5d ",pCur->aContextArray[i][j]);
  142.             fprintf(fp1,"total=%d:n",pCur->aTagFreq[i]);
  143. }
  144. pCur=pCur->next;
  145. }
  146. fclose(fp);
  147. fclose(fp1);
  148. return true;
  149. }
  150. bool CContextStat::Load(char *sFilename)
  151. {
  152. FILE *fp;
  153. if((fp=fopen(sFilename,"rb"))==NULL)
  154. {
  155. return false;
  156. }
  157. PMYCONTEXT pCur=m_pContext,pTemp,pPre=NULL;
  158. while(pCur!=NULL)
  159. {//delete the context array
  160. pTemp=pCur->next;
  161. for(int i=0;i<m_nTableLen;i++)
  162.    delete [] pCur->aContextArray[i];
  163. delete [] pCur->aContextArray;
  164. delete [] pCur->aTagFreq;
  165. delete pCur;
  166. pCur=pTemp;
  167. }
  168. fread(&m_nTableLen,sizeof(m_nTableLen),1,fp);//write the table length
  169. if(m_pSymbolTable!=NULL)
  170. delete [] m_pSymbolTable;
  171. m_pSymbolTable=new int[m_nTableLen];//new buffer for symbol
  172. fread(m_pSymbolTable,sizeof(int),m_nTableLen,fp);//write the symbol table
  173.     //free exists items
  174.     while(!feof(fp))
  175. {//Read the context 
  176. pCur=new MYCONTEXT;
  177. pCur->next=NULL;
  178. if(fread(&pCur->nKey,sizeof(int),1,fp)<1)//Read error
  179. {
  180. delete pCur;
  181. break;
  182. }
  183.         fread(&pCur->nTotalFreq,sizeof(int),1,fp);
  184. pCur->aTagFreq=new int [m_nTableLen];
  185. fread(pCur->aTagFreq,sizeof(int),m_nTableLen,fp);//the every POS frequency
  186. pCur->aContextArray=new int *[m_nTableLen];
  187.         for(int i=0;i<m_nTableLen;i++)
  188. {
  189.     pCur->aContextArray[i]=new int[m_nTableLen];
  190. fread(pCur->aContextArray[i],sizeof(int),m_nTableLen,fp);
  191. }
  192. if(pPre==NULL)
  193. m_pContext=pCur;
  194. else
  195. pPre->next=pCur;
  196. pPre=pCur;
  197. }
  198. fclose(fp);
  199. return true;
  200. }
  201. double CContextStat::GetContextPossibility(int nKey, int nPrev, int nCur)
  202. {
  203. PMYCONTEXT pCur;
  204. int nCurIndex=BinarySearch(nCur,m_pSymbolTable,m_nTableLen);
  205. int nPrevIndex=BinarySearch(nPrev,m_pSymbolTable,m_nTableLen);
  206. if(!GetItem(nKey,&pCur)||nCurIndex==-1||nPrevIndex==-1||pCur->aTagFreq[nPrevIndex]==0||pCur->aContextArray[nPrevIndex][nCurIndex]==0)
  207. return 0.000001;//return a lower value, not 0 to prevent data sparse
  208. int nPrevCurConFreq=pCur->aContextArray[nPrevIndex][nCurIndex];
  209. int nPrevFreq=pCur->aTagFreq[nPrevIndex];
  210. return 0.9*(double)nPrevCurConFreq/(double)nPrevFreq+0.1*(double)nPrevFreq/(double)pCur->nTotalFreq;
  211. //0.9 and 0.1 is a value based experience
  212. }
  213. int CContextStat::GetFrequency(int nKey, int nSymbol)
  214. {//Get the frequency which nSymbol appears
  215. PMYCONTEXT pFound;
  216. int nIndex,nFrequency=0;
  217. if(!GetItem(nKey,&pFound))//Not found such a item
  218. return 0;
  219. nIndex=BinarySearch(nSymbol,m_pSymbolTable,m_nTableLen);
  220.     if(nIndex==-1)//error finding the symbol
  221. return 0;
  222. nFrequency=pFound->aTagFreq[nIndex];//Add the frequency
  223. return nFrequency;
  224. }
  225. bool CContextStat::GetItem(int nKey,PMYCONTEXT *pItemRet)
  226. {//Get the item according the nKey
  227. PMYCONTEXT pCur=m_pContext,pPrev=NULL;
  228. if(nKey==0&&m_pContext)
  229. {
  230. *pItemRet=m_pContext;
  231. return true;
  232. }
  233. while(pCur!=NULL&&pCur->nKey<nKey)
  234. {//delete the context array
  235. pPrev=pCur;
  236. pCur=pCur->next;
  237. }
  238.     if(pCur!=NULL&&pCur->nKey==nKey)
  239. {//find it and return the current item
  240. *pItemRet=pCur;
  241. return true;
  242. }
  243. *pItemRet=pPrev;
  244. return false;
  245. }
  246. bool CContextStat::SetTableLen(int nTableLen)
  247. {
  248. m_nTableLen=nTableLen;//Set the table len
  249. m_pSymbolTable=new int[nTableLen];//new buffer for symbol
  250. m_pContext=0;//init with empty
  251. return true;
  252. }
  253. void CContextStat::ReleaseContextStat()
  254. {
  255. PMYCONTEXT pCur=m_pContext,pTemp,pPre=NULL;
  256. while(pCur!=NULL)
  257. {//delete the context array
  258. pTemp=pCur->next;
  259. for(int i=0;i<m_nTableLen;i++)
  260. {
  261. if(pCur->aContextArray[i]!=NULL)
  262. {
  263. delete [] pCur->aContextArray[i];
  264. pCur->aContextArray[i]=NULL;
  265. }
  266. }
  267. if(pCur->aContextArray!=NULL)
  268. {
  269. delete [] pCur->aContextArray;
  270. pCur->aContextArray=NULL;
  271. }
  272. if(pCur->aTagFreq!=NULL)
  273. {
  274. delete [] pCur->aTagFreq;
  275. pCur->aTagFreq=NULL;
  276. }
  277. delete pCur;
  278. pCur=pTemp;
  279. }
  280. m_pContext=NULL;
  281. if(m_pSymbolTable!=NULL)
  282. {
  283. delete [] m_pSymbolTable;
  284. m_pSymbolTable=NULL;
  285. }
  286. }