爬虫(六十九)简明 jieba 中文分词教程(六十)) K9 x' e! B- u! {
/ z$ m( B3 c5 {. Z. ]0 g0 引言jieba 是目前最好的 Python 中文分词组件,它主要有以下 3 种特性: - 7 U. v- T& M: k+ o* ]
! Q5 f r' z* H5 _8 S( C2 W
# 导入 jieba* t7 t* n( t9 d! ]( J8 X3 |( Q
0 X- F% q+ v6 l$ R - ; y1 Z9 V8 u& J# E6 r" `8 W( v
% O* L" p. ?; Y" O
import jieba! Q3 e+ B- N: U( E s
, f3 p* P0 q6 G+ s3 a0 J" v) A
& N' b7 A {5 M( M" ~) u3 Q# ^, y* h; ^% n; G
import jieba.posseg as pseg #词性标注
1 D8 O H! E% R; C! x4 f. c
) A, a* y l! B3 r- ( p. V m$ B. l& L
2 J; ]" U, \ f* h+ ^3 ?9 uimport jieba.analyse as anls #关键词提取2 }9 b: P0 t' H! c2 F7 W7 a/ b
* e8 P, a% n- u4 H- a) d8 x* z
0 B" g+ l3 Y# \- g* }9 @: n+ W
1 分词
8 z9 u0 ~+ n6 x5 a3 S可使用 jieba.cut 和 jieba.cut_for_search 方法进行分词,两者所返回的结构都是一个可迭代的 generator,可使用 for 循环来获得分词后得到的每一个词语(unicode),或者直接使用 jieba.lcut 以及 jieba.lcut_for_search 直接返回 list。其中:) N) L; K& W, a. X' r# K% ~' X
# 尽量不要使用 GBK 字符串,可能无法预料地错误解码成 UTF-8
! {* F6 I4 o) A, y5 z) N1.1 全模式和精确模式$ S O( x _4 L$ Y6 N; p# Z
& F; q- |; ]# v& z! M
: c- v) b, T3 L6 M
3 k9 T6 s9 [$ Y8 U; {0 w' U# 全模式2 ^/ k+ @' V2 Z7 k: w
! r2 }1 m K* E6 l3 }
; q9 n, e5 U3 f" [. f! \& i# G( p0 S
seg_list = jieba.cut("他来到上海交通大学", cut_all=True)
$ r5 A9 w" [: D" ?1 F/ |
0 s2 |6 B" k7 c- 4 Z; o1 Y: X- _+ c( E. e1 o3 _. Y) K
0 K8 \( d' Q1 n5 k4 h' u) d
print("【全模式】:" + "/ ".join(seg_list)) ! f; F5 ^, ]( E) z9 C/ T' c% W
! ]' P; o4 s( ]7 w' r1 e8 R& `
9 T. f. S0 _$ t# C# e, C' M
【全模式】:他/ 来到/ 上海/ 上海交通大学/ 交通/ 大学
: u2 M0 D* \/ H" E% N8 F/ z" k" `+ o- x: T# Y3 ]& a. c
# 精确模式% h8 {" k' i2 n: M: y6 \; q
! c! ~0 f. Y6 I2 S/ _ J" G- # V4 {' w9 ?! G! F* W
1 ] T7 C8 R8 eseg_list = jieba.cut("他来到上海交通大学", cut_all=False)
8 P" } E! h/ q" z7 Z
: t- Z8 ~" Q5 C - $ @ j4 h/ \5 i P6 W6 ?
! f# o2 u; Z: E2 |' o' P- _print("【精确模式】:" + "/ ".join(seg_list))! G+ T: x" I" k' l& @+ a
% w: T1 N/ C5 K# G( g( V% r
- \. p7 n& F' B+ {* Z0 ?0 ?/ e
【精确模式】:他/ 来到/ 上海交通大学 type(seg_list)generator
) |$ _1 A. m8 T$ g1 S
7 `( r: l+ k1 T# 返回列表
5 w" C- e ?4 \7 C
! B4 k- f0 y) R1 e! X: |- 4 s2 X: i. s7 z K0 u) L; {
- w9 w$ [- B+ ^/ j# {% H
seg_list = jieba.lcut("他来到上海交通大学", cut_all=True)
% Q+ ?- n) t+ ~" q
+ ], D3 z0 L& s; U. D2 S( A. H( d - + A/ a! a- o) P# \, Y. ^4 Z( G
* L& I4 ]# L0 [) q6 u$ m! m+ o
print("【返回列表】:{0}".format(seg_list)); d5 f& D/ y2 z+ }' ~
$ ~3 @, x5 T1 c: d
1 ~4 y9 w6 u% `8 Y
【返回列表】:['他', '来到', '上海', '上海交通大学', '交通', '大学'] type(seg_list)list 1.2 搜索引擎模式 - 6 @9 {# `. L: T; \; K" ?
5 A9 Z* }6 D' M+ C# 搜索引擎模式1 M! P. D. c, e5 e- G' U& v
. {. H! {/ l: n& [% Z1 C
; D4 }2 {: W$ D& S# R" j
" F: B2 n, M2 gseg_list = jieba.cut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")0 O- B0 N k' R: @0 q. F3 V3 ~2 L8 f
9 @/ q0 u5 N5 g
# F+ J* ?3 @/ ^- E) `, g
& B& ?% R7 u1 G9 ~print("【搜索引擎模式】:" + "/ ".join(seg_list))
# {7 Y) j, g* l0 {0 W
5 y$ i! m" R. E( v s0 F, q- z' v% {8 Y) M
【搜索引擎模式】:他/ 毕业/ 于/ 上海/ 交通/ 大学/ 上海交通大学/ 机电/ 系/ ,/ 后来/ 在/ 一机部/ 上海/ 电器/ 科学/ 研究/ 研究所/ 工作 - 2 b/ A' L6 G: f; A
: j' `; D2 D$ ~* p+ x
# 返回列表
) n+ {+ X+ `, A7 P% ?
( F( J4 @& h1 |3 n
$ z- o0 \8 q! ^( H4 f
$ A5 r2 ]' E3 cseg_list = jieba.lcut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")* o; A" Z, S4 j- t7 L5 ?9 x
. U& G6 c* t& z& t0 h! T% X4 \7 P" o
8 g3 U1 ?. {( Z
' X- G, y% f: W; [) V' ?print("【返回列表】:{0}".format(seg_list))
0 B$ A* `: \( x( a) r" J7 D" G; C* C2 Z1 \% O* B$ r! a
- ]4 F2 U. o+ {, \. k" O
【返回列表】:['他', '毕业', '于', '上海', '交通', '大学', '上海交通大学', '机电', '系', ',', '后来', '在', '一机部', '上海', '电器', '科学', '研究', '研究所', '工作']3 c6 p/ f6 L& s
# a7 W( V' E; I, R
1.3 HMM 模型
{$ D0 d: k' I: P" hHMM 模型,即隐马尔可夫模型(Hidden Markov Model, HMM),是一种基于概率的统计分析模型,用来描述一个系统隐性状态的转移和隐性状态的表现概率。在 jieba 中,对于未登录到词库的词,使用了基于汉字成词能力的 HMM 模型和 Viterbi 算法,其大致原理是:
- X6 w# p5 c$ K: z" [: J J采用四个隐含状态,分别表示为单字成词,词组的开头,词组的中间,词组的结尾。通过标注好的分词训练集,可以得到 HMM 的各个参数,然后使用 Viterbi 算法来解释测试集,得到分词结果。4 y8 R! o0 K1 D' r b1 Z" Q: v
, J6 u) y% Y+ R* [" ]' y# o s
# 代码实现可参考 HmmSeg.py
, h* C* B) e$ A8 y6 n& G, N# O) |* c' y* v% y
- g( w: N7 d" S
6 X+ D+ ^9 S4 ^3 x, V) E# E. n! l# 未启用 HMM5 {3 P8 L) R0 p; Z
6 t, _& p4 n) Q8 l
0 ^2 v1 @ {5 I
: V7 I" I+ M" V" gseg_list = jieba.cut("他来到了网易杭研大厦", HMM=False) #默认精确模式和启用 HMM. h/ y/ U) f$ h6 F6 R
% V3 D9 W9 v7 j: v4 ]
" a1 w9 [- ?3 k; m; e% i K9 z
' h$ r: s% \9 ]; o- \9 `; m1 j1 Qprint("【未启用 HMM】:" + "/ ".join(seg_list))
0 h" k, B5 V; M' T% w( o/ l# X& ~1 D; g% t
! C3 y4 T, [2 ?$ Y+ n8 S
【未启用 HMM】:他/ 来到/ 了/ 网易/ 杭/ 研/ 大厦
0 K1 B* M# @5 b) W, F* N2 }/ D
! Y. v% r( W7 }; @# 识别新词7 \% p2 @& }3 v* T
% x& Q+ N, u' x1 K- I+ O
5 N$ k5 c$ o: C* y# j) T' y2 @% U/ o; @) Y
seg_list = jieba.cut("他来到了网易杭研大厦") #默认精确模式和启用 HMM& V4 E x2 e" `; j
; f; v {/ a; H" h0 A: A
8 i9 q+ x$ |- Y. r. \ q: H: ]/ Y @1 f m l6 I2 a$ f Y3 n
print("【识别新词】:" + "/ ".join(seg_list))! |5 b7 _" `7 ]* e( O+ @
& p j& m f" t. i; i6 Q% f5 W) O0 f. ~
【识别新词】:他/ 来到/ 了/ 网易/ 杭研/ 大厦 2 繁体字分词jieba 还支持对繁体字进行分词。 - ' i8 _9 O2 f& j$ A& U
1 t; Z+ ^+ b, l% Y
# 繁体字文本
/ _- a6 w, I4 l) e, n: F3 M
. f: ?% l/ Y% A3 r2 h
; _( F4 M& P# s
) f' u/ q6 h: P# ?$ [, ]/ s6 [9 Cft_text = """人生易老天難老 歲歲重陽 今又重陽 戰地黃花分外香 壹年壹度秋風勁 不似春光 勝似春光 寥廓江天萬裏霜 """
' S' G. u. B0 C/ O. q
1 N& m5 a/ T5 u( D) @
/ n7 I0 y2 l6 f1 V- L" }) T9 U' T0 l, x2 ` |# e" W/ g
# 全模式+ H$ W1 d; ?6 Z) ?/ X/ p
: r$ Z+ x- b: s
4 b" S# r9 {$ [" B' K3 {! L! H
print("【全模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=True)))
6 K& J( s/ B8 A9 X
9 {' a' e K+ Y6 I8 h# Q
2 {. Y# W! `& k. ]
【全模式】:人生/ 易/ 老天/ 難/ 老/ / / 歲/ 歲/ 重/ 陽/ / / 今/ 又/ 重/ 陽/ / / 戰/ 地/ 黃/ 花/ 分外/ 香/ / / 壹年/ 壹/ 度/ 秋/ 風/ 勁/ / / 不似/ 春光/ / / 勝/ 似/ 春光/ / / 寥廓/ 江天/ 萬/ 裏/ 霜/ /
2 `# x8 S) y: h2 O7 K* r: @
# {* S$ n, I) F# m& ~
$ L9 B" D; b2 `! f# A# 精确模式
8 b# O' x/ T l# d" m+ z
8 V4 }$ P2 \# J" e6 j+ ~/ ] \, R
& N+ A; o+ K+ b6 a. X7 S! b' p( d1 N0 K3 } P" [
print("【精确模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=False)))/ n! ]6 u& w, X! u
8 f) D9 o! J4 M" m0 j" Z b4 i2 Q' y4 _
【精确模式】:人生/ 易/ 老天/ 難老/ / 歲/ 歲/ 重陽/ / 今/ 又/ 重陽/ / 戰地/ 黃/ 花/ 分外/ 香/ / 壹年/ 壹度/ 秋風勁/ / 不/ 似/ 春光/ / 勝似/ 春光/ / 寥廓/ 江天/ 萬/ 裏/ 霜/+ f; y' _$ a7 B* V; v; G
7 t( B. E; n0 z8 x( _- o: q. x6 u3 r( \; M$ F- V. ^3 ]2 ^: `
- 5 G9 q9 x; g7 S2 u0 g$ H
3 } l0 r. Y4 ?3 R; ?
# 搜索引擎模式
& G a6 R" t& f& L0 n5 ^6 f/ q8 v5 V6 `3 B4 f+ H) ^- P e7 X3 @/ N
- , s# V+ p7 H" S2 V2 }
2 L' x, ~* @, H/ d' o; L& w
print("【搜索引擎模式】:" + "/ ".join(jieba.cut_for_search(ft_text)))
! ], ?2 Z/ \ y, u- ~
$ x4 t5 K1 e" Q" H& }1 {3 H( Z! i; A( W
搜索引擎模式】:人生/ 易/ 老天/ 難老/ / 歲/ 歲/ 重陽/ / 今/ 又/ 重陽/ / 戰地/ 黃/ 花/ 分外/ 香/ / 壹年/ 壹度/ 秋風勁/ / 不/ 似/ 春光/ / 勝似/ 春光/ / 寥廓/ 江天/ 萬/ 裏/ 霜/# G% d+ N: {* w1 Q# u; X
( n0 c4 Q0 s) u% [+ q. d' c
3 添加自定义词典8 { b/ F( ?' }! W* Y; \
开发者可以指定自定义词典,以便包含 jieba 词库里没有的词,词典格式如下:
2 x( K7 |1 [! l* D! K9 Q词语 词频(可省略) 词性(可省略)
3 j7 w$ }2 _0 L) d" P. C7 H; Q# ^* i$ S% r6 [0 f3 `2 m- K
例如:
; \) r l7 K3 n1 G9 u0 a" f( S9 }+ v/ X1 g) T+ z
^ V; x5 P. S# ^( d& ?. T2 s d
- 0 A& a2 U: k5 ~8 @ J
! c5 |' j) [( e, H8 V0 c创新办 3 i4 ]+ |+ @& E. m$ c
3 p7 x2 T+ [& O# x
- * C+ H9 \! _' a) V. T
" d3 [ S. s5 I D1 @2 D5 M云计算 5
( g2 G+ q8 h# A1 ^. |1 A9 i+ ]8 r" \! H( D4 e0 s; x, K
- 4 X/ E" ~( F6 t9 [' Q
1 L5 N5 s2 }2 w V
凱特琳 nz
% X/ ?; T( o; _7 p/ A& D" [# M& g8 O& l$ w6 X. K/ Z
- n1 R8 Z7 b/ ^3 {' U U
# 虽然 jieba 有新词识别能力,但自行添加新词可以保证更高的正确率。
7 ^ C* H; }$ P3.1 载入词典 K. S0 A* x1 ^, K' i
使用 jieba.load_userdict(file_name) 即可载入词典。9 n/ I `- c0 L4 J9 D: X* t
# file_name 为文件类对象或自定义词典的路径; P+ B* L% q, X& e
+ a% l! S6 S$ g3 S0 J. ]* X W; P
" s6 y( }3 q. R9 S; o# Z8 W( b
) P X% m3 R q0 E& |, q( V
/ T, _% I+ s6 w) Z2 ^/ X# 示例文本
, ]5 e1 M9 X$ r9 k- `% u7 s# G4 B$ N- r, Q7 h
% M* g0 m( l, o, X! [2 a- W: B) n7 Y& Z5 E
sample_text = "周大福是创新办主任也是云计算方面的专家"
; I4 p: u( U/ P4 r
$ W- @ D- z# [7 |- U- $ ~* C0 E2 ~! p# c0 J6 v
n; ~: i# Y8 G+ k. F
) b1 ~3 P% U3 ?, {
& g' A. ~% C" F, ?$ i9 M" L+ N0 y
0 [7 x1 f w& K" j
& a- D6 m1 I4 A. G& w0 Q6 b! l) R# 未加载词典1 O: V, |4 R8 V. _: t, @
' }8 V! r; S" `3 ^+ T8 e7 z
- $ k, N5 V; E u% Z
1 n/ K/ D. {) ~' p0 `7 h7 bprint("【未加载词典】:" + '/ '.join(jieba.cut(sample_text)))
; Q8 e4 P0 e+ I7 V8 p: X8 p. p
1 I9 ?* ^0 I' ?" i `6 X, t
, q7 U! ^: b! f) z( ~+ V. P+ S
【未加载词典】:周大福/ 是/ 创新/ 办/ 主任/ 也/ 是/ 云/ 计算/ 方面/ 的/ 专家 【加载词典后】:周大福/ 是/ 创新办/ 主任/ 也/ 是/ 云计算/ 方面/ 的/ 专家
) {% H z- ?+ o. u0 J% [: g O) n. l9 K3 y, f
3.2 调整词典/ `0 H8 D5 z: y
使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。/ I8 D4 ?$ G+ H& p/ Z% j) C8 y( F8 Q
9 ~8 w6 C$ _4 H8 }# N, ~) c* {
7 t8 o% `1 ^; L& q - 7 L8 ?* m! C1 B/ Q1 I
4 ~) x- z/ S; j9 N9 ?' W
jieba.add_word('石墨烯') #增加自定义词语& z, e/ r' r+ N% i
" Q/ w# ?8 }0 J, R4 G - $ X0 g t/ b4 h0 I
6 f, z, o3 n+ M, k# E; Njieba.add_word('凱特琳', freq=42, tag='nz') #设置词频和词性5 X- h4 W3 Z9 P e' }' N5 }6 U
7 V6 o3 F4 J0 e$ S: p9 v: V7 b
, B1 W: S: x8 n) ?8 s4 H8 C; ^% m7 t0 @( |
jieba.del_word('自定义词') #删除自定义词语: m- r& u4 K$ C
. R3 [. D4 G" E' c( \
* C E' O/ W. K
使用suggest_freq(segment, tune=True)可调节单个词语的词频,使其能(或不能)被分出来
9 Z% D& ]1 ]4 X$ b4 D! g2 a
9 V5 N$ D$ f8 }; S2 B- u8 L# 调节词频前% @. v) _$ Y: q, I6 A7 @* D3 c
& q$ o5 z, C! K" j" u- F- 4 d; S: g& _, [1 m8 k v( f
Z$ }/ J4 H3 p8 rprint("【调节词频前】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
% E' J- H7 d+ \2 q. s2 [
. g: ^7 o, V' O1 c# s8 _9 G/ m4 l: k9 N4 v1 Y0 t& l- ~3 b
【调节词频前】:如果/放到/post/中将/出错/。 - + \( |6 l, \& S5 v; e7 {
/ S4 N6 \( {' Z- j
# 调节词频2 m$ Y- j. l% g
1 _! ?3 N. [% _ - 0 ]3 h6 D8 I1 `7 n
8 W, L6 t0 T, Kjieba.suggest_freq(('中', '将'), True)
5 ?& t% d; C5 t/ d4 H6 d# a7 G
, x3 p2 Y& {6 H8 D' S* ?1 _. ]% |4 P$ I; q0 k
494 - 3 D% [: b+ l6 s% H8 W7 c
# X7 m2 U1 h+ v" P# 调节词频后3 b/ \0 r" E2 s3 i# K% e
! N k+ q2 q! W
5 Z1 B6 x2 G7 w. T9 X3 C3 m$ A. m) y
print("【调节词频后】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
: A% ^8 V6 I# B/ d' ]0 v6 R3 V1 @$ J) Z0 [, Y7 Q! e
' i/ ~; c# z% B. d/ d6 B
【调节词频后】:如果/放到/post/中/将/出错/。" d; M. ^7 {0 ?7 l# q
3 ]# ~. h: P; b. |4 关键词提取9 p$ x1 X* ^. u+ r4 P. R2 e2 i
jieba 提供了两种关键词提取方法,分别基于 TF-IDF 算法和 TextRank 算法。
0 _" ]6 m7 \0 r$ S4 S; s& s7 M4.1 基于 TF-IDF 算法的关键词提取7 B- l4 r+ b9 |5 O& x! y2 S
TF-IDF(Term Frequency-Inverse Document Frequency, 词频-逆文件频率)是一种统计方法,用以评估一个词语对于一个文件集或一个语料库中的一份文件的重要程度,其原理可概括为:
1 Z! `0 n# I0 ]+ F* _( s$ d一个词语在一篇文章中出现次数越多,同时在所有文档中出现次数越少,越能够代表该文章! V( i. @; g9 K& v4 B8 d
+ ~3 T- x7 B$ O! l
计算公式:TF-IDF = TF * IDF,其中:
" X0 D; x$ S9 o# w4 i$ }1 B ![]() IDF(inverse document frequency, IDF):逆文件频率,如果包含词条的文件越少,则说明词条具有很好的类别区分能力,计算公式:
. i& s& B+ n( c' R! @# b, w2 ?0 k) D* Q& U/ ~
* D/ \, O$ q1 q3 _) F& _5 d$ C; M
; w, ?' n4 ]4 L" n. w
![]() 通过 jieba.analyse.extract_tags 方法可以基于 TF-IDF 算法进行关键词提取,该方法共有 4 个参数:
' L4 I- D# Y H o8 q# a0 Q - 0 I( u' Q" y5 D3 Y, f: @4 q @: V. `
/ j' P! q4 D' C+ C: U/ bs = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。"
1 [& }4 y; p0 l* T3 J4 V3 c% m; h# J; |- R3 B2 _1 b9 q
5 S2 A9 g, V5 m% p. z% C! H7 p1 ?& I4 H* P7 y8 C; w$ h
for x, w in anls.extract_tags(s, topK=20, withWeight=True):
+ J! f! R: `+ Q' b7 d
* A" ]' Q3 q3 E2 M
E" @4 m M2 w1 e$ A2 Z8 C- W7 X9 ?: y5 w3 {8 T. n
print('%s %s' % (x, w))
$ u7 d$ W+ }% U @! u) Z3 A) I/ h
) c& e P' {6 v$ V. {4 t
欧亚 0.73001427002893637 P+ c: N' [ x
吉林 0.659038184373617
3 n8 W l, I5 q置业 0.4887134522112766
8 z* `. J0 w' _0 M万元 0.3392722481859574( T! z/ K) L% N) p1 A
增资 0.33582401985234045
5 t w F& X9 [, Y3 w+ }4 u! M4.3 0.254356755380851063 j3 C8 c0 v; m, Z6 c; E
7000 0.25435675538085106* m6 Q) q5 `) O" M8 i, ~1 ^
2013 0.254356755380851060 K6 [$ @* r u' R+ v* M" I4 i: g
139.13 0.25435675538085106
; Y0 }8 Z5 Z2 N! g, ]/ y实现 0.19900979900382978
/ a8 S3 I+ k4 K4 w综合体 0.19480309624702127
. A* Z* P* L; H% M( m% y经营范围 0.19389757253595744
; e6 ?6 e; t( A6 s( @亿元 0.1914421623587234
! D& b' {9 c6 P8 }, m在建 0.17541884768425534
N2 R/ X' d7 L3 h. n全资 0.17180164988510638
3 R1 y- H; Y/ [& U4 L注册资本 0.17124415267 D) f; \% T- m+ ]6 s( z
百货 0.16734460041382979) K! q9 v9 q. l/ F# z
零售 0.1475057117057447: v0 J7 H- f: K' l' s/ E- M
子公司 0.14596045237787234% f4 J/ d, y6 y! X& M
营业 0.13920178509021275. D4 ~. d2 l i% D% Z& Z
5 S; Z1 F9 ^) ^# e# d# }# c使用 jieba.analyse.TFIDF(idf_path=None) 可以新建 TFIDF 实例,其中 idf_path 为 IDF 频率文件。6 O7 Q/ ~+ J; z6 ]4 ~8 `
4.2 基于 TextRank 算法的关键词提取
$ w Q- d1 z/ d p- m$ }TextRank 是另一种关键词提取算法,基于大名鼎鼎的 PageRank,其原理可参见论文—— TextRank: Bringing Order into Texts 。
5 b+ M" V9 I( s, r; s8 r通过 jieba.analyse.textrank 方法可以使用基于 TextRank 算法的关键词提取,其与 'jieba.analyse.extract_tags' 有一样的参数,但前者默认过滤词性(allowPOS=('ns', 'n', 'vn', 'v'))。
& g# g( j7 \$ ^+ x; T2 Z1 N
6 K3 ?/ f% s% X3 f* x9 e2 ~: q, c
/ d) L) s D% Q: Q- p b* P
' [ G8 U" Z8 w6 Q9 d Y6 gfor x, w in anls.textrank(s, withWeight=True):! B( D0 {' o! A( W9 t! S0 V" z6 O6 Q
0 u( Q/ l% |/ Y$ G/ s5 @. b
2 i5 q4 o9 _3 Z% D! L3 e
0 B4 x0 k$ P: T r/ { print('%s %s' % (x, w))+ F' M3 R2 K4 {
) S G5 w4 Q% ~4 O6 h
% f+ u7 w9 U0 S$ A
吉林 1.0! [& j, B, f' W' Z) @3 l
欧亚 0.9966893354178172
# l6 E. d: R! Y5 W6 N' @. _置业 0.6434360313092776
0 e: [1 R/ B) @/ C, G: I实现 0.5898606692859626
; C% e( N# x+ M% `/ n7 v收入 0.43677859947991454
# \! D% l( }" ^4 y7 J增资 0.40999005312832768 ~; A: ^- d% `% ?
子公司 0.35678295947672795
5 e; J( Q" d3 K4 u城市 0.34971383667403655
+ x. W, F. v/ F1 x# `1 a* X商业 0.34817220716026936; Q% `( Q% o* j
业务 0.30922309926198383 A6 K% D: d# S) L o3 W2 E0 u; o
在建 0.3077929164033088+ z: P1 E* x, S
营业 0.30357770493195884 _$ @* X: J7 @ |
全资 0.303540981053475' L6 M" `7 c$ ?8 T2 E+ c6 W
综合体 0.29580869172394825
@2 N" ]: C9 `3 s+ V注册资本 0.29000519464085045
9 T7 s Q; m! t7 \# R- i7 o- y有限公司 0.2807830798576574
% K; p! p( q8 c零售 0.27883620861218145% o w7 a! N5 b; Q5 C; G( \
百货 0.2781657628445476
1 y h8 l! B. C* |开发 0.26934887792958512 I/ J- P; A5 J) u+ _
经营范围 0.26427621735583160 y( H$ U9 M1 u. Z$ D
; n0 \1 t+ D- [0 E使用 jieba.analyse.TextRank() 可以新建自定义 TextRank 实例。5 h$ Z! ^ d9 b$ l
4.3 自定义语料库3 J7 j( K, [* A S- N
关键词提取所使用逆向文件频率(IDF)文本语料库和停止词(Stop Words)文本语料库可以切换成自定义语料库的路径。
' Z% w# M# |8 s" _7 Y
6 V( U; K; H9 }" c8 x8 Z
. z6 i" Y3 n/ ^& T- ]* X. M- p
: l4 M* h- h3 b; o. e0 x' T% ?, ^: }1 H& ?# u% c
jieba.analyse.set_stop_words("stop_words.txt")
0 u0 a4 O3 m# V: L3 f) h
! P! a2 T- f6 g- z
, A s: J/ ^% g; v/ |9 O
f4 U4 B/ \" Xjieba.analyse.set_idf_path("idf.txt.big");+ z/ h- }% y Y
: p& @* \7 ]7 s( f0 c
- 0 Z) J' ^$ |3 t6 q4 `* G( M* S
- L6 K: Z' g1 I/ C% e/ c6 v- }for x, w in anls.extract_tags(s, topK=20, withWeight=True):
, E* [- f% p6 Z1 q+ J- P2 Z
) i) L/ u! e8 w; [( \) L: D - ' ^+ K. Y2 w; R5 N
+ e9 Q: i9 y) z2 \- p print('%s %s' % (x, w))% A1 I4 H4 \$ q9 Y" p( D
2 n' ^; D3 \7 l+ ^: T& n$ i
: |' O0 e8 n l+ ]+ J
吉林 1.0174270215234043' P0 {! u1 S! y5 s N
欧亚 0.7300142700289363# D; O/ v/ u: M( ]0 `) f/ E! o c+ _
增资 0.5087135107617021* P1 F) g6 A. S3 y/ H( E/ G* N
实现 0.5087135107617021& n9 J5 S, w0 b
置业 0.4887134522112766
$ `" X, x+ U" Z9 B万元 0.33927224818595743 ^1 F9 |5 i+ p3 n& G" b# o1 n
此外 0.25435675538085106
\, q4 h% Z J y ^全资 0.25435675538085106, I( {6 r+ d/ u6 F' G* i
有限公司 0.25435675538085106+ i1 n- A# K ^0 y" F: V; C
4.3 0.25435675538085106
+ Q6 m, d0 c" t' D: x8 U注册资本 0.254356755380851068 I9 r/ [5 i! H
7000 0.25435675538085106
$ z6 ^6 ^. X, k+ \# ~3 N. J增加 0.25435675538085106
4 i5 }. M- c+ S/ A/ B7 `主要 0.25435675538085106
5 R% V7 c- [( [8 f* t) t房地产 0.254356755380851067 C/ `) U' [; v$ R
业务 0.25435675538085106
3 e4 Q& `+ p8 s; [( z8 m目前 0.25435675538085106
6 V) A( L& M& z城市 0.25435675538085106
3 D% W5 j9 w) b" x综合体 0.25435675538085106. J2 ]0 c9 D0 q* _" Y
2013 0.25435675538085106# ~% n1 U9 E( n) d: ~ r' D9 ^ i; U
! M3 _5 D: P2 i3 m3 X' f9 u5 S/ }( H! k( ^) W/ ~5 p5 Y6 C
5 词性标注9 W7 Z0 W. o7 B* o. m
jieba.posseg.POSTokenizer(tokenizer=None) 新建自定义分词器,tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。* q: W/ ]/ j2 \( x" R3 t# H
# 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。
. h& Y! e! ~# l1 Y! g. {% z! c! J1 Z3 i
1 _2 }& u+ | h6 K: d
( [8 A9 Q, ^# B& t* h! W+ G* e
" ^; D/ [4 O( wwords = pseg.cut("他改变了中国")! S+ T5 z( [ T
2 @/ x3 ?5 p' o- H
' ]& h% n& x; r) F3 t1 Y% V% J4 p
" n3 s7 T3 C! ?6 B0 I7 }for word, flag in words:5 t! ?) {# r9 V( o
" t5 |5 U& W, _* d; J' z
6 n9 ^6 L" x/ _0 p- N
! e! I8 F0 t+ W+ z1 o% I. Z z print("{0} {1}".format(word, flag))
! T9 l. R) } c) s+ ]* V8 S. t7 {4 U8 z
, E" P7 k' f+ W* [6 P# _0 g
他 r 改变 v 了 ul 中国 ns 6 并行分词( v+ A. Z. c/ e- z" n
将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升。用法:
; f1 ]7 s; i5 X% o& ^2 B8 E # 可参考 test_file.py
" G- {$ b. ]# Q" A注意:基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows
" P* E" @0 A8 D- k' Y( f1 u* }: q' Z* Z c
3 L$ K* I- k# e6 m7 j+ D
7 返回词语在原文的起止位置 使用 jieba.tokenize 方法可以返回词语在原文的起止位置。 注意:输入参数只接受 unicode - 1 i0 D" R3 w* C* @8 a
6 v {6 w$ y8 ~3 [3 I
result = jieba.tokenize(u'上海益民食品一厂有限公司')7 a" K8 N- F K, W2 b6 x j' J1 h8 a
! w& J$ T i' _' u5 z# ~/ _
' |9 H7 q0 t& b3 x+ h$ S( a3 F. i- ~: |. Z) }
print("【普通模式】")/ K+ [" o o( L2 B( C! m2 P
1 C- y7 J9 l' D: V# O- . g5 Z2 U/ c/ }0 G' x, R1 A1 S
# e3 b! g- V' A v- L/ j/ b
for tk in result:' H) ^- U" j- L
* b# O- ]# r+ o - : b! C( P/ U2 P$ |2 q7 v- _9 g
1 h; ~: x' J' n; |. q2 |4 _; U print("word: {0} \t\t start: {1} \t\t end: {2}".format(tk[0],tk[1],tk[2]))
% w1 \. S" H$ c, p
! f, x$ b2 H! p0 @; p' Q
! _ T9 D7 u* R( O0 u' W2 Y1 |
【普通模式】
: }- }. z! I$ S6 A( D7 H4 Rword: 上海 start: 0 end: 2$ p. ~, F! E/ J! E8 t+ P' V& l
word: 益民 start: 2 end: 4$ B# H$ [3 h5 v
word: 食品 start: 4 end: 6
. ~& r' u- V% y" ?" G' A6 Z( @word: 一厂 start: 6 end: 83 {' f( V% Q" _7 d" s
word: 有限公司 start: 8 end: 12
3 ?5 G; U% I+ e3 q2 ]3 J7 {/ l% y2 [3 W) S1 Q M9 f0 }
4 `8 a& Y* _8 L+ |6 G" W - 1 o) a5 {' [, a/ @! ^
4 m/ n6 o+ C; e1 |4 ^result = jieba.tokenize(u'上海益民食品一厂有限公司', mode='search')
- q6 D+ q8 [1 K0 k. M! P! ?9 t% ^: i3 p7 O3 Q8 U
( V" v2 W1 o5 C3 O$ U; S( B
8 L; |0 ^) \+ C6 N5 ~5 M, Hprint("【搜索模式】")! ^& F9 D4 S! m+ l/ ?1 b6 ^$ f1 O
5 O9 ]- Z! ^& j# P6 V- j/ w
- 5 U4 g9 ?& c: v$ Q
$ G0 [2 O+ d2 qfor tk in result:
- z0 K( T8 @9 A- m( [; m8 `: A# W+ ?3 _2 P! w: d5 g0 h
' I) I+ ]7 H' e% ~, `
+ k3 v! B+ l& r- r& p$ M! K print("word: {0} \t\t start: {1} \t\t end: {2}".format(tk[0],tk[1],tk[2]))
% {* o* ?# u! q) y
- q3 w4 w% A3 D6 M5 g* J! U; M! A2 a3 k/ ]$ c& l1 i
【搜索模式】4 y* k# X; ?3 m" e
word: 上海 start: 0 end: 2
, j. \6 p2 L: b9 K7 uword: 益民 start: 2 end: 4& H: g6 k; V/ @; r* N2 n+ m( @5 r
word: 食品 start: 4 end: 6- F0 F: s; |; ?( I
word: 一厂 start: 6 end: 89 v9 p6 t7 |9 A) q+ p% y
word: 有限 start: 8 end: 108 E" f$ L1 n: r% K
word: 公司 start: 10 end: 12
- w$ H O0 l8 U0 r$ lword: 有限公司 start: 8 end: 12 0 |$ }3 V3 \8 U, v
/ K8 P! ]6 I, i" V' z9 L/ x! z |