各个部分代码详解
inition(docs)
def inition ( docs) :
D = len ( docs)
avgdl = sum ( [ len ( doc) + 0.0 for doc in docs] ) / D
for doc in docs:
tmp = { }
for word in doc:
tmp[ word] = tmp. get( word, 0 ) + 1
f. append( tmp)
for k in tmp. keys( ) :
tf[ k] = tf. get( k, 0 ) + 1
for k, v in tf. items( ) :
idf[ k] = math. log( D - v + 0.5 ) - math. log( v + 0.5 )
return D, avgdl
基本的功能:遍历文章库中的所有的文章,以字典的形式统计文章中所有词语的出现次数 dict.get(k,0):在字典dict中,查找key为k的对应的value,如果没有将之置为0。
get_sentences()
def get_sentences ( doc) :
line_break = re. compile ( '[\r\n]' )
delimiter = re. compile ( '[,。?!;]' )
sentences = [ ]
for line in line_break. split( doc) :
line = line. strip( )
if not line:
continue
for sent in delimiter. split( line) :
sent = sent. strip( )
if not sent:
continue
sentences. append( sent)
return sentences
基本功能描述:获取一片文章中所有的句子 line_break = re.compile(’[\r\n]’),生成识别句子的正则识别对象 delimiter = re.compile(’[,。?!;]’):生成将完整的句子按照标点符号进行分割的正则识别器
先将完整的文章,分割成一行一行的句子,然后再将一个一行句子按照标点分成一个一个的小分句。
filter_stop()
stop = set ( )
fr = codecs. open ( 'stopwords.txt' , 'r' , 'utf-8' )
for word in fr:
stop. add( word. strip( ) )
fr. close( )
re_zh = re. compile ( '([\u4E00-\u9FA5]+)' )
def filter_stop ( words) :
return list ( filter ( lambda x: x not in stop, words) )
filter(函数,容器):遍历容器中的每一个元素,将符合函数条件的生成一个新的列表 stop:是停止词构成的集合 words:是输入的词构成的列表 整体函数功能:过滤掉words单词列表中的所有停止词 strip():去除所有为空的字符,比如果’\r\n’等等
字符串.strip(‘字符’):从头到尾遍历所有的字符串,删除所有与字符串相同字符,并将字符串返回 默认为空,表示去除其中的所有的空字符
re.compile(’([\u4E00-\u9FA5]+)’):创造能匹配所有中文字符的正则匹配对象
可执行的完全的代码
import math
import jieba
import os
import re
import codecs
text = '''
自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。
它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。
自然语言处理是一门融语言学、计算机科学、数学于一体的科学。
因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,
所以它与语言学的研究有着密切的联系,但又有重要的区别。
自然语言处理并不是一般地研究自然语言,
而在于研制能有效地实现自然语言通信的计算机系统,
特别是其中的软件系统。因而它是计算机科学的一部分。
'''
f = [ ]
tf = { }
idf = { }
k1 = 1.5
b = 0.75
avgdl = 0
document = list ( )
D = 0
def inition ( docs) :
D = len ( docs)
avgdl = sum ( [ len ( doc) + 0.0 for doc in docs] ) / D
for doc in docs:
tmp = { }
for word in doc:
tmp[ word] = tmp. get( word, 0 ) + 1
f. append( tmp)
for k in tmp. keys( ) :
tf[ k] = tf. get( k, 0 ) + 1
for k, v in tf. items( ) :
idf[ k] = math. log( D - v + 0.5 ) - math. log( v + 0.5 )
return D, avgdl
def sim ( doc, index) :
score = 0.0
for word in doc:
if word not in f[ index] :
continue
d = len ( document[ index] )
score += ( idf[ word] * f[ index] [ word] * ( k1 + 1 ) / ( f[ index] [ word] + k1 * ( 1 - b + b * d / avgdl) ) )
return score
def simall ( doc) :
scores = [ ]
for index in range ( D) :
score = sim( doc, index)
scores. append( score)
return scores
def filter_stop ( words) :
stop = set ( )
fr = codecs. open ( 'stopwords.txt' , 'r' , 'utf-8' )
for word in fr:
stop. add( word. strip( ) )
fr. close( )
re_zh = re. compile ( '([\u4E00-\u9FA5]+)' )
return list ( filter ( lambda x: x not in stop, words) )
def get_sentences ( doc) :
line_break = re. compile ( '[\r\n]' )
delimiter = re. compile ( '[,。?!;]' )
sentences = [ ]
for line in line_break. split( doc) :
line = line. strip( )
if not line:
continue
for sent in delimiter. split( line) :
sent = sent. strip( )
if not sent:
continue
sentences. append( sent)
return sentences
sents = get_sentences( text)
doc = [ ]
for sent in sents:
words = list ( jieba. cut( sent) )
words = filter_stop( words)
doc. append( words)
print ( doc)
document = doc
D, avgdl = inition( doc)
print ( tf)
print ( f)
print ( idf)
print ( simall( [ '自然语言' , '计算机科学' , '领域' , '人工智能' , '领域' ] ) )
分析与总结
这个方法是有一点问题的,已经人工地将句子处理为一行一个,在实际中并不是这样,如果一个句子比较长,横跨了两行,那就不好处理,会拆开一些特殊的关键字,但是可以作为一个初步理解BM25方法的简单的程序。