简单实现中文分词中的常用字过滤

        首先感谢 兽族的荣耀朋友的文章 简单编写的中文分词程序 ,我开始接触搜索引擎这个领域以及写这篇随笔都离不开他的精彩文章的帮助:)
       下面切入正题。 

    名词:分析器(Analyzer),词单元(Tokens),高亮(Highlight)。
    实现背景:
        当在搜索引擎文本框中写入源词时,分析器(Analyzer)会将源词拆分成多组词单元(Tokens)。之后搜索引擎会在词库中搜索词单元,进行匹配,记录权重等其它操作。
        当有些源词中包括常用词时,往往会给接下来的工作带来麻烦,比如下面的情况:
         
      当搜索 [丰富的教学经验]时,分词器将源词拆分为[丰富]-[的]-[教学]-[经验],由于高亮(Highlight)会将每个词单元在页面中套色,于是过滤掉这些常用词就会显得十分必要 。  
      实现思路:
            可以为词汇创建词库,当然也可以为需要过滤的常用词创建过滤词库,每次源词分词之前将源词进行过滤,再把过滤后的源词进行拆分。
      实现环节:
            知识1:缓存配置文件
            许多朋友都有 J2EE  开发经验,对经典框架 Struts 都能熟练运用。大家一定都注意到每次修改struts-config.xml时,都要重新启动服务器后才能生效。为什么要这样设计呢?每次修改配置文件都能立即奏效不是更好吗?
            对于小型应用来讲,每次从配置文件中读取信息,的确是不错的选择,但是当配置文件比较大时,比如用于过滤常用词的过滤词库,每次搜索时都重新加载词库并且从中进行搜索,显然耗费很长的时间。于是当应用程序启动时一次性加载过滤词库成为了不错的解决方案。
            将配置文件缓存的方法非常简单,只要把接收过滤词的对象(可以是string[],也可以是IList<string>或者其它的什么你随意:))声明为 static 就可以了,以下是实现代码: 
            
None.gif public   class  FilterDemo
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
private static string _filterPath;
InBlock.gif    
private static IList<string> filter = null;
InBlock.gif
InBlock.gif    
static FilterDemo()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _filterPath 
= HttpContext.Current.Request.MapPath("~/App_Data/File/" + "Filter.txt");         
InBlock.gif        
// 从指定文件获得 待过滤字符串列表
InBlock.gif
        InitFilterFile(_filterPath);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

            filter 被声明为静态变量用于接收过滤词库中的词。当静态方法 InitFilterFile() 方法执行之后,filter被初始化。至此过滤词库加载成功,之后要获得过滤词列表,只会从缓存,也就是 filter 变量中获得,而不是从过滤词库中加载,从而提高了响应速度。当然如果要在词库中添加或者修改内容,必须重新启动服务才能生效,事物有一利必有一弊,鱼和熊掌的道理吧:)
            知识2:从文本文件中读取信息
                  从文本文件读取信息,随手查一下 msdn 或者随便 google 一下可以找到一堆解决方案,所以具体实现过程也不用过多陈述。在这里我想强调一下文件字符集格式问题,因为我在写代码的时候的确遇到了问题。 先看一下下面的两种写法吧:
方法1:
None.gif using  (StreamReader sr  =  File.OpenText(path)) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    filter 
= new List<string>();
InBlock.gif    
string s = "";
InBlock.gif    
while ((s = sr.ReadLine()) != null
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        filter.Add(s);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
方法2:
None.gif using  (StreamReader sr  =   new  StreamReader(path, Encoding.Default))
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    filter 
= new List<string>();
InBlock.gif    
string s = "";
InBlock.gif    
while ((s = sr.ReadLine()) != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        filter.Add(s);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
      第一种方法用 File 类的静态方法 OpenText(string path)  将内容读入 StreamReader 对象中,第二种方法直接用 StreamReader 的构造器实现了同样的功能,除此之外还指定了操作流的字符集。
      功能强大的 Framework 为实现相同的功能提供了多套解决方案,方法的重载中往往为功能的实现提供了更为准确的路线,比如 StreamReader 构造中的 字符集 参数,在我使用上面第一种方法实现功能时,的确就遇到了乱码,而且把可用的词库修改内容另存之后用第一种方法读取,依然乱码,于是我试想是否可以在操作流中指定流的字符集,结果找到了上面的第二种方法,而且奏效。
      想在这里说的感想就是自己想要的方法,Framework 可能已经为你做好了服务,理解了 Framework 的风格,会使功能实现的过程变得更加顺利:)

      最后就是过滤源词的步骤了,非常简单:
ContractedBlock.gif ExpandedBlockStart.gif   // 过滤非法字符,字符串 - private static string WordFilter(string s) #region // 过滤非法字符,字符串 - private static string WordFilter(string s)
ExpandedSubBlockStart.gifContractedSubBlock.gif 
/**//// <summary>
InBlock.gif 
/// 过滤非法字符,字符串
InBlock.gif 
/// </summary>
ExpandedSubBlockEnd.gif 
/// <param name="s">源字符串</param>

InBlock.gif private static string WordFilter(string s)
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif    
foreach (string code in filter)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        s 
= s.Replace(code, "");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return s;
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif 
#endregion

WordFilter(string s) 方法返回的就是过滤后的源词,至此功能实现。
看看效果吧:
200701061148.jpg

存在问题:
         过滤词库中的一些词(或字),会出现在一些词语中,比如[我],  在成语[我见犹怜]中会被过滤,所以这个成语会被拆分成 [见]-[犹]-[怜]。

说在后边:
        搜索引擎技术至今没有一个统一的标准,还没有到某某功能用某某方式解决 普遍比较认同的阶段。大多数的站内搜索都处于摸索,试探阶段(当然,这个阶段给我们带来了无穷的乐趣:)),所以以上的解决方案只是众多解决方案中非常不成熟的一种,但是如果以上的方案能够给您带来一丝的灵感或者引起您对搜索引擎的一点点兴趣,我将感到非常开心:)

附赠: 过滤词库

ContractedBlock.gif ExpandedBlockStart.gif Filter.txt
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif
None.gifthe
None.giffor
None.gifin
None.gifto
None.gifon
None.gif 
None.gif  
None.gif   
None.gif     
None.gifa
None.gifb
None.gifc
None.gifd
None.gife
None.giff
None.gifg
None.gifh
None.gifi
None.gifj
None.gifk
None.gifl
None.gifm
None.gifn
None.gifo
None.gifp
None.gifq
None.gifr
None.gifs
None.gift
None.gifu
None.gifv
None.gifw
None.gifx
None.gify
None.gifz
None.gif
1
None.gif
2
None.gif
3
None.gif
4
None.gif
5
None.gif
6
None.gif
7
None.gif
8
None.gif
9
None.gif
0
None.gifabout
None.gifabove
None.gifafter
None.gifagain
None.gifall
None.gifalso
None.gifam
None.gifan
None.gifand
None.gifany
None.gifare
None.gifas
None.gifat
None.gifback
None.gifbe
None.gifbeen
None.gifbefore
None.gifbehind
None.gifbeing
None.gifbelow
None.gifbut
None.gifby
None.gifcan
None.gifclick
None.gifdo
None.gifdoes
None.gifdone
None.gifeach
None.gifelse
None.gifetc
None.gifever
None.gifevery
None.giffew
None.giffor
None.giffrom
None.gifgenerally
None.gifget
None.gifgo
None.gifgone
None.gifhas
None.gifhave
None.gifhello
None.gifhere
None.gifhow
None.gifif
None.gifin
None.gifinto
None.gifis
None.gifjust
None.gifkeep
None.giflater
None.giflet
None.giflike
None.giflot
None.giflots
None.gifmade
None.gifmake
None.gifmakes
None.gifmany
None.gifmay
None.gifme
None.gifmore
None.gifmost
None.gifmuch
None.gifmust
None.gifmy
None.gifneed
None.gifno
None.gifnot
None.gifnow
None.gifof
None.gifoften
None.gifon
None.gifonly
None.gifor
None.gifother
None.gifothers
None.gifour
None.gifout
None.gifover
None.gifplease
None.gifput
None.gifso
None.gifsome
None.gifsuch
None.gifthan
None.gifthat
None.gifthe
None.giftheir
None.gifthem
None.gifthen
None.gifthere
None.gifthese
None.gifthey
None.gifthis
None.giftry
None.gifto
None.gifup
None.gifus
None.gifvery
None.gifwant
None.gifwas
None.gifwe
None.gifwell
None.gifwhat
None.gifwhen
None.gifwhere
None.gifwhich
None.gifwhy
None.gifwill
None.gifwith
None.gifwithin
None.gifyou
None.gifyour
None.gifyourself
None.gif

转载于:https://www.cnblogs.com/ayuan/archive/2007/01/17/621475.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文分词、词性标注和关键词提取是NLP常用的三个功能,可以通过开源NLP工具包如jieba、THULAC和NLTK等来实现,下面是具体步骤: 1.中文分词:将一段文本切分成一个个单独的词语。jieba是目前比较流行的Python中文分词工具包,使用方法非常简单。首先安装jieba,然后在代码导入jieba模块,在文本输入时调用jieba模块分词函数即可完成中文分词操作。 例如,下面展示了在Python使用jieba对一段文文本进行分词的示例代码: ``` import jieba text = '我喜欢看电影' seg_list = jieba.cut(text, cut_all=False) # cut_all=False表示精确模式 print("分词结果:", "/".join(seg_list)) ``` 输出结果为:“分词结果:我/喜欢/看/电影” 2.词性标注:给分词的每个词语附加上其词性的标记,例如“名词”、“动词”、“形容词”等。THULAC是一个高效准确的文词法分析工具,支持中文分词和词性标注等操作,可以自动识别出文文本的人名、地名、各类数字、日期等,并正确定位他们在句子的位置。使用方法与jieba相似,通过安装THULAC库,并调用相关函数即可完成中文分词和词性标注。 例如,下面展示了在Python使用THULAC对一段文文本进行分词和词性标注的示例代码: ``` import thulac thu1 = thulac.thulac() #默认模式 text = '我喜欢看电影' seg_list = thu1.cut(text, text=True) #进行分词和词性标注 print("分词和词性标注结果:", seg_list) ``` 输出结果为:”分词和词性标注结果:[['我', 'r'], ['喜欢', 'v'], ['看', 'v'], ['电影', 'n']]“ 3.关键词提取:从一段文本提取出最具代表性的关键词,常用于文本摘要、文本分类、信息检索等应用场景。NLTK是Python较为常用的自然语言处理工具包之一,其提供了多种文本预处理功能,其包括关键词提取功能。只需要按照以下步骤,即可使用NLTK实现关键词提取: - 安装NLTK:在Python命令行或终端输入命令“pip install nltk”即可完成安装。 - 导入相关模块:使用以下代码导入nltk和nltk.corpus模块,以及相关的停用词库。 ```python import nltk from nltk.corpus import stopwords from nltk.tokenize import word_tokenize ``` - 加载和处理文本:首先需要载入一段文本,并进行分词处理和词性标注。为了减少干扰项,还需要进行一些过滤操作,例如过滤停用词、标点符号等。这里以一个简单的示例为例: ```python text = '我喜欢看电影,特别喜欢科幻电影。' stop_words = set(stopwords.words('chinese')) # 载入文停用词库 word_tokens = word_tokenize(text) # 将句子进行分词处理 filtered_sentence = [w for w in word_tokens if not w in stop_words] # 过滤停用词 ``` - 提取关键词:使用NLTK提供的Collocations和FreqDist函数,实现对文本关键词的提取。其Collocations可以检查文本的共现频率最高的词对或短语,而FreqDist可以对文本出现的词语进行频率统计,找出出现频率最高的单词和短语。 ```python bigram_measures = nltk.collocations.BigramAssocMeasures() finder = nltk.collocations.BigramCollocationFinder.from_words(filtered_sentence) keywords = finder.nbest(bigram_measures.raw_freq, 3) # 提取出现频率前三的词语 ``` 输出结果为:[(‘喜欢’, ‘科幻’), (‘科幻’, ‘电影’), (‘看’, ‘电影’)] 综上所述,中文分词、词性标注和关键词提取是常见的NLP功能,在Python可以通过开源工具库来实现,具体实现流程见上述示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值