# \[1-2]文本预处理

### 数据导入

数据源有CSV，HTML, XML, 数据库, Json, PDF, NoSQL等。

对应的Python解析器有csv, HTMLparser、 SAX Parser、 DOM Parser, XMLParser, PYODBC, json, PDFminer等。

例如

```python
# csv load 
>>>import csv
>>>with open('example.csv','rb') as f:
>>>    reader=csv.reader(f,delimiter=',',quotechar='"')
>>> for line in reader :
>>> print line[1] # assuming the second field is the raw sting

# json load 
>>>import json
>>>jsonfile=open('example.json')
>>>data=json.load(jsonfile)
>>>print data['string']
```

### 句子拆分

一个典型的句子拆分器可以根据字符串中的`.`进行拆分，也可以使用预测式分类器识别句子边界。

```python
>>>inputstring = ' This is an example sent. The sentence splitter will split on sent markers. Ohh really !!'
>>>from nltk.tokenize import sent_tokenize
>>>all_sent=sent_tokenize(inputstring)
>>>print all_sent
[' This is an example sent', 'The sentence splitter will split on markers.','Ohh really !!']
```

函数`sent_tokenize`内部使用了NLTK中构建的句子边界检测算法。

如果需要自定义句子拆分器，可以用下列的方式训练自己的句子拆分器：

```python
>>>import nltk.tokenize.punkt
>>>tokenizer =nltk.tokenize.punkt.PunktSentenceTokenizer(text)
```

### 分词

```python
# word tokenizer
>>>s ="Hi Everyone !    hola gr8" # simplest tokenizer
>>>print s.split()

>>>from nltk.tokenize import word_tokenize
>>>word_tokenize(s)

>>>from nltk.tokenize import regexp_tokenize, wordpunct_tokenize, blankline_tokenize
>>>regexp_tokenize(s, pattern='\w+')

>>>regexp_tokenize(s, pattern='\d+')

>>>wordpunct_tokenize(s)
>>>blankline_tokenize(s)
```

NLTK有两个最常用的分词器，`word_tokenize`是一种通用和健壮的分词方法，在大部分情况下都可以正常使用。另一个是`regexp_tokenize`，是相对自定义的分词器，可以满足用户的特定需求。大多数分词器派生自`regexp_tokenize`。

### 词干提取

词干提取(Stemming)表示将树的分支削减得到主干的过程。使用一些基本规则可以有效地将任何token进行削减，得到其主干。词干提取是基于规则、相对原始的处理，通过这个处理，可以将token的不同变体集合起来。例如，eat具有eating, eaten, eats等不同变体。在某些应用中，在eat和eaten之间作出区分是没有意义的，因此使用词干提取将两个经过语法变型的单词归结到单词的根。

```python
#Porter stemmer
>>>from nltk.stem import PorterStemmer # import Porter stemmer
>>>from nltk.stem.lancaster import LancasterStemmer
>>>from nltk.stem.Snowball import SnowballStemmer
>>>pst=PorterStemmer()   # create obj of the PorterStemmer
>>>lst = LancasterStemmer() # create obj of LancasterStemmer
>>>lst.stem("eating")
eat
>>>pst.stem("shopping")
shop
```

使用基本的词干提取器，如消除-s/es或-ing或-ed，可以达到70%以上的精度，而波特(Porter)词干提取器使用了更多的规则，获得了更高的准确率。

在英语上，使用波特词干提取器就足够了。

有一系列的Snowball词干提取器可以适用于荷兰语、英语、法语、德语、意大利语、葡萄牙语、罗马尼亚语、俄语等。

是否使用词干提取器通常取决于应用和领域。如果希望使用一些NLP标注器，如词性标注器(POST)、NER或依存解析器，由于词干提取将会修改token而导致不同的结果，因此应该避免使用词干提取。

### 词形还原

词形还原（lemmatization）转换单词词根的所有语法/折叠形式。

词形还原使用上下文和词性，确定单词的折叠形式，根据每个单词的词性，应用不同的标准化规则，得到词根单元（词元）。

```python
#Lemmatizer
>>>from nltk.stem import WordNetLemmatizer
>>>wlem=WordNetLemmatizer()
>>>wlem.lemmatize("ate")
eat
```

WordNetLemmatizer方法接受一个单词，在语义词典wordnet中搜索这个单词。这种方法还使用形态分析，将单词削减到词根，搜素特定词元（单词的变体）。

这里如果使用词干提取是得不到eat的。

**词干提取和词形还原之间的区别**

词干提取更多地使用基于规则的方法，获得单词语法形式的词根。但是词形还原同时考虑了给定单词的上下文和词性，然后应用语法变体的特定规则。词干提取器更容易实现，其处理速度也比词形还原器更快。

### 停用词删除

移除在语料库的所有文档中通常都会出现的一些单词。

```python
# stop word 

>>>from nltk.corpus import stopwords
>>>stoplist=stopwords.words('english') # config the language name
>>>text = "This is just a test"
>>>cleanwordlist=[word for word in text.split() if word not in stoplist]
```

`stopwords.fileids()`可以看到所有语言的停用词列表。

### 生僻字删除

一些单词，如名称、品牌、产品名称以及一些嘈杂的字符（如在处理HTML时剩下的一些遗漏字符），在性质上非常独特，因此根据不同的NLP任务，这些单词或字符也要删除。

也可以使用单词的长度作为标准，删除非常短或非常长的单词。

```python
# rare word removal 

>>>freq_dist=nltk.FreqDist(token)
>>>rarewords =freq_dist.keys()[-50:]
>>>after_rare_words= [ word for word in token not in rarewords]
```

使用FreqDist()函数，获得了语料库中术语的频率分布，选择最生僻的术语并删除。

### 拼写校正

可以使用字典查找创建一个非常基本的拼写检查器。

```python
# spell check

>>>from nltk.metrics import edit_distance
>>>edit_distance(“rain”,”shine”)
3
```

关于拼写检查，可以访问Norvig网站了解更多信息。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codingling.gitbook.io/study/basic-know/yu-chu-li/12-wen-ben-yu-chu-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
