使用 Python 进行自然语言处理第 4 部分:文本表示

news2024/11/28 11:46:17

一、说明

        本文是在 2023 年 3 月为 WomenWhoCode 数据科学跟踪活动发表的系列文章中。早期的文章位于:第 1 部分(涵盖 NLP 简介)、第 2 部分(涵盖 NLTK 和 SpaCy 库)、第 2 部分(涵盖NLTK和SpaCy库)3(涵盖文本预处理技术)

二、文本表示

  • 文本数据以字母、单词、符号、数字或所有这些的集合的形式存在。例如“印度”、“、”、“Covid19”等。
  • 在我们将机器学习/深度学习算法应用于文本数据之前,我们必须以数字形式表示文本。单个单词和文本文档都可以转换为浮点数向量。
  • 将标记、句子表示为数值向量的过程称为“嵌入”,这些向量的多维空间称为嵌入空间。
  • 循环神经网络、长短期记忆网络、变形金刚等深度神经网络架构需要以固定维数值向量的形式输入文本。

2.1 一些术语:

  1. 文档:文档是许多单词的集合。
  2. 词汇:词汇是文档中唯一单词的集合。
  3. Token:Token是离散数据的基本单位。它通常指单个单词或标点符号。
  4. 语料库:语料库是文档的集合。
  5. 上下文:单词/标记的上下文是文档中左右围绕该单词/标记的单词/标记。
  6. 向量嵌入:基于向量的文本数字表示称为嵌入。例如,word2vec 或 GLoVE 是基于语料库统计的无监督方法。像tensorflow和keras这样的框架支持“嵌入层”。

2.2 文本表示应具有以下属性:

  1. 它应该唯一地标识一个单词(必须是双射)
  2. 应捕捉单词之间的形态、句法和语义相似性。相关词在欧德空间中应该比不相关词更接近出现。
  3. 这些表示应该可以进行算术运算。
  4. 通过表示,计算单词相似性和关系等任务应该很容易。
  5. 应该很容易从单词映射到其嵌入,反之亦然。

2.3 文本表示的一些突出技术:

  1. 一次性编码
  2. 词袋模型 — CountVectorizer 和带有 n 元语法的 CountVectorizer
  3. Tf-Idf模型
  4. Word2Vec 嵌入
  5. 手套包埋
  6. 快速文本嵌入
  7. ChatGPT 和 BERT 等 Transformer 使用自己的动态嵌入。

一热编码:

        这是将文本表示为数值向量的最简单技术。每个单词都表示为由 0 和 1 组成的唯一“One-Hot”二进制向量。对于词汇表中的每个唯一单词,向量包含一个 1,其余所有值为 0,向量中 1 的位置唯一标识一个单词。

例子:

        单词 Apple、Banana、Orange 和 Mango 的 OneHot 向量示例

from sklearn.preprocessing import OneHotEncoder
import nltk
from nltk import word_tokenize
document = "The rose is red. The violet is blue."
document = document.split()
tokens = [doc.split(" ") for doc in document]

wordids = {token: idx for idx, token in enumerate(set(document))}
tokenids = [[wordids[token] for token in toke] for toke in tokens]

onehotmodel = OneHotEncoder()
vectors = onehotmodel.fit_transform(tokenids)
print(vectors.todense())

2.4 词袋表示:CountVectorizer

        请参阅此处的详细信息:https ://en.wikipedia.org/wiki/Bag-of-words_model

        词袋 (BoW) 是一种无序的文本表示形式,用于描述文档中单词的出现情况。它具有文档中已知单词的词汇表以及已知单词存在的度量。词袋模型不包含有关文档中单词的顺序或结构的任何信息。

维基百科的例子:

文档1:约翰喜欢看电影。玛丽也喜欢电影。

文件2:玛丽也喜欢看足球比赛。

词汇1:“约翰”、“喜欢”、“去”、“看”、“电影”、“玛丽”、“喜欢”、“电影”、“太”

词汇2:“玛丽”、“也”、“喜欢”、“去”、“看”、“足球”、“游戏”

BoW1 = {“约翰”:1,“喜欢”:2,“观看”:1,“观看”:1,“电影”:2,“玛丽”:1,“太”:1};

BoW2 = {“玛丽”:1,“也”:1,“喜欢”:1,“到”:1,“观看”:1,“足球”:1,“游戏”:1};

Document3 是 document1 和 document2 的并集(包含文档 1 和文档 2 中的单词)

文件3:约翰喜欢看电影。玛丽也喜欢电影。玛丽还喜欢看足球比赛。

BoW3: {“约翰”:1、“喜欢”:3、“观看”:2、“观看”:2、“电影”:2、“玛丽”:2、“太”:1、“也”:1 ,“足球”:1,“游戏”:1}

让我们编写一个函数来在用向量表示文本之前对其进行预处理。

# This process_text() function returns list of cleaned tokens of the text
import numpy
import re
import string
import unicodedata
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
stop_words = stopwords.words('english')
lemmatizer = WordNetLemmatizer()

def process_text(text):
    # Remove non-ASCII characters
    text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8', 'ignore')
    # Remove words not starting with alphabets
    text = re.sub(r'[^a-zA-Z\s]', '', text)
    # Remove punctuation marks
    text = text.translate(str.maketrans('', '', string.punctuation))
    #Convert to lower case
    text = text.lower()
    # Remove stopwords
    text = " ".join([word for word in str(text).split() if word not in stop_words])
    # Lemmatize
    text = " ".join([lemmatizer.lemmatize(word) for word in text.split()])
    return text

接下来,我们使用 Sklearn 库中的 CountVectorizer 将预处理后的文本转换为词袋表示。

#https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html
#https://stackoverflow.com/questions/27697766/understanding-min-df-and-max-df-in-scikit-countvectorizer
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
import nltk
document = ["The", "rose", "is", "red", "The",  "violet", "is", "blue"] #, "This is some text, just for demonstration"]

processed_document = [process_text(item) for item in document]
processed_document = [x for x in processed_document if x != '']
print(processed_document)

bow_countvect = CountVectorizer(min_df = 0., max_df = 1.)

matrix = bow_countvect.fit_transform(processed_document)
matrix.toarray()
vocabulary = bow_countvect.get_feature_names_out()
print(matrix)
matrix.todense()

2.5 词袋表示:n-grams

        Simpe Bag-of-words 模型不存储有关单词顺序的信息。n-gram 模型可以存储这些空间信息。

        单词/标记被称为“gram”。n-gram 是出现在文本文档中的一组连续的 n-token。
一元词表示 1 个单词,二元词表示两个词,三元词表示一组 3 个词……

        例如对于文本(来自维基百科):

        文档1:约翰喜欢看电影。玛丽也喜欢电影。

        二元模型将文本解析为以下单元,并像简单的 BoW 模型一样存储每个单元的术语频率。

        [“约翰喜欢”、“喜欢”、“看”、“看电影”、“玛丽喜欢”、“喜欢电影”、“也看电影”,]

Bag-of-word 模型可以被认为是 n-gram 模型的特例,其中 n=1

#https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html
from sklearn.feature_extraction.text import CountVectorizer

document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]
ngram_countvect = CountVectorizer(ngram_range = (2, 2), stop_words = 'english')
#ngram_range paramenter to count vectorizer indicates the lower and upper boundary of the range of n-values for 
#different word n-grams or char n-grams to be extracted. All values of n such such that min_n <= n <= max_n will be used. 
#For example an ngram_range of (1, 1) means only unigrams, (1, 2) means unigrams and bigrams, and (2, 2) means only bigrams.

matrix = ngram_countvect.fit_transform(document)
vocabulary = ngram_countvect.get_feature_names_out()
matrix.todense()

三、Tf-Idf 矢量化器:术语频率 — 逆文档频率

可以在这里找到 TF-IDF 矢量器的非常好的解释

  • 文档“d”中术语/单词“w”的 Tf-Idf 分数 tfidf(w,D) 是两个指标的乘积:术语频率 (tf) 和逆文档频率 (idf)。即 tfidf(w, d, C) = tf(w,d)*idf(w,d,C)
  • 其中w是术语或单词,d是文档,C是包含总共N个文档(包括文档d)的语料库。
  • 词频 tf(w,d) 是文档 d 中单词 w 的频率。术语频率可以根据文档的长度进行调整(出现的原始计数除以文档中的单词数),它可以是对数缩放频率(例如 log(1 + 原始计数)),也可以是布尔频率(例如,如果该术语在文档中出现,则为 1;如果该术语在文档中未出现,则为 0)。
  • 文档频率:是一个术语/单词 w 在一组 N 个文档(语料库)中出现的频率。逆文档频率是衡量一个词在语料库中的常见或罕见程度的指标。更少的是 IDF,更常见的是这个词,反之亦然。单词的 IDF 是通过将语料库中的文档总数除以包含该单词的文档数量的对数来计算的。逆文档频率是术语/单词信息量的度量。频繁出现的单词信息量较少。单词的逆文档频率是在一组文档(语料库)中计算的。
from sklearn.feature_extraction.text import TfidfVectorizer

document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]

tf_idf = TfidfVectorizer(min_df = 0., max_df = 1., use_idf = True)
tf_idf_matrix = tf_idf.fit_transform(document)
tf_idf_matrix = tf_idf_matrix.toarray()
tf_idf_matrix

四、词嵌入

上述文本表示方法通常不能捕获单词的语义和上下文。为了克服这些限制,我们使用嵌入。嵌入是通过训练庞大数据集的模型来学习的。这些嵌入通过考虑句子中的相邻单词以及句子中单词的顺序来捕获单词的上下文。三个著名的词嵌入是:Word2Vec、GloVe、FastText

词向量

  • 是一个在巨大文本语料库上训练的无监督模型。它创建单词的词汇表以及表示词汇表的向量空间中单词的分布式连续密集向量表示。它捕获上下文和语义的相似性。
  • 我们可以指定词嵌入向量的大小。向量总数本质上就是词汇表的大小。
  • Word2Vec中有两种不同的模型架构类型——CBOW(连续词袋)模型、Skip Gram模型

CBOW 模型 - 尝试根据源上下文单词预测当前目标单词。Skip Gram 模型尝试预测给定目标单词的源上下文单词。

from gensim.models import word2vec
import nltk
document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]

tokenized_corpus = [nltk.word_tokenize(doc) for doc in document]
#parameters of word2vec model
# feature_size : integer   :  Word vector dimensionality
# window_context : integer :  The maximum distance between the current and predicted word within a sentence.(2, 10)
# min_word_count : integer : Ignores all words with total absolute frequency lower than this - (2, 100)
# sample : integer  : The threshold for configuring which higher-frequency words are randomly downsampled. Highly influencial. - (0, 1e-5)
# sg: integer: Skip-gram model configuration, CBOW by default

wordtovector = word2vec.Word2Vec(tokenized_corpus,  window = 3, min_count = 1, sg = 1)
print('Embedding of the word blue')
print(wordtovector.wv['blue'])

print('Size of Embedding of the word blue')
print(wordtovector.wv['blue'].shape)

如果您希望查看词汇表中的所有向量,请使用以下代码:

#All the vectors for all the words in our input text
words = wordtovector.wv.index_to_key
wvs = wordtovector.wv[words]
wvs

或者将它们转换为 pandas 数据框

import pandas as pd
df = pd.DataFrame(wvs, index = words)
df

五、GloVe库(手套)

  • 全局向量 (GloVe) 是一种为 Word2Vec 等单词生成密集向量表示的技术。它首先创建一个由(单词,上下文)对组成的巨大的单词-上下文共现矩阵。该矩阵中的每个元素代表上下文中单词的频率。可以应用矩阵分解技术来近似该矩阵。由于 Glove 是在 globar 词-词共现矩阵上进行训练的,因此它使我们能够拥有一个具有有意义的子结构的向量空间。
  • Spacy 库支持 GloVe 嵌入。为了使用英语嵌入,我们需要下载管道“en_core_web_lg”,这是大型英语语言管道。我们使用 SpaCy 得到标准的 300 维 GloVe 词向量。
import spacy
import nltk

nlp = spacy.load('en_core_web_lg')

total_vectors = len(nlp.vocab.vectors)
print('Total word vectors:', total_vectors)

document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]
tokenized_corpus = [nltk.word_tokenize(doc) for doc in document]

vocab = list(set([word for wordlist in tokenized_corpus for word in wordlist]))

glovevectors = np.array([nlp(word).vector for word in vocab])#Spacy's nlp pipeline has the vectors for these words
glove_vec_df = pd.DataFrame(glovevectors, index=vocab)
glove_vec_df

如果您想查看单词“violet”的手套向量,请使用代码

glove_vec_df.loc['violet']

希望查看所有词汇向量?

glovevectors

使用 TSNE 可视化数据点

from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
tsne = TSNE(n_components = 2, random_state = 42, n_iter = 250, perplexity = 3)
tsneglovemodel = tsne.fit_transform(glovevectors)
labels = vocab
plt.figure(figsize=(12, 6))
plt.scatter(tsneglovemodel[:, 0], tsneglovemodel[:, 1], c='red', edgecolors='r')
for label, x, y in zip(labels, tsneglovemodel[:, 0], tsneglovemodel[:, 1]):
plt.annotate(label, xy=(x+1, y+1), xytext=(0, 0), textcoords='offset points')

六 快速文本

        FastText 在 Wikipedia 和 Common Crawl 上进行了训练。它包含在 Wikipedia 和 Crawl 上训练的 157 种语言的词向量。它还包含语言识别和各种监督任务的模型。您可以在 gensim 库中试验 FastText 向量。

import warnings
warnings.filterwarnings("ignore")

from gensim.models.fasttext import FastText
import nltk
document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]
tokenized_corpus = [nltk.word_tokenize(doc) for doc in document]

fasttext_model = FastText(tokenized_corpus, window = 5, min_count = 1, sg = 1)
import warnings
warnings.filterwarnings("ignore")

from gensim.models.fasttext import FastText
import nltk
document = ["The rose is red.", "The violet is blue.", "This is some text, just for demonstration"]
tokenized_corpus = [nltk.word_tokenize(doc) for doc in document]

fasttext_model = FastText(tokenized_corpus, window = 5, min_count = 1, sg = 1)

print('Embedding')
print(fasttext_model.wv['blue'])

print('Embedding Shape')
print(fasttext_model.wv['blue'].shape)

        要查看词汇表中单词的向量,您可以使用此代码

words_fasttext = fasttext_model.wv.index_to_key
wordvectors_fasttext = fasttext_model.wv[words]
wordvectors_fasttext

        在本系列的下一篇文章中,我们将介绍文本分类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1166495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

32 mysql in 的实现

前言 这里我们主要是来探讨一下 mysql 中 in 的使用, find_in_set 的使用 这两者 在我们实际应用中应该也是 非常常用的了 测试数据表如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(16) DEFAULT NULL,field2 varchar(16) DEFAU…

ElasticSearch集群架构实战及其原理剖析

ES集群架构 为什么要使用ES集群架构 分布式系统的可用性与扩展性&#xff1a; 高可用性 服务可用性&#xff1a;允许有节点停止服务&#xff1b;数据可用性&#xff1a;部分节点丢失&#xff0c;不会丢失数据&#xff1b; 可扩展性 请求量提升/数据的不断增长(将数据分布…

1688商品评论API接口(评论内容|日期|买家昵称|追评内容|评论图片|评论视频..)

一般来说&#xff0c;1688商品评论API接口可以用于获取1688平台上商品评论的数据。通过该接口&#xff0c;您可以获取到商品评论的详细信息&#xff0c;包括评论内容、评论时间、评论者信息等。 要使用1688商品评论API接口&#xff0c;您需要完成以下步骤&#xff1a; 在1688…

MySQL BinLog实战应用之二

一、前言 上篇 MySQL Binlog实战应用之一 主要讲了BinLog的开启以及用MySQLBinLog读取BigLog二进制文件&#xff0c;但MySQLBinLog很难直接对接Java&#xff0c;所以有了Canal这个Alibaba开发的用于MySQL增量日志解析&#xff0c;提供增量数据的订阅和消费组件。 二、Canal原…

117. 填充每个节点的下一个右侧节点指针 II : 详细图解 O(1) 空间构建过程

题目描述 这是 LeetCode 上的 「117. 填充每个节点的下一个右侧节点指针 II」 &#xff0c;难度为 「中等」。 Tag : 「BFS」、「链表」 给定一个二叉树&#xff1a; struct Node { int val; Node *left; Node *right; Node *next;} 填充它的每个 next 指针&#xff0c;让这…

【256MB+256MB】起,含税低至88元!飞凌嵌入式FET113i-S全国产核心板上市

超低价、超灵活、超全能&#xff01;飞凌嵌入式FET113i-S全国产核心板正式发布&#xff01;整板采用100%国产工业级元器件&#xff0c;含税价最低仅需88元&#xff01; FET113i-S核心板基于全志T113-i工业级处理器开发设计&#xff0c;主频1.2GHz&#xff0c;配备多核多架构&a…

2023 冬季波卡黑客松先导预告:三大赛题、30 万美金奖赏 Web3 探险者!

用「熊市」形容 2023 年的 web3 行业似乎并不准确。狂热之后的巨头暴雷、黑客攻击和投资锐减并未使 web3 发展停滞。比特币 ETF 进展引人瞩目&#xff0c;新的技术进展、新的 web3 物种也正在出现&#xff0c;而 AI 等技术的发展也在为 web3 应用带来新的想象力。2023 或许又是…

微信小程序-form表单-获取用户输入文本框的值

微信小程序-form表单-获取用户输入文本框的值 data: {userName: ,userPwd:""},//获取用户输入的用户名 userNameInput:function(e) {this.setData({userName: e.detail.value}) }, passWdInput:function(e) {this.setData({userPwd: e.detail.value}) }, //获取用户输…

Nacos本地修改编译源码2.2.3

下载Nacos源码 由于github访问速度慢&#xff0c;所以在gitee上下载 git clone https://gitee.com/mirrors/Nacos.git切换2.2.3版本 git checkout 2.2.3或者直接下载2.2.3的源码 本地编译 源码导入idea&#xff0c;然后编译 mvn -Dmaven.test.skiptrue -Drat.skiptrue c…

电力/税务单位宣传稿考核,投稿报纸怎么做

在当今信息传播的多元化时代&#xff0c;纸质媒体仍然是企业、机关事业单位宣传的重要平台。不管的本地报纸&#xff0c;还是省级报纸或国家级报纸、网媒&#xff0c;可能都有考核要求。 要在报纸上发表文稿&#xff0c;一般需要以下步骤&#xff1a; 1、选择合适的报纸&#x…

用斐波那契分解正整数

https://vjudge.net/contest/591700#problem/C 观察这个形式&#xff0c;如果交替做&#xff0c;就是个斐波那契数列 打表可得&#xff0c;任何正整数都可以大约由 log ⁡ \log log 个斐波那契数加起来 然后直接拼斐波那契数即可 #include<bits/stdc.h> using namesp…

REF615C-D HCFFAEAGABC2BAA1XD 一体化工业解决方案

REF615C-D HCFFAEAGABC2BAA1XD 一体化工业解决方案 Crimson Control使客户能够使用IEC 61131编程语言——如梯形逻辑、功能块、结构化文本和指令列表——通过开发类似可编程逻辑控制器(PLC)或远程遥测单元(RTU)的逻辑控制来解决特定的应用需求&#xff0c;而无需额外的费用。该…

TikTok小企业营销:崭露头角的新机遇

在数字时代&#xff0c;社交媒体已经成为推广和营销的强大工具。其中&#xff0c;TikTok以其独特的短视频内容和庞大的用户基础&#xff0c;为小企业提供了前所未有的营销机会。本文将深入探讨TikTok小企业的崛起&#xff0c;以及它所带来的新机会和挑战。 TikTok&#xff1a;数…

新建Git仓库后!如何将本地项目直接推送上到git仓库中的详细教程!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Git新建仓库二、来到你的本地仓库 前言 我们在git新建仓库后&#xff0c;如何直接在本地的项目文件夹中直接推送到git仓库中呢&#xff01;那么下面是详细…

QT6/5无痛安装和扩展,新手专用

QT6安装教程 注意在QT5.14.2以后版本只支持在线安装&#xff0c;所以如果需要离线exe版本&#xff0c;请安装5.14.2版本。这里是基于6.5版本Windows10的安装 如果觉得有用的话&#xff0c;请给个点赞收藏 1、安装链接 官方链接 qt官方链接&#xff1a;https://download.qt.io…

Angular异步数据流编程

1 目前常见的异步编程的几种方法 首先给出一个异步请求的实例&#xff1a; import {Injectable} from angular/core;Injectable({providedIn: root }) export class RequestServiceService {constructor() {}getData() {setTimeout(() > {let res zhaoshuai-lcreturn res…

uniapp写一个计算器用于记账(微信小程序,APP)

提要&#xff1a;自己用uniapp写了一个记账小程序&#xff08;目前是小程序&#xff09;&#xff0c;写到计算器部分&#xff0c;在网上找了别人写的计算器&#xff0c;大多数逻辑都是最简单的&#xff0c;都不能满足一个记账计算器的基本逻辑。与其在网上找来找去&#xff0c;…

Okta 数据泄露暴露了员工的个人信息

Okta 警告近 5000 名员工&#xff0c;他们的个人信息在第三方供应商遭到破坏后泄露。 Okta 是一家位于旧金山的云身份和访问管理解决方案提供商&#xff0c;其单点登录 (SSO)、多重身份验证 (MFA) 和 API 访问管理服务被全球数千个组织使用。 该 数据泄露通知 警告称&#xf…

PS学习笔记合集

2.一些快捷键 一、放大快捷键 Ctrl&#xff1a;在画布中点击一次&#xff0c;即可放大一次&#xff0c;可多次点击。 CtrlShift&#xff1a;在画布中点击一次&#xff0c;即可放大到适合窗口大小。 CtrlAlt&#xff1a;在画布中点击一次&#xff0c;即可放大到适合窗口大小&a…

Leetcode刷题详解——二叉树的所有路径

1. 题目链接&#xff1a;257. 二叉树的所有路径 2. 题目描述&#xff1a; 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5]…