设计
给出一篇文章,判断其属于某一个分类
格式如下,{}中表示是一组词
>>> 广告事前
贵公司
{
办证
电话
}
>>> 广告事后
{
网站
代购
}
开发票
构思:
1.单个关键词,实际应用中一个单关键词最多属于一个分类,先做一下倒排
censor_single_keyword={
"贵公司":1,
"开发票":2,
}
配合多关键词查找(比如Aho-Corasick State Machine),很easy
2.
a. 给每一个组分配id
1:{
办证
电话
},
2:{
网站
代购
}
b.
记录 类别id - 分组id
用array
c.
记录 分组id - id的中内容长度
用array
'B' unsigned char int 1
d.
词做倒排
词 <-> 分类id列表
e.
多关键词查找 统计出出现的词的set
f.
新建一个字典
每一个出现词 分类id count+=1
for xx in 这个字典
if count == 分组id 中 id的中内容长度
确认是这个分类(这里只考虑属于一个分类)
------------------------
实现
~/algorithm/censor/lib/multi_pattern_search $ cat keyword2group.py
~/algorithm/censor $ cat lib/multi_pattern_search/keyword2group.py
#coding:utf-8
from array import array
from collections import defaultdict
from multi_pattern_search import MultiPatternSearch
class CensorKeyword(object):
def __init__(self):
pass
def _reload(self):
self.group_name_list = []
self.single_keyword_to_cat_id = {}
self.group_keyword = []
self.group_keyword_to_group_id = {}
self.group_id_to_cat_id = array('I')
self.group_keyword_length = array('B')
self.single_search = MultiPatternSearch()
self.group_search = MultiPatternSearch()
def _init_search(self):
for i in self.single_keyword_to_cat_id.keys():
self.single_search.add_keyword(i)
group_keyword_set = set()
for i in self.group_keyword:
for k in i:
group_keyword_set.add(k)
for i in group_keyword_set:
self.group_search.add_keyword(i)
def _keyword_to_group_id(self):
#词做倒排
group_keyword_to_group_id = self.group_keyword_to_group_id
for pos, group_keyword_list in enumerate(self.group_keyword):
for keyword in group_keyword_list:
if keyword not in group_keyword_to_group_id:
group_keyword_to_group_id[keyword] = array('I')
group_keyword_to_group_id[keyword].append(pos)
def load_txt(self, txt):
self._reload()
SINGE_KEYWORD = 0
GROUP_KEYWORD = 1
txt = txt.split("/n")
state = SINGE_KEYWORD
group_keyword = set()
#处理文本
for line in txt:
line = line.strip()
if not line:
continue
if line.startswith(">>>"):
cat_id = len(self.group_name_list)
group_name_list = line[3:].strip()
self.group_name_list.append(group_name_list)
state = SINGE_KEYWORD
elif len(line) == 1:
if line == '{':
state = GROUP_KEYWORD
elif line == "}":
state = SINGE_KEYWORD
if group_keyword:
group_keyword = tuple(group_keyword)
self.group_keyword.append(group_keyword)
self.group_id_to_cat_id.append(cat_id)
self.group_keyword_length.append(len(group_keyword))
group_keyword = set()
elif state == SINGE_KEYWORD:
self.single_keyword_to_cat_id[line] = cat_id
elif state == GROUP_KEYWORD:
group_keyword.add(line)
self._keyword_to_group_id()
self._init_search()
def which_group_id(self, text):
total_group = len(self.group_name_list)
group = total_group
single_search = self.single_search.count(text)
all_keys = single_search.keys()
if single_search:
for key in single_search.keys():
cat_id = self.single_keyword_to_cat_id[key]
if cat_id < group:
group = cat_id
group_search = self.group_search.count(text)
all_keys.extend(group_search.keys())
group_count = defaultdict(int)
for k in group_search.keys():
group_id_list = self.group_keyword_to_group_id[k]
for i in group_id_list:
group_count[i]+=1
for k, v in group_count.iteritems():
if self.group_keyword_length[k] <= v:
#返回最小的那个 事情比事后优先级高
cat_id = self.group_id_to_cat_id[k]
if cat_id < group:
group = cat_id
if group < total_group:
return group, all_keys
def which_group_name(self, text):
pos = self.which_group_id(text)
if pos is not None:
pos , keywords = pos
keywords = " ".join(keywords)
return self.group_name_list[pos], keywords
if __name__ == "__main__":
test_input = """
>>> 广告事前
贵公司
{
办证
电话
}
{
是
网站
促销
}
>>> 敏感文章事前
>>> 广告事后
开发票
{
网站
代购
}
的
>>> 敏感文章事后
"""
censor_keyword = CensorKeyword()
censor_keyword.load_txt(test_input)
censor_keyword.load_txt(test_input)
censor_keyword.load_txt(test_input)
test = """
牛奶@咖啡3月21日专场演出(免票)
牛奶@咖啡3月21日专场演出(免票)
活动介绍
牛奶@咖啡自从巡演回来后一直没有在北京作专场演出,如果你对最近每次的小型演出还不过瘾,就到我们的这次专场上听个够吧!“一起不孤单!”
让更多的人来一起倾听牛奶@咖啡的歌声吧!如果你还不知道他们,去下面的网址了解一下吧!http://www.douban.com/group/milkcoffee/
牛奶@咖啡3月21日周六下午1点半SOHO尚都专场,免票无需报名
地点:SOHO尚都西塔一层钢琴舞台(地铁一号线永安里站B口出倒126路公交芳草地站下车即是)
咨询电话:老徐:13801108173
活动网址:http://www.douban.com/event/10533960/
同时还有市集可以逛:http://www.douban.com/event/10503500/
"""
#print " ".join(censor_keyword.which_group_name("贵公司"))
#print " ".join(censor_keyword.which_group_name("代购网站的"))
print " ".join(censor_keyword.which_group_name(test))
关键词/词组->分类识别系统 设计+实现
最新推荐文章于 2024-09-26 13:55:29 发布