使用Python spaCy时,read()与readlines()的词/词性计数结果差异问题
问题:spaCy词性统计中read()与readlines()结果差异的原因及可信性
我在使用spaCy对《福尔摩斯》书籍进行词数统计时,最初使用以下代码:
import spacy nlp = spacy.load('en_core_web_sm') with open("sherlock.txt", encoding='utf8') as sherlock: sherlock = str(sherlock.readlines()) text = nlp(sherlock) count = text.count_by(spacy.attrs.POS) for k, v in count.items(): print(text.vocab[k].text, v)
之后我将readlines()改为read()简化代码:
import spacy nlp = spacy.load('en_core_web_sm') with open("sherlock.txt", encoding='utf8') as sherlock: sherlock = sherlock.read() text = nlp(sherlock) count = text.count_by(spacy.attrs.POS) for k, v in count.items(): print(text.vocab[k].text, v)
但两者得到的计数结果差异极大:
使用readlines()的结果:
X 2753 PUNCT 53127 DET 9309 NOUN 18666 ADP 11106 PROPN 8769 NUM 979 SPACE 711 ADJ 6118 PRON 15626 AUX 7491 ADV 5800 VERB 13183 PART 2265 SCONJ 3437 CCONJ 3665 INTJ 486 SYM 31
使用read()的结果:
DET 10211 PROPN 4048 ADP 11774 SPACE 9329 NOUN 16950 PUNCT 21603 PART 2433 PRON 16906 AUX 8133 ADV 6236 VERB 13561 ADJ 6628 CCONJ 3945 SCONJ 3735 NUM 974 INTJ 477 SYM 35 X 10
虽然知道readlines()返回列表、read()返回字符串,标点差异可以理解,但两者的形容词、代词、名词数量分别相差500、1300、2000左右。请问造成这种差异的原因是什么?我应该信任哪一组结果?
原因分析
核心问题出在str(sherlock.readlines())这行代码上:
readlines()返回的是每行文本组成的列表,当你用str()将其转换为字符串时,会把列表的格式符号(比如方括号[]、逗号,、单引号')全部混入文本内容中,被spaCy当作正常文本处理。- 这些额外的符号不仅会被错误统计为标点或
X(其他类别),还会干扰正常文本的分词和词性标注逻辑——比如原本的单词被引号包裹后,可能被spaCy识别为特殊token,导致词性判断出错,进而影响各类词性的计数结果。 - 而
read()直接返回完整的纯文本字符串,没有任何额外的列表格式符号,spaCy可以正确处理原始文本的分词和词性标注,得到的结果更准确。
结论
你应该完全信任使用read()得到的统计结果。readlines()加str()的处理方式相当于给原始文本注入了大量不属于书籍内容的“垃圾符号”,导致spaCy的词性统计完全失真,没有参考价值。
内容的提问来源于stack exchange,提问作者DownrightBass
相关产品推荐
相关产品推荐

