Lucene.net中文分词探究

来源:互联网 发布:淘宝上原单正品外贸店 编辑:程序博客网 时间:2024/05/24 15:38

一、中文分词方式:

中文分词几种常用的方式:

A. 单字分词

单字分词,顾名思义,就是按照中文一个字一个字地进行分词。如:我们是中国人,效果:我/////人。

B. 二分法

二分法,就是按两个字进行切分。如:我们是中国人,效果:我们/们是/是中/中国/国人。

C. 词库分词

词库分词,就是按某种算法构造词然后去匹配已建好的词库集合,如果匹配到就切分出来成为词语。通常词库分词被认为是最理想的中文分词算法如:我们是中国人,通成效果为:我们//中国/中国人。

二、Lucene.net中五种中文分词效果探究

Lucene.net中有很多种分词器,不同分词器使用了不同的分词算法,有不同的分词效果,满足不同的需求!在这里主要是看看其中五中分词器用来对中文切词的效果。五中分词器分别为:StandardTokenizerCJKTokenizerChinessTokenizerLowerCaseTokenizerWhitespaceTokenizer;

   下面就来测试一下它们切词的效果:

   测试目标:是否支持中文词语,英文单词,邮件,IP地址,标点符号,数字,数学表达式的切割。
   测试文字:“我们是中国人; 我们 是 人;we are chiness; 172.16.34.172;youpeizun@126.com;#$*;85*34;58 69

测试StandardTokenizer的分词情况如下:

/ / / / / / / / / / we/ are/ chiness/ 172.16.34.172/ youpeizun@126.com/ 85/ 34/ 58/ 69/

测试CJKTokenizer的分词情况如下:

我们/ 们是/ 是中/ 中国/ 国人/ 我们/ / / we/ chiness/ 172/ 16/ 34/ 172/ youpe

izun/ 126/ com/ #/ 85/ 34/ 58/ 69/

测试ChinessTokenizer的分词情况如下:

/ / / / / / / / / / we/ are/ chiness/ 172/ 16/ 34/ 172/ youp

eizun/ 126/ com/ 85/ 34/ 58/ 69/

测试LowerCaseTokenizer的分词情况如下:

我们是中国人/我们///we/are/chiness/youpeizun/com/

测试WhitespaceTokenizer的分词情况如下:

我们是中国人;/我们//;we/are/chiness;/172.16.34.172;youpeizun@126.com;#$*;85*

34;58/69/

测试代码:
一、中文分词方式:


using System;
using System.Collections.Generic;
using System.Text;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using System.IO;
using Lucene.Net.Analysis.Cn;
using Lucene.Net.Analysis.CJK;
//date:11-02-2007
//home page:http://www.cnblogs.com/xuanfeng
//author:peizunyou
namespace TokenizerTest
{
    
class TokenizerTest
    
{
        
static void Main(string[] args)
        
{
            
string testText = "我们是中国人; 我们 是 人;we are chiness; 172.16.34.172;youpeizun@126.com;#$*;85*34;58 69";
            Console.WriteLine(
"测试文字:"+testText);
            Console.WriteLine(
"测试StandardTokenizer的分词情况如下:");
            TestStandardTokenizer(testText);
            Console.WriteLine(
"测试CJKTokenizer的分词情况如下:");
            TestCJKTokenizer(testText);
            Console.WriteLine(
"测试ChinessTokenizer的分词情况如下:");
            TestChinessTokenizer(testText);
            Console.WriteLine(
"测试LowerCaseTokenizer的分词情况如下:");
            TestLowerCaseTokenizer(testText);
            Console.WriteLine(
"测试WhitespaceTokenizer的分词情况如下:");
            TestWhitespaceTokenizer(testText);
            Console.Read();
        }

        
static  void TestStandardTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);

            StandardTokenizer st 
= new StandardTokenizer(tr);
         
            
while (st.Next() != null)
            
{

                Console.Write(st.token.ToString()
+"");
            }

            Console.WriteLine();
        }

        
static void TestCJKTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            
int end = 0;
            CJKAnalyzer cjkA 
= new CJKAnalyzer();
            TokenStream ts 
= cjkA.TokenStream(tr);
            
while(end<text.Length)
            
{
                Lucene.Net.Analysis.Token t 
= ts.Next();
                end 
= t.EndOffset();
                Console.Write(t.TermText()
+"");
            }

            Console.WriteLine();
        }

        
static void TestChinessTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            ChineseTokenizer ct 
= new ChineseTokenizer(tr);
            
int end = 0;
            Lucene.Net.Analysis.Token t;
            
while(end<text.Length)
            
{
                t 
= ct.Next();
                end 
= t.EndOffset();
                Console.Write(t.TermText()
+"");
            }

            Console.WriteLine();
        
        }

        
        
static void TestLowerCaseTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            SimpleAnalyzer sA 
= new SimpleAnalyzer();
            
//SimpleAnalyzer使用了LowerCaseTokenizer分词器
            TokenStream ts = sA.TokenStream(tr);
            Lucene.Net.Analysis.Token t;
            
while((t=ts.Next())!=null)
            
{
                Console.Write(t.TermText()
+"/");
            }

            Console.WriteLine();
        }

        
static void TestWhitespaceTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
   
            WhitespaceAnalyzer sA 
= new WhitespaceAnalyzer();
            TokenStream ts 
= sA.TokenStream(tr);
            Lucene.Net.Analysis.Token t;
            
while ((t = ts.Next()) != null)
            
{
                Console.Write(t.TermText() 
+ "/");
            }

            Console.WriteLine();
        }

    }

}

 

中文分词几种常用的方式:

A. 单字分词

单字分词,顾名思义,就是按照中文一个字一个字地进行分词。如:我们是中国人,效果:我/////人。

B. 二分法

二分法,就是按两个字进行切分。如:我们是中国人,效果:我们/们是/是中/中国/国人。

C. 词库分词

词库分词,就是按某种算法构造词然后去匹配已建好的词库集合,如果匹配到就切分出来成为词语。通常词库分词被认为是最理想的中文分词算法如:我们是中国人,通成效果为:我们//中国/中国人。

二、Lucene.net中五种中文分词效果探究

Lucene.net中有很多种分词器,不同分词器使用了不同的分词算法,有不同的分词效果,满足不同的需求!在这里主要是看看其中五中分词器用来对中文切词的效果。五中分词器分别为:StandardTokenizerCJKTokenizerChinessTokenizerLowerCaseTokenizerWhitespaceTokenizer;

   下面就来测试一下它们切词的效果:

   测试目标:是否支持中文词语,英文单词,邮件,IP地址,标点符号,数字,数学表达式的切割。
   测试文字:“我们是中国人; 我们 是 人;we are chiness; 172.16.34.172;youpeizun@126.com;#$*;85*34;58 69

测试StandardTokenizer的分词情况如下:

/ / / / / / / / / / we/ are/ chiness/ 172.16.34.172/ youpeizun@126.com/ 85/ 34/ 58/ 69/

测试CJKTokenizer的分词情况如下:

我们/ 们是/ 是中/ 中国/ 国人/ 我们/ / / we/ chiness/ 172/ 16/ 34/ 172/ youpe

izun/ 126/ com/ #/ 85/ 34/ 58/ 69/

测试ChinessTokenizer的分词情况如下:

/ / / / / / / / / / we/ are/ chiness/ 172/ 16/ 34/ 172/ youp

eizun/ 126/ com/ 85/ 34/ 58/ 69/

测试LowerCaseTokenizer的分词情况如下:

我们是中国人/我们///we/are/chiness/youpeizun/com/

测试WhitespaceTokenizer的分词情况如下:

我们是中国人;/我们//;we/are/chiness;/172.16.34.172;youpeizun@126.com;#$*;85*

34;58/69/

测试代码:
测试代代码下载


using System;
using System.Collections.Generic;
using System.Text;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using System.IO;
using Lucene.Net.Analysis.Cn;
using Lucene.Net.Analysis.CJK;
//date:11-02-2007
//home page:http://www.cnblogs.com/xuanfeng
//author:peizunyou
namespace TokenizerTest
{
    
class TokenizerTest
    
{
        
static void Main(string[] args)
        
{
            
string testText = "我们是中国人; 我们 是 人;we are chiness; 172.16.34.172;youpeizun@126.com;#$*;85*34;58 69";
            Console.WriteLine(
"测试文字:"+testText);
            Console.WriteLine(
"测试StandardTokenizer的分词情况如下:");
            TestStandardTokenizer(testText);
            Console.WriteLine(
"测试CJKTokenizer的分词情况如下:");
            TestCJKTokenizer(testText);
            Console.WriteLine(
"测试ChinessTokenizer的分词情况如下:");
            TestChinessTokenizer(testText);
            Console.WriteLine(
"测试LowerCaseTokenizer的分词情况如下:");
            TestLowerCaseTokenizer(testText);
            Console.WriteLine(
"测试WhitespaceTokenizer的分词情况如下:");
            TestWhitespaceTokenizer(testText);
            Console.Read();
        }

        
static  void TestStandardTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);

            StandardTokenizer st 
= new StandardTokenizer(tr);
         
            
while (st.Next() != null)
            
{

                Console.Write(st.token.ToString()
+"");
            }

            Console.WriteLine();
        }

        
static void TestCJKTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            
int end = 0;
            CJKAnalyzer cjkA 
= new CJKAnalyzer();
            TokenStream ts 
= cjkA.TokenStream(tr);
            
while(end<text.Length)
            
{
                Lucene.Net.Analysis.Token t 
= ts.Next();
                end 
= t.EndOffset();
                Console.Write(t.TermText()
+"");
            }

            Console.WriteLine();
        }

        
static void TestChinessTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            ChineseTokenizer ct 
= new ChineseTokenizer(tr);
            
int end = 0;
            Lucene.Net.Analysis.Token t;
            
while(end<text.Length)
            
{
                t 
= ct.Next();
                end 
= t.EndOffset();
                Console.Write(t.TermText()
+"");
            }

            Console.WriteLine();
        
        }

        
        
static void TestLowerCaseTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
            SimpleAnalyzer sA 
= new SimpleAnalyzer();
            
//SimpleAnalyzer使用了LowerCaseTokenizer分词器
            TokenStream ts = sA.TokenStream(tr);
            Lucene.Net.Analysis.Token t;
            
while((t=ts.Next())!=null)
            
{
                Console.Write(t.TermText()
+"/");
            }

            Console.WriteLine();
        }

        
static void TestWhitespaceTokenizer(string text)
        
{
            TextReader tr 
= new StringReader(text);
   
            WhitespaceAnalyzer sA 
= new WhitespaceAnalyzer();
            TokenStream ts 
= sA.TokenStream(tr);
            Lucene.Net.Analysis.Token t;
            
while ((t = ts.Next()) != null)
            
{
                Console.Write(t.TermText() 
+ "/");
            }

            Console.WriteLine();
        }

    }

}

 

三、            五中分词器代码设计探究

       从下面分词器代码设计中的静态结构图可以清晰的看出其继承关系。无论是哪个分词器,其分词最终实现的算法都是在Next()方法,想深入了解,请看其相关源码。

Feedback

三、            五中分词器代码设计探究

       从下面分词器代码设计中的静态结构图可以清晰的看出其继承关系。无论是哪个分词器,其分词最终实现的算法都是在Next()方法,想深入了解,请看其相关源码。

Feedback