基於k-gram的拼寫校正方法的實現

Xiaohui Huang, [email protected]
China University of Geosciences, Wuhan , 430074
School of Computer. Network Engineering


基於k-gram的拼寫校正方法的實現


一、k-gram拼寫校正方法簡介

k-gram拼寫校正方法是《信息檢索導論》中提到的兩種主要的拼寫校正方法之一(另一種主要的拼寫校正方法爲基於編輯距離的拼寫校正方法),核心思想是通過求Jaccard係數,通過比較Jaccard係數與預先定義的閾值進行相關的比較。

其中,Jaccard係數的計算公式爲:



其中,A、B爲兩個單詞,長度分別爲m和n,那麼單詞A和B的k-gram詞項集合中的詞項數分別爲m+1-k和n+1-k個。

其中,分子AB表示單詞A和B的k-gram詞項集合中相同的詞項個數。分母的A表示單詞A的k-gram詞項集合中的詞項數,B表示單詞B的k-gram詞項集合的詞項數。

算出Jaccard後,與預先定義的閾值做比較,留下Jaccard係數大於閾值的單詞。


二、Jaccard係數計算實例

假設有一詞項集合


查詢關鍵詞爲bord;k取2,閾值爲0.35,那麼查詢關鍵詞bord的2-gram詞項集合爲A={bo,or,rd};(3個)

對於任意一單詞border,其2-gram詞項集合爲B={bo,or,rd,de,er};(5個)

其中集合A和集合B的交集爲{bo,or,rd};(3個)

      那麼單詞border的Jaccard係數爲



0.8>0.35,滿足條件。


三、代碼實現

代碼實現環境爲Visual C++ 6.0,文件名字爲k-gram_Search.cpp
#include<iostream>
#include<string>
#include<fstream>
using namespace std;


//字符數目爲n的詞項k-gram數目爲n+1-k
//預定的閾值爲0.1

#define threshold 0.1//閾值

void k_gram(string words,string kwords,int _k)
{
	string input="";//輸入的字符串
	string search="";//要查詢的字符串
	int k=0;//k-gram中的k值
	int input_k_gram=0;//輸入字符串的k-gram數目
	int search_k_gram=0;//查詢關鍵字的k-gram數目
	int fitness=0;//匹配度
	float Jaccard=0.00;//Jaccard係數

	//初始化相應的值
	//cout<<"請輸入要查詢的字符:";
	//cin>>input;
	input=words;
	//cout<<"請輸入查詢關鍵字:";
	//cin>>search;
	search=kwords;
	//cout<<"請輸入k-gram中的k值:";
	//cin>>k;
	k=_k;
	
	//計算k-gram數目
	input_k_gram=input.size()+1-k;
	search_k_gram=search.size()+1-k;

	cout<<input_k_gram<<"    "<<search_k_gram<<endl;

	for(int i=0;i<search.size()-1;i++)
	{
		string temp=search.substr(i,k);
		string::size_type pos=input.find(temp);
		if(pos<input.size()) fitness++;
	}
	
	cout<<"fitness="<<fitness<<endl;
	
	//計算Jaccard係數
	Jaccard=(float)fitness/(input_k_gram+search_k_gram-fitness);
	cout<<Jaccard<<endl;
	
	if(Jaccard>threshold) cout<<input<<endl;

	cout<<endl;
}

void main()
{
	//初始化部分
	cout<<"請輸入查詢關鍵字:";
	string kwords;
	cin>>kwords;
	cout<<"請輸入k值:";
	int k;
	cin>>k;

	
	string str;
	ifstream out("F:\\大三下課程\\網絡存儲\\課程實習\\words.txt",ios::in);
	while(!out.eof())
	{
		getline(out,str);
		//cout<<str<<endl;
		k_gram(str,kwords,k);
	}
	out.close();
}

其中,此處單詞集合我是用文本的形式存儲的,每一行存儲一個單詞
也可以用單鏈表實現單詞集合的存儲。


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