【大模型基础】P1 N-Gram 模型

2024-09-08 04:20
文章标签 基础 模型 gram p1

本文主要是介绍【大模型基础】P1 N-Gram 模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • N-Gram 概述
  • N-Gram 构建过程
  • Token
  • N-Gram 实例
    • 第1步 构建实验语料库
    • 第2步 把句子分成 N 个 “Gram”
    • 第3步 计算每个 Bigram 在语料库中的词频
    • 第4步 计算出现的概率
    • 第5步 生成下一个词
    • 第6步:输入前缀,生成连续文本
  • 上述实例完整代码
  • N-Gram 的局限性

N-Gram 概述

N-Gram 诞生于统计学 NLP 初期,为解决词序列冗长导致的高复杂性概率计算。其通过分割文本为连续 N 个词的组合,来预测下一个词。

e . g . e.g. e.g. 我喜欢大模型
根据分词结果,文本中有三个词:“我”、“喜欢”、“大模型”

  • N=1,组合成一元组(Unigram):“我”、“喜欢”、“大模型”
  • N=2,组合成二元组(Bigram):“我喜欢”、“喜欢大模型”
  • N=3,组合成三元组(Trigram):“我喜欢大模型”

N-Gram 构建过程

第一步:分割文本为连续 N 个词的组合(N-Gram)

  • 以二元组(Bigram)为例,将语料库中文本进行分割。
  • e . g . e.g. e.g. 我爱吃香菜
    在这里插入图片描述

第二步:统计每个 N-Gram 在文本中出现的次数,即词频

  • 在语料库 ["我爱吃香菜", "我爱吃涮", "我爱吃汉堡", "我喜欢你", "我也爱吃水果"] 中,Bigram “我爱” 出现了 3 次。

第三步:计算下一个词出现的概率

  • 二元组 “我爱” 出现了 3 次,而其前缀 “我” 在语料库中出现了 5 次,则给定 “我” 为前缀时,下一个词为 “爱” 的概率为 60%

在这里插入图片描述

第四步:迭代上述过程,生成整段文本内容

在这里插入图片描述


Token

上述内容中,我们将文本 “我爱吃香菜” 分为了 4 个词。但是标准的说法,是分成了 4 个 Token。

在 NLP 中,

  • 英文分词方法通常使用 NLTK、spaCy 等自然语言处理库。
  • 中文分词则通常使用 jieba 库。
  • 在预训练模型在 BERT 中,使用 Tokenizer 库。

分词是预处理的一个重要环节,其他还包括文本清洗、去停用词、词干提取、词性标注等环节。


N-Gram 实例

整体流程一览图如下:

在这里插入图片描述

第1步 构建实验语料库

# 构建语料库
corpus = ["我喜欢吃苹果", "我喜欢吃香蕉", "她喜欢吃葡萄", "他不喜欢吃香蕉", "他喜欢吃苹果", "她喜欢吃草莓"]

第2步 把句子分成 N 个 “Gram”

import jiebadef generate_bigrams(corpus):bigram_list = []for sentence in corpus:# 使用jieba分词words = list(jieba.cut(sentence))bigrams = [(words[i] , words[i + 1]) for i in range(len(words) - 1)]bigram_list.extend(bigrams)return bigram_listbigrams = generate_bigrams(corpus)
print(bigrams)

结果:

[('我', '喜欢'), ('喜欢', '吃'), ('吃', '苹果'), ('我', '喜欢'), ('喜欢', '吃'), ('吃', '香蕉'), ('她', '喜欢'), ('喜欢', '吃'), ('吃', '葡萄'), ('他', '不'), ('不', '喜欢'), ('喜欢', '吃'), ('吃', '香蕉'), ('他', '喜欢'), ('喜欢', '吃'), ('吃', '苹果'), ('她', '喜欢'), ('喜欢', '吃'), ('吃', '草莓')]

第3步 计算每个 Bigram 在语料库中的词频

from collections import defaultdict, Counterdef count_bigrams(bigrams):# 创建字典存储biGram计数bigrams_count = defaultdict(Counter)for bigram in bigrams:prefix = bigram[:-1]token = bigram[-1]bigrams_count[prefix][token] += 1return bigrams_countbigrams_counts = count_bigrams(bigrams)
for prefix, counts in bigrams_counts.items():print("{}: {}".format("".join(prefix), dict(counts)))

结果:

: {'喜欢': 2}
喜欢: {'吃': 6}: {'苹果': 2, '香蕉': 2, '葡萄': 1, '草莓': 1}: {'喜欢': 2}: {'不': 1, '喜欢': 1}: {'喜欢': 1}

第4步 计算出现的概率

def bigram_probabilities(bigrams_count):bigrams_prob = defaultdict(Counter)for prefix, tokens_count in bigrams_count.items():total_count = sum(tokens_count.values())for token, count in tokens_count.items():bigrams_prob[prefix][token] = count / total_countreturn bigrams_probbigrams_prob = bigram_probabilities(bigrams_count)
for prefix, probs in bigrams_prob.items():print("{}: {}".format("".join(prefix), dict(probs)))

结果:

: {'喜欢': 1.0}
喜欢: {'吃': 1.0}: {'苹果': 0.3333333333333333, '香蕉': 0.3333333333333333, '葡萄': 0.16666666666666666, '草莓': 0.16666666666666666}: {'喜欢': 1.0}: {'不': 0.5, '喜欢': 0.5}: {'喜欢': 1.0}

第5步 生成下一个词

def generate_token(prefix, bigram_probs):if not prefix in bigram_probs:return Nonenext_token_probs = bigram_probs[prefix]next_token = max(next_token_probs, key=next_token_probs.get)return next_token

第6步:输入前缀,生成连续文本

def generate_text(prefix, bigram_probs, length=6):tokens = list(prefix)for _ in range(length - len(prefix)):next_token = generate_token(tuple(tokens[-1:]), bigram_probs)if not next_token:breaktokens.append(next_token)return "".join(tokens)generate_text("我", bigram_probs)

结果:

'我喜欢吃苹果'

上述实例完整代码

import jieba
from collections import defaultdict, Counter# 构建语料库
corpus = ["我喜欢吃苹果", "我喜欢吃香蕉", "她喜欢吃葡萄", "他不喜欢吃香蕉", "他喜欢吃苹果", "她喜欢吃草莓"]# 二元组切词
def generate_bigrams(corpus):bigram_list = []for sentence in corpus:# 使用jieba分词words = list(jieba.cut(sentence))bigrams = [(words[i] , words[i + 1]) for i in range(len(words) - 1)]bigram_list.extend(bigrams)return bigram_list# 计算二元组词频
def count_bigrams(bigrams):# 创建字典存储biGram计数bigrams_count = defaultdict(Counter)for bigram in bigrams:prefix = bigram[:-1]token = bigram[-1]bigrams_count[prefix][token] += 1return bigrams_count# 计算二元组概率
def bigram_probabilities(bigrams_count):bigram_probs = defaultdict(Counter)for prefix, tokens_count in bigrams_count.items():total_count = sum(tokens_count.values())for token, count in tokens_count.items():bigram_probs[prefix][token] = count / total_countreturn bigram_probs# 生成内容
def generate_token(prefix, bigram_probs):if not prefix in bigram_probs:return Nonenext_token_probs = bigram_probs[prefix]next_token = max(next_token_probs, key=next_token_probs.get)return next_tokendef generate_text(prefix, bigram_probs, length=6):tokens = list(prefix)for _ in range(length - len(prefix)):next_token = generate_token(tuple(tokens[-1:]), bigram_probs)if not next_token:breaktokens.append(next_token)return "".join(tokens)if __name__ == '__main__':bigrams = generate_bigrams(corpus)print(bigrams)bigrams_count = count_bigrams(bigrams)for prefix, counts in bigrams_count.items():print("{}: {}".format("".join(prefix), dict(counts)))bigram_probs = bigram_probabilities(bigrams_count)for prefix, probs in bigram_probs.items():print("{}: {}".format("".join(prefix), dict(probs)))res = generate_text("我", bigram_probs)print(res)

N-Gram 的局限性

N-Gram 模型具有很大的启发意义和价值,我们只需要一个简单的语料库,结合二元组模型,即可生成一段话。

N-Gram 模型中,我们预测一个词出现的频率,只考虑其之前的 N-1 个词,其优点是计算简单,但是缺点也很明显,那就是它无法捕捉到距离较远的词之间的关系。

下一节,将介绍于 N-Gram 同时代产物,词袋模型(Bag-of-Words)。词袋模型不考虑哪个词和哪个词接近,而是通过把词看作一袋子元素的方式来把文本转换为能统计的特征。


2024.09.07

这篇关于【大模型基础】P1 N-Gram 模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147097

相关文章

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee