本文主要参考Coursera上 国立高等经济大学的自然语言处理课程 和 吴恩达老师的的机器学习课程。
one-hot
one-hot 可以说是机器学习领域最常见的数据表示形式了。
实例
假设我们的语料库如下:
荣荣爱玩游戏
垃圾该分类了
我爱自然语言处理
经过 tokenization 化之后得到如下的 vocabulary
字典
{
"荣荣": 0,
"爱": 1,
"玩游戏": 2,
"垃圾": 3,
"分类": 4,
"我": 5,
"自然语言处理": 6
}
其中,
了
和该
已被当做 停止词 去掉。
将上述的词转化为 one-hot 形式如下:
"我": [0, 0, 0, 0, 1, 0]
"爱": [0, 1, 0, 0, 0, 0]
"自然语言处理": [0, 0, 0, 0, 0, 1]
向量的长度为词汇量的大小。
简单的流程
那么自然语言处理领域该怎么用 one-hot 呢?
流程如下所示:
- 创建两个个字典变量
vocabulary
,reverse_vocabulary
; - 将文本tokenization化(参考我第一篇文章自然语言处理之文本预处理(一)),得到token;
- 得到以下形式的词汇表
vocabulary[token] = n
和reverse_vocabulary[n] = token
,其中n
为该词出现的顺序; - 最终得到
vocabulary
字典为word -> index
的映射;reverse_vocabulary
为index -> word
的映射; - 利用这两个字典,将数据转换成 one-hot 的形式
面临的问题:
- 数据量太大,一台服务器保存不下这个字典,怎么办?
- 想多台服务器并行计算怎么同步(CAP理论)?
此处仅提出了这两个问题,不进行深入讨论。
BoW(Bag of Words)
我们已经可以使用 one-hot 形式来表示词了,那么 该怎么表示一个句子 呢?
还是以 上述内容为例,对于 我爱自然语言处理
这句话 tokenization 化之后得到了三个 one-hot 形式表示的词;将这三个词的向量进行垂直方向堆叠起来就可以当做这句话的向量表示。
如下:
text: 我爱自然语言处理
vector: [0, 1, 0, 0, 0, 0, 1, 1]
那么,如果有的词不在 vocabulary
字典中呢?(可以采取直接跳过的方式来处理)
text: 我喜欢自然语言处理
vector: [0, 0, 0, 0, 0, 0, 1, 1]
该模型有两个主要问题如下:
- 正如这个模型的名字一样,该模型无法表示 词在句子中出现的顺序;
- 所有出现过的词全都为
1
。
n-gram
为了解决问题一(仅完善了一点,没有实际上解决),提出了 n-gram
的方法。
该方法将 连续的 n
个 token 组合在一起,继续拿上述例子:
荣荣爱玩游戏
垃圾该分类了
我爱自然语言处理
此时,tokeization 化之后结果为:
{
"荣荣": 0,
"荣荣爱": 1,
"爱": 2,
"爱玩游戏": 3,
"玩游戏": 4,
"垃圾": 5,
"分类": 6,
"我": 7,
"我爱": 8,
"爱自然语言处理": 9,
"自然语言处理": 10
}
此时,BoW 表示如下:
text: 我爱自然语言处理
vector: [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1]
可以看到当
n
增大的时候,得到的稀疏矩阵将会指数级增长,所以一般情况下,n
只取2-3
当然,对于 n-gram
形式表示的 token 中会有好多 token 经常出现,也有好多只出现过几次,这些都可以去掉来减少向量的维度。
tf-idf
那么怎么解决问题二呢?
tf-idf 是一个很好的解决办法,tf-idf此处就不多加讲解了,不了解的人可以参考阮一峰老师的文章
如何将 tf-idf 应用到 BoW 中来呢?
其实只需要将向量中原本为 1
的值,替换为 tf-idf 的值即可。
text: 我爱自然语言处理
vector: [0, 0, 0, 0, 0, 0, 0, 0, 0.43, 0, 0.43]
上述
vector
中的值不是真实的 tf-idf 值。
python tf-idf example
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
texts = [
"good movie",
"not a good movie",
"did not like",
"i like it",
"good one"
]
tfidf = TfidfVectorizer(min_df=2, max_df=0.5, ngram_range=(1, 2))
features = tfidf.fit_transform(texts)
f = pd.DataFrame(features.todense(), columns=tfidf.get_feature_names())
print(f)
'''
good movie like movie not
0 0.707107 0.000000 0.707107 0.000000
1 0.577350 0.000000 0.577350 0.577350
2 0.000000 0.707107 0.000000 0.707107
3 0.000000 1.000000 0.000000 0.000000
4 0.000000 0.000000 0.000000 0.000000
'''
其中:
- min_df, max_df: 移除低频和高频(停止词)出现的 grams
如果参数的值为 float(0.0 - 1.0)则代表比值; 如果是 int 类型, 则代表出现的次数
- ngram_range: 上文提到的 n-gram, 此处保留 1 个和 2 个
总结
本文讲解了自然语言处理(机器学习)中常用的 BoW 模型及其其他形式,读者可以自行使用两种方式来分别实验后选择合适的模型。
下一篇文章将会继续介绍 深度学习中常用的文本表示模型
- word2vec
参考链接
如何系统的去学习大模型LLM ?
大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业
?”“谁的饭碗又将不保了?
”等问题热议不断。
不如成为「掌握AI工具的技术人
」,毕竟AI时代,谁先尝试,谁就能占得先机!
但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高
针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料
分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓
👉[CSDN大礼包🎁:全网最全《LLM大模型入门+进阶学习资源包》免费分享(安全链接,放心点击)]()👈