第三章(4):自然语言处理入门
在本节中,我们将在简单文本数据上(例如一个句子上),执行一系列基本操作,来帮助你熟悉NLP的工作原理,其中一些技术在第三章(2):深入理解NTLK库基本使用方法_安静到无声的博客-CSDN博客和第三章(3):深入理解Spacy库基本使用方法_安静到无声的博客-CSDN博客两个章节有所提及。但是,本节将系统性地阐述NLP基本操作,以帮助读者获得更深入的理解。主要内容包括:正则表达式进行文本搜索、将文本转换为列表、文本预处理、移除停止词、计数向量化和TF-IDF分数等,(ง •_•)ง。
如果感觉有用,
不妨给博主来个一键三连,白天科研,深夜肝文,实属不易~ ~
拜托了!
文章目录
- 第三章(4):自然语言处理入门
- 前言
- 1 正则表达式进行文本搜索
- 2 将文本转换为列表
- 3 文本预处理
- 3.1 替换单词
- 3.2 删除特定类型的单词
- 3.3 添加特定类型的单词
- 4. 移除停止词
- 5 计数向量化
- 6 TF-IDF分数
- 7. 总结
前言
在本节中,我们将在简单文本数据上(例如一个句子上),执行一系列基本操作,来帮助你熟悉NLP的工作原理,其中一些技术在第三章(2):深入理解NTLK库基本使用方法_安静到无声的博客-CSDN博客和第三章(3):深入理解Spacy库基本使用方法_安静到无声的博客-CSDN博客两个章节有所提及。但是,本节将系统性地阐述NLP基本操作,以帮助读者获得更深入的理解。主要内容包括:正则表达式进行文本搜索、将文本转换为列表、文本预处理、移除停止词、计数向量化和TF-IDF分数等。
1 正则表达式进行文本搜索
正则表达式是一种非常有用的方法,用于从给定的文本中搜索特点类型的设计或字集。正则表达式(RE)指定一组与其匹配的字符串,此模块中的函数允许检查给定字符串是否与特定的RE匹配。
可以使用Python内置的re模块来实现正则表达式进行文本搜索,具体可以参考Python官方文档中关于re模块的说明。
一般情况下,使用re模块进行正则表达式文本搜索需要以下步骤:
-
导入re模块:
import re
-
定义要匹配的模式:
pattern = r'text'
。其中,r表示字符串为原始字符串,防止出现转义问题;text是你要搜索的文本。 -
使用re.search()函数进行搜索:
match = re.search(pattern, text)
。search()函数会在text中查找第一个匹配的pattern,并返回一个match对象,如果没有匹配,则返回None。 -
对搜索结果进行处理:如果match不是None,则可以通过match.group()方法获取到匹配的文本内容。
下面是一个简单的示例:
text = 'This is a sample text for regex search in Python.'
pattern = r'text'
match = re.search(pattern, text)
if match:
print('Matched:', match.group())
else:
print('No match found.')
实验结果:
Matched: text
2 将文本转换为列表
可以读取一个文本文件并根据需要将它转化为一列单词或者一列句子。示例如下:
有一文本data.txt
内容如下:
The experimental results validated our approach, showing that GRIT outperforms all published methods by a large margin in inference accuracy and speed.
(1)将文本文件转换为一列单词的步骤如下:
-
打开文本文件并读取所有内容:
with open('filename.txt', 'r') as f: text = f.read()
-
使用字符串的split()方法将文本分割成单词:
words_list = text.split()
-
将单词列表返回或进行进一步操作。
with open('filename.txt', 'r') as f:
text = f.read()
words_list = text.split()
print(words_list)
实验结果:
['The', 'experimental', 'results', 'validated', 'our', 'approach,', 'showing', 'that', 'GRIT', 'outperforms', 'all', 'published', 'methods', 'by', 'a', 'large', 'margin', 'in', 'inference', 'accuracy', 'and', 'speed.']
(2)将文本文件转换为一列句子的步骤如下:
-
打开文本文件并读取所有内容:
with open('filename.txt', 'r') as f: text = f.read()
-
使用字符串的splitlines()方法将文本分割成句子:
sentences_list = text.splitlines()
-
将句子列表返回或进行进一步操作。
下面是一个简单的示例代码:
with open('filename.txt', 'r') as f:
text = f.read()
sentences_list = text.splitlines()
print(sentences_list)
实验结果:
['The experimental results validated our approach, showing that GRIT outperforms all published methods by a large margin in inference accuracy and speed.']
3 文本预处理
可以用很多方式对文本进行预处理,例如,将一个单词替换为另一个单词,删除或添加某些特定类型的单词等。
在 Python 中,可以使用字符串的内置函数和正则表达式来实现对单词的替换、删除或添加等操作。
3.1 替换单词
可以使用 str.replace()
函数来替换单词,它接受两个参数,第一个是要被替换的单词,第二个是替换后的单词。例如:
text = "Hello World"
new_text = text.replace("World", "Python")
print(new_text)
实验结果:
Hello Python
3.2 删除特定类型的单词
使用正则表达式来匹配特定类型的单词,并使用 re.sub()
函数将其删除。例如,下面的代码删除了所有以元音字母开头的单词:
import re
text = "Apple banana cat dog elephant"
new_text = re.sub(r'\b[Ad]\w+\b', '', text)
print(new_text)
实验结果:
banana cat dog
在正则表达式中,\b
表示单词边界,\w
表示任意字母数字字符,+
表示匹配重复多次,即匹配一个或多个字母数字字符。
3.3 添加特定类型的单词
可以使用正则表达式和 re.sub()
函数来添加特定类型的单词。例如,下面的代码在每个单词之后添加了一个感叹号
import re
text = "Hello World"
new_text = re.sub(r'\b(\w+)\b', r'\1!', text)
print(new_text)
实验结果:
Hello! World!
在正则表达式中,(\w+)
表示匹配一个或多个字母数字字符,并将其分组,然后在替换中使用 \1
来引用该分组。最终结果是,在每个单词之后添加了一个感叹号。
4. 移除停止词
在自然语言处理中,停用词(Stop Words)是指在文本中使用频率很高,但却没有实际含义的常见单词,如“the”、“a”、“an”、“in”、“of”等。这些单词通常被删除或剔除,以便更好地理解和分析文本。
示例如下:
import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')
text = "This is an example sentence to demonstrate stop word removal."
stop_words = set(stopwords.words('english'))
filtered_words = [word for word in text.split() if word.lower() not in stop_words]
filtered_text = ' '.join(filtered_words)
print("原始文本:", text)
print("过滤后的文本:", filtered_text)
实验结果:
原始文本: This is an example sentence to demonstrate stop word removal.
过滤后的文本: example sentence demonstrate stop word removal.
上面的代码首先下载了英文停用词表,然后将其存储在 stop_words
变量中。接着,使用列表推导式和 split()
函数将文本拆分为单词,并检查每个单词是否在停用词集合中出现,如果不出现则添加到新的列表中。最后,使用 join()
函数将过滤后的单词列表转换回字符串形式。可以看到,停用词 “This”,“is”,“an” 和 “to” 已经被成功地删除,只剩下有实际含义的单词。
5 计数向量化
计数向量化是一个Scikit-learn库工具,它可以接收大量文本数据,将每个独特的单词作为特征返回,并计算每个单词在文本中出现的次数。
示例如下:
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['This is the first document.',
'This is the second document.',
'And this is the third document.',
'Is this the first document?']
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
print(X.toarray())
实验结果:
['and', 'document', 'first', 'is', 'second', 'the', 'third', 'this']
[[0 1 1 1 0 1 0 1]
[0 1 0 1 1 1 0 1]
[1 1 0 1 0 1 1 1]
[0 1 1 1 0 1 0 1]]
以上代码首先定义了一个包含四个文本字符串的列表 corpus
,然后创建了一个 CountVectorizer
对象,并将其拟合到 corpus
数据上。最后,将 corpus
数据转换为计数矩阵格式并打印出结果。
可以看到,虽然 corpus
中包含了多个相同的单词,但由于计数向量化是基于每个文本单独处理的,因此这些单词在不同的文本中被分别计数。其中,第一个文本和最后一个文本中出现的单词一样,但它们在计数矩阵中的位置和值是不同的。另外,标点符号 “?
” 没有被计入矩阵中,因为默认情况下 CountVectorizer
类已经将它们移除。
6 TF-IDF分数
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。
例子:词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个,而词语“母牛”出现了3次,那么“母牛”一词在该文件中的词频就是3/100=0.03。一个计算文件频率 (IDF) 的方法是文件集里包含的文件总数除以测定有多少份文件出现过“母牛”一词。所以,如果“母牛”一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是 lg(10,000,000 / 1,000)=4。最后的TF-IDF的分数为0.03 * 4=0.12。
代码示例:
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
'This is the first document.',
'This is the second document.',
'And this is the third one.',
'Is this the first document?',
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
print(X.toarray())
实验结果:
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
[[0. 0.46979139 0.58028582 0.38408524 0. 0.
0.38408524 0. 0.38408524]
[0. 0.42796959 0. 0.34989318 0. 0.67049706
0.34989318 0. 0.34989318]
[0.51184851 0. 0. 0.26710379 0.51184851 0.
0.26710379 0.51184851 0.26710379]
[0. 0.46979139 0.58028582 0.38408524 0. 0.
0.38408524 0. 0.38408524]]
以上代码首先定义了一个包含四个文本字符串的列表 corpus
。然后,创建了一个 TfidfVectorizer
对象,并将其拟合到 corpus
数据上。最后,将 corpus
数据转换为稀疏矩阵格式并打印出结果。
在结果中,第一行输出了经过处理的所有独特的单词作为特征的名称。第二行到第五行则分别表示了 corpus
中的每个文本在这些特征上的 TF-IDF 分数。
可以看到,与计数向量化不同,TF-IDF 分数考虑了每个单词的重要性,以及它们在整个语料库中出现的频率和特定文本中出现的频率。对于常见的单词如 “this” 和 “is”,它们在 TF-IDF 分数中的权重比较低,而对于较少出现但是在文本中有较大作用的单词,它们在 TF-IDF 分数中的权重相对较高。由此,TF-IDF 分数可以更好地反映单词的重要性和区分能力。
7. 总结
本节系统性地阐述NLP基本操作,以帮助读者获得更深入的理解。主要内容包括:正则表达式进行文本搜索、将文本转换为列表、文本预处理、移除停止词、计数向量化和TF-IDF分数等。
参考
tf-idf_百度百科 (baidu.com)