【NLP】Python NLTK處理原始文本


Python NLTK 處理原始文本

作者:白寧超

2016年11月8日22:45:44

摘要:NLTK是由賓夕法尼亞大學計算機和信息科學使用python語言實現的一種自然語言工具包,其收集的大量公開數據集、模型上提供了全面、易用的接口,涵蓋了分詞、詞性標注(Part-Of-Speech tag, POS-tag)、命名實體識別(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各項 NLP 領域的功能。本文主要介紹:1)怎樣編寫程序訪問本地和網絡上的文件,從而獲得無限的語言材料?2)如何把文檔分割成單獨的單詞和標點符號,並進行文本語料上的分析?3)怎樣編寫程序產生格式化輸出,並把結果保存在文件中?關於Python基礎知識可以參看本人的【Python五篇慢慢彈】系列文章(本文原創編著,轉載注明出處:Python NLTK處理原始文本

目錄


【Python NLP】干貨!詳述Python NLTK下如何使用stanford NLP工具包(1)

【Python NLP】Python 自然語言處理工具小結(2)

【Python NLP】Python NLTK 走進大秦帝國(3)

【Python NLP】Python NLTK獲取文本語料和詞匯資源(4)

【Python NLP】Python NLTK處理原始文本(5)

關於處理原始文本部分導入語句:

>>> from __future__ import division
>>> import nltk,re,pprint

1 從網絡和硬盤訪問文本(在線獲取傷寒雜病論)


 python網絡訪問程序:

>>> from __future__ import division
>>> import nltk,re,pprint
>>> from urllib.request import urlopen
>>> url=r'http://www.gutenberg.org/files/24272/24272-0.txt'
>>> raw=urlopen(url).read()
>>> raw = raw.decode('utf-8')
>>> len(raw)
70306
>>> raw[2000:2500]

 運行結果:

對其中文分詞:

>>> from nltk.tokenize import StanfordSegmenter
>>> segmenter = StanfordSegmenter(
    path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-segmenter.jar",
    path_to_slf4j=r"E:\tools\stanfordNLTK\jar\slf4j-api.jar",
    path_to_sihan_corpora_dict=r"E:\tools\stanfordNLTK\jar\data/",
    path_to_model=r"E:\tools\stanfordNLTK\jar\data\pku.gz",
    path_to_dict=r"E:\tools\stanfordNLTK\jar\data\dict-chris6.ser.gz"
)
>>> result = segmenter.segment(raw)
>>> result[1000:2500]

 分詞結果:

 

2 在線獲取處理HTML文本(紅樓夢)


在線獲取html文本資料:

>>> import re,nltk
>>> from urllib.request import urlopen
>>> url='http://www.gutenberg.org/cache/epub/24264/pg24264-images.html'
>>> html=urlopen(url).read()
>>> html=html.decode('utf-8')
>>> html[5000:5500]

 運行結果:

相關正則知識:

  1. \d  匹配一個數字
  2. \w 匹配一個字母或者數字
  3. *  任意個字符(包括0個),
  4. +  至少一個字符
  5. ?  0個或1個字符
  6. {n} n個字符
  7. {n,m} n-m個字符
  8. \s 匹配一個空格
  9. \s+ 至少有一個空格
  10. \d{3,8} 表示3-8個數字,例如'1234567'
  11. \d{3}\s+\d{3,8}
  12. [0-9a-zA-Z\_] 匹配一個數字、字母或者下划線
  13. [0-9a-zA-Z\_]+ 匹配至少由一個數字、字母或者下划線組成的字符串,
  14. 比如'a100','0_Z','Py3000'等等;
  15. [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划線開頭,后接任意個由一個數字、字母或者下划線組成的字符串,也就是Python合法的變量
  16. [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精確地限制了變量的長度是1-20個字符(前面1個字符+后面最多19個字符)
  17. A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'
  18. ^表示行的開頭,^\d表示必須以數字開頭
  19. $表示行的結束,\d$表示必須以數字結束

正則表達式進行數據清洗:

>>> len(html)
962651
>>> strhtml=re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。??、~@#¥%……&*()]+|[A-Za-z0-9]+","",html)#去掉中英文符號
>>> len(strhtml)
781150
>>> strhtml[5000:5500]

清洗后結果:

紅樓夢進行中文分詞

>>> # 紅樓夢進行中文分詞
>>> from nltk.tokenize import StanfordSegmenter
>>> segmenter = StanfordSegmenter(
    path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-segmenter.jar",
    path_to_slf4j=r"E:\tools\stanfordNLTK\jar\slf4j-api.jar",
    path_to_sihan_corpora_dict=r"E:\tools\stanfordNLTK\jar\data/",
    path_to_model=r"E:\tools\stanfordNLTK\jar\data\pku.gz",
    path_to_dict=r"E:\tools\stanfordNLTK\jar\data\dict-chris6.ser.gz"
)
>>> result = segmenter.segment(raw)

查找分析:查找“曰”后面的內容

re.findall(r'(曰.{,3})',strhtml)

 

備注:處理搜索引擎的結果:基於自己配置的搜索引擎處理

 

3 處理RSS訂閱


 

>>> import feedparser #feedparser需要在python庫中下載
>>> llog=feedparser.parse(url)

 

4 讀取本地文件:strip()方法刪除輸入行結尾的換行符


方法一:

>>> f=open(r"E:\dict\q0.txt","r")
>>> for line in f:
	print(line.strip())

方法二:

>>> with open(r"C:\Users\cuitbnc\Desktop\dqdg.txt","r+") as f:
    str=f.read()

方法三:

>>> import nltk
>>> path=nltk.data.find(r'C:\Users\cuitbnc\Desktop\dqdg.txt')
>>> raw=open(path,'rU').read()
>>> len(raw)
673167
>>> 

 PDF或者MSWord以及其他二進制提取文本,利用第三方函數庫pypdf和pywin32

>>> raw=open(r"E:\dict\q0.txt","r").read()
>>> tokens=nltk.word_tokenize(raw)
>>> words=[w for w in tokens]
>>> vocab=sorted(set(words))
>>> vocab

 

5 字符串:最底層的文本處理


有用的字符串方法:

  • s.find(t)  字符串s中包含t的第一個索引s.rfind(t)  字符串s中包含t的最后一個索引
  • s.index(t)  與s.find(t)類似
  • s.rindex(t)  與s.rfind(t)類似
  • s.join(text)
  • s.split(t)  字符串分割
  • s.splitlines()
  • s.lower()
  • s.upper()
  • s.titlecase() s首字母大寫
  • s.strip()  返回一個沒有首尾空白字符的s的復制
  • s.replace(t,u) 用u替換s中的t

鏈表和字符串的差異:字符串和鏈表都是一種序列,可以通過索引抽取他們一部分,可以切片,可以合並。但是,鏈表和字符串不能連接

  

6 使用Unicode進行文字處理


解碼:文件中的文本都有特定的編碼,需要一些機制將文本翻譯成Unicode的過程就是解碼。 編碼:將Uniocde寫入一個文件或者終端,首先需要將Unicode轉化為合適的編碼,這個過程就是編碼

中文解碼問題

 

>>> raw=open(r"E:\dict\text.txt","r").read()
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    raw=open(r"E:\dict\text.txt","r").read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 16: illegal multibyte sequence
>>> import codecs
>>> f=codecs.open(r"E:\dict\text.txt",'r',encoding="utf-8").read()

 ord()查找字符的整數序列

>>> ord('a')
97
>>> ord('f')
102

 

7 使用正則表達式檢測詞組搭配


import re 導入re函數庫

re.search('ed$',w)查詢w字符串中是都ed結尾匹配 [w for w in wordlist if re,search('ed$',w)]

通配符“.”可以用來匹配任何單個字符。例如:有一個8個字母組成的字謎,j是第三個字母,t的第六個字母,每個空白單元格用句點隔開.(^字符串開始,$字符串結束)

[w for w in wordlist if re.search('^..j..t..$',w)]

計算文本中詞出現次數 sum(w for w in text if re.search('^e-?mail$',w))

搜索數字

[w for w in wordlist if re.search('^[0-9]+\.[0-9]+$',w)]

[w for w in wordlist if re.search('^[0-9]{4}$',w)]

python正則表達式基本元字符 

  1. .   通配符,匹配所有字符
  2. ^abc  匹配以abc開始的字符串
  3. abc$  匹配以abc結尾的字符串
  4. [abc]  匹配字符集合
  5. [A-Z0-9] 匹配字符范圍
  6. ed|ing|s 匹配指定的字符串,諸如ed或者ing或者s
  7. *   前面項目0個或者多個,如a*/[a-z]* (也叫Kleene閉包)
  8. +   前面項目1個或者多個,如a+、[a-z]+
  9. ?   前面項目0個或者1個,如a?、[a-z]?
  10. {n}   重復n次
  11. {n,}  至少重復n次
  12. {,n}  重復不多於n次
  13. {m,n}  至少重復m次不多於n次
  14. a(b|c)+  括號表示操作符的范圍
  15. 正則表達式符號:
  16. \b 詞邊界
  17. \d 任何數字等於[0-9]
  18. \D 任何非數字等於[^0-9]
  19. \s 任何空白字符[\t\n\r\f\v]
  20. \S 任何非空白字符[^\t\n\r\f\v]
  21. \w 任何字母[A-Za-z0-9]
  22. \W 任何非字母[^A-Za-z0-9]
  23. \t 制表符
  24. \n 換行符

指定條件查詢分析:

>>> f=codecs.open(r"E:\dict\q0.txt",'r').read()
>>> import re
>>> re.findall(r"大秦",f)
['大秦']
>>> re.findall(r"龐涓",f)
['龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓', '龐涓']
>>> len(re.findall(r"龐涓",f))
33
>>> 

 

【推薦】 

  1. 古滕堡語料庫
  2. 語料庫在線
  3. 搜狗實驗室新聞|互聯網數據
  4. 北京大學語言研究中心
  5. 計算機語言研究所
  6. 數據堂

                  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM