中文分词-学习笔记

分词:将一个句子分成以词为单位的组成(中文都是以词组句子)

分词方法:动态规划方法,维特比算法(HMM)

分词工具:jieba、snowNLP、THULAC

1. jieba

pip install jieba

算法

  1. 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)
  2. 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
  3. 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法

jieba.cut(data),返回generator, 需list(jieba.cut(data))

jieba.cut(data, cut_all=False)   #默认精确模式cut_all=False; 若cut_all=True为全模式

github上jieba介绍:

https://github.com/fxsjy/jieba

import jieba
import re

# 载入数据(txt文本,encoding="utf-8")
data = open("test.txt", encoder="utf-8",errors="ignore").readlines()

# 观察数据
data[:5]
[out]:
['\ufeff\n',
 '\u3000第一回\u3000风雪惊变\n',
 '\n',
 '\u3000\u3000钱塘江浩浩江水,日日夜夜无穷无尽的从临安牛家村边绕过,东流入海。江畔一排数十株乌柏树,叶子似火烧般红,正是八月天时。村前村后的野草刚起始变黄,一抹斜阳映照之下,更增了几分萧索。两株大松树下围着一堆村民,男男女女和十几个小孩,正自聚精会神的听着一个瘦削的老者说话。\n',
 '\n']

# 定义分词函数,首先预处理数据成可以用于分词的数据,再使用jieba.cut分词
def process(data, lenNum):
    # 过滤长度小于lenNum的行
    filterdata = filter(lambda s: len(s)>=lenNum, data)
    # 去掉字符串收尾缩进"\u3000"和换行符"\n",注意filter,map返回的是生成器,不能直接读取,要使用list()
    m1 = map(lambda s: s.strip("\u3000|\n"), filterdata)
    # 去掉字符串中间的缩进,用replace("\u3000","")
    m2 = map(lambda s: s.replace("\u3000",""),m1)
    # 去掉中文标点符号,正则表达式re.sub("a","b",c)将c中的a换成b
    m3 = map(lambda s: re.sub("[!?。※ □"#$%&'()《》*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏.]+","",s),m2)
    # 中文分词, jieba.cut()返回generator,list(jieba.cut())将结果显示出来
    cut_words = map(lambda s: list(jieba.cut(s)),m3)
    return list(cut_words)

# 将制定文本分词
cut_words = process(data, 5)
cut_words[:2]
[out:]
[['第一回', '风雪', '惊变'],
 ['钱塘江',
  '浩浩',
  '江水',
  '日日夜夜',
  '无穷无尽',
  '的',
  '从',
  '临安',
  '牛家村',
  '边',
  '绕过',
  '东',
  '流入',
  '海',
  '江畔',
  '一排',
  '数十株',
  '乌',
  '柏树',
  '叶子',
  '似',
  '火烧',
  '般红',
  '正是',
  '八月',
  '天时',
  '村前村后',
  '的',
  '野草',
  '刚',
  '起始',
  '变黄',
  '一抹',
  '斜阳',
  '映照',
  '之下',
  '更增',
  '了',
  '几分',
  '萧索',
  '两株',
  '大',
  '松树',
  '下',
  '围着',
  '一堆',
  '村民',
  '男男女女',
  '和',
  '十几个',
  '小孩',
  '正自',
  '聚精会神',
  '的',
  '听',
  '着',
  '一个',
  '瘦削',
  '的',
  '老者',
  '说话']]

​# cut_words返回的list为分行分词后的结果,要统计所有字符的频率
total_words = []
for each in cut_words:
    # 用extend是将each列表中的元素4添加到原列表[1,2,3]中,组成一个新的列表[1,2,3,4]。而append是将each列表[4]为一个整体添加到原列表中[1,2,3,[4]]
    total_words.extend(each)

len(total_words)
[out]:458018
len(cut_words)
[out]:2690

猜你喜欢

转载自blog.csdn.net/huangxiaoyun1900/article/details/81300132