ICTCLAS代碼學習筆記之ContextStat類

ContextStat.h和ContextStat.cpp是上下文無關類CContextStat的相關聲明和實現。該類的相關操作只在Cspan類中調用。
該類中使用一個結構體tagContext,具體如下:
struct tagContext{
int nKey;//The key word
int **aContextArray;//The context array
int *aTagFreq;//The total number a tag appears
int nTotalFreq;//The total number of all the tags
struct tagContext *next;//The chain pointer to next Context
};
這個結構體的具體含義待補。

CcontextStat類的成員

2006-9-8的學習筆記
現在回到不能迴避的CContextStat類上。這個類的具體作用暫時沒看清楚,從操作的步驟來一點一點寫吧,呵呵。
構造函數和析構函數就是初使化一些成員變量及釋放相應的空間,並不真正的讀入內容。Load函數用於讀入上下文相關內容。相應文件的格式如下,第一個int型大小的數據爲表的長度,讀入到m_nTableLen中,然後爲m_pSymbolTable分配大小爲m_nTableLen的int型空間,並讀入相應m_nTableLen個int型數據到m_pSymbolTable中。然後讀上下文無關m_pContext鏈表中的內容。第一個int型數據爲鏈表結點中的關鍵字pCur->nKey,第二個int型數據爲結點的頻率值pCur->nTotalFreq,接下來的m_nTableLen個int型數據爲相應的每個標記類型的頻率值,分別讀入到pCur->aTagFreq中。接下來的m_nTableLen×m_nTableLen個int型數據是aContextArray的值,其中aContextArray是一個大小爲m_nTableLen的int型指針數組,每個m_nTableLen[i]指向一個大小爲m_nTableLen的int型數組。上下文無關內容m_pContext每個結點都通過next指針串起來直到文件結束。Save函數就是load的逆過程,依上文所述之格式寫入文件即可,這裏不再詳述,唯一注意的就是新添了一個以文本格式記錄了文件的內容以供查看和參考。
對於該類的修改性函數還有Add,即添加一個新的結點,傳入的參數分別是該結點的關鍵字nKey,前一個符號的id,當前要插入的符號的id以及相應的頻率值。先查找是否已存在相同nKey的結點,如果沒有找到則新建一個插入到相應的位置,注意新建這個結點的所有頻率值都被置爲0,只有關鍵字爲nKey。無論是否找到nKey結點,根據傳入的符號nPrevSymbol和nCurSymbol分別在符號表中查找相應的索引值。如果沒有找到則修改其符號(爲nPrevSymbol-nPrevSymbol%256)重新查找一下。如果都找到了那麼更新相應的頻率值及總頻率值。
SetTableLen函數顧名思義就是設置符號表的大小,即修改m_nTableLen的值,同時會發生變化的還有m_pSymbolTable所指空間等,但是這個函數中沒有做原有空間的釋放工作直接就賦空了不太合理可能造成內存泄漏,不過這個函數在目前的代碼中沒有用到,暫時未構造潛在的危害。
SetSymbol也有類似SetTableLen的問題,直接進行了內存拷貝memcpy,而沒有考空m_pSymbolTable是否有足夠的空間,傳入的參數是否合法。
GetItem用於查找給定關鍵字nKey的上下文無關結點,返回其指針。如果找到了則返回true並將其指針記錄在pItemRet中,如果沒有找到則返回其前一個結點的指針並返回false。注意如果鏈表爲空則前一個結點的指針爲NULL。
GetFrequency就是查找給定關鍵字給定符號的頻率值,通過查找m_pContext所帶的鏈表找到相應的關鍵字所在的結點pFound,通過查找m_pSymbolTable找到相應的符號的索引nIndex,然後返回pFound->aTagFreq[nIndex]。如果沒有找到則返回0。
GetContextPossibility函數則是獲得上下文無關文法的相應概率值。基本的策略是從符號表中讀取當前符號和前一個符號的索引值,從上下文無關文法鏈表中讀入相應關鍵詞所在的結點位置,如果沒有找到相應的結點,或者沒有找到上述兩個符號,又或者結點對應的前一個符號的詞性標註概率值爲0,又或者結點對應的這兩個符號的上下文無關概率值爲0,則返回一個很小的概率值避免數據稀疏。否則,返回按經驗公式計算得到的相應概率值,計算公式如下:
0.9*nPrevCurConFreq/nPrevFreq+0.1*nPrevFreq/pCur->nTotalFreq;nPrevCurConFreq=pCur->aContextArray[nPrevIndex][nCurIndex];nPrevFreq=pCur->aTagFreq[nPrevIndex];其中
注意上述公式中計算時要將整型數據強制轉換爲double型數據,否則除法的結果會有問題。另外0.9和0.1都是經驗值。
CContextStat類的總結。
至此,CContextStat類的函數就寫完了。總的來說,這個類提供關於上下文無關文法的概率計算操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章