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,滿足條件。
三、代碼實現
#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();
}
其中,此處單詞集合我是用文本的形式存儲的,每一行存儲一個單詞。