百科词条比较(3)

3. 中文分词

虽然中文分词工具也很多,但没有一个分词工具能像ICTCLAS那样光芒万丈,而且还是免费的,所以就直接用它了。

我们先看下ICTCLAS犀利的简介 :

  • ICTCLAS在国内973专家组组织的评测中活动获得了第一名,在第一届国际中文处理研究机构SigHan组织的评测中都获得了多项第一名。
  • ICTCLAS 2011分词速500KB/s左右,分词精度98.45%,API不超过100KB,各种词典数据压缩后不到3M。
  • ICTCLAS全部采用C/C++编写,支持Linux、FreeBSD及Windows系列操作系统,支持C/C++/C#/Delphi/Java等主流的开发语言

单击此处,可以获得ICTCLAS更详细的介绍,想膜拜该作者的童靴可以去新浪微博围观@ICTCLAS张华平博士

使用C#的同学可以从网站上下载 ICTCLAS2011_Windows_32_c ,其中有详细介绍C#接口的文档和Demo.

添加好C#的接口之后,就可以用如下函数进行分词:

ICTCLAS clas = ICTCLAS.GetInstance();

List<ResultTerm> terms = clas.Segment(str);

其中str是string类型的待分词文本,返回的结果中ResultTerm的结构如下:

public struct ResultTerm

{

    public string Word;        //字符串

    public int POS;             //词性标志

    public string POSStr;     //词性说明

}

可以看出,分词返回的结果中并没有词频,这个需要我们自己统计。

在之后计算相似度的过程中,发现去除停用词和只保留词频和字数都大于1的词项后得到的结果,与使用全部词项的结果差不多,所以在分词时就只保留了部分有代表性(非停用词且词频和字数都大于1)的词项,并将剩余的词项按词频降序排序。

分词部分的实现代码如下:

class TermFrequence

{

    private string[] stopWords;   //停用词表

    private BaikeEntry baikeEntry;



    private TermFrequence()

    {

    }



    public TermFrequence(BaikeEntry newBaikeEntry)

    {

        baikeEntry = newBaikeEntry;



         GetTermDic();

         RemoveStopWords();

         GetTermList();  //只保留词频大于1且词项字数大于1的词项

       UpdateTermDic();

        GetTermShow();

    }



    private void GetTermDic()

    {

        ICTCLAS clas = ICTCLAS.GetInstance();

        List<ResultTerm> terms = clas.Segment(baikeEntry.text);



        baikeEntry.wordDic.Clear();

        foreach (ResultTerm term in terms)

        {

            if (baikeEntry.wordDic.ContainsKey(term.Word))

                baikeEntry.wordDic[term.Word] += 1;

            else

                baikeEntry.wordDic.Add(term.Word, 1);

        }

    }



    private void RemoveStopWords()

    {

        //获取停用词表

        StreamReader sr = new StreamReader("stopWords.txt", Encoding.UTF8);

        string tmp = sr.ReadToEnd();

        stopWords = Regex.Split(tmp, @"\r\n");



        //去除停用词

        foreach (string str in stopWords)

        {

            if (baikeEntry.wordDic.ContainsKey(str))

                baikeEntry.wordDic.Remove(str);

        }



        //去除其他字符

        Dictionary<string, int> newDic = new Dictionary<string, int>();

        foreach (KeyValuePair<string, int> dic in baikeEntry.wordDic)

        {

            if (Regex.Replace(dic.Key, @"(?is)\s*", "").Length != 0)

                newDic.Add(dic.Key, dic.Value);

        }

        baikeEntry.wordDic = newDic;

    }



    private void GetTermList()

    {

        baikeEntry.wordList.Clear();



        foreach (KeyValuePair<string, int> dic in baikeEntry.wordDic)

        {

            if (dic.Value > 1 && dic.Key.Length > 1)

                baikeEntry.wordList.Add(new WordFreq(dic.Key, dic.Value));

        }

        baikeEntry.wordList.Sort((a, b) => { return b.freq - a.freq; });

    }



    private void UpdateTermDic()

    {

        baikeEntry.wordDic.Clear();

        foreach (WordFreq wf in baikeEntry.wordList)

            baikeEntry.wordDic.Add(wf.name, wf.freq);

    }



    private void GetTermShow()

    {

        foreach (WordFreq wf in baikeEntry.wordList)

            baikeEntry.allWordFreq += string.Format("{0}:{1}\n", wf.name, wf.freq);

    }

}


-------------------------------------------
作者:兔纸张   来源:博客园 ( http://www.cnblogs.com/geiliCode )

你可能感兴趣的:(比较)