知识补充
前言
小白实现代码,记录自己的学习脚步。
一、Tokenization
1.知识补充-wordpiece中提到的对数似然估计
对数似然估计
通常使用概率的对数来衡量的原因有几点:
数值稳定性: 概率通常是小于1的小数,当计算多个概率相乘时,可能会导致数值下溢(即计算结果变得非常接近于零),尤其是在长句子或者大规模数据集中。使用对数转换后,可以将相乘转换为相加,避免了数值下溢问题,提高了计算的稳定性。
便于比较: 对数概率的值域是负无穷到零,数值越大表示概率越高。这种形式使得概率的比较更加直观和方便,不需要考虑概率的范围。
数学便利性: 对数函数具有很好的数学性质,例如对数函数的导数可以简化计算。这使得在概率模型中的一些计算更加高效和方便。
对数似然增益(Log Likelihood Gain):
是一种在机器学习和统计领域中用于评估模型性能的指标。它通常用于监督学习中的分类和回归任务。对数似然增益是指在某个模型下,使用对数似然函数作为损失函数时,模型在数据集上的对数似然值的增加量。
让我们从对数似然函数开始解释。在统计学中,对数似然函数是一种用于估计参数的方法。对于给定的观察数据集,我们假设数据服从某个概率分布,例如高斯分布或伯努利分布。对数似然函数是这些数据在给定模型下的似然性的对数值。其表达式通常写为:
在训练机器学习模型时,我们的目标是最大化对数似然函数。对于分类问题,我们希望模型的预测值与真实标签的概率分布尽可能接近;对于回归问题,我们希望模型的预测值与真实值之间的误差尽可能小。
对数似然增益是指在模型进行改进后,对数似然函数的增加量。在训练过程中,我们尝试不同的模型参数或不同的模型结构,以使对数似然函数的值增加。对数似然增益提供了一种量化模型改进的指标,即模型的新版本相对于之前版本对数据的拟合程度提高了多少。
在实践中,对数似然增益通常与交叉验证结合使用,以帮助选择最佳的模型参数或模型结构,以便在未见数据上获得良好的泛化性能。
2.子词粒度subword常用库
二、构造词表
构造词表的主要目的包括:
词频统计: 构造词表可以帮助统计每个词在文本中出现的频率。这对于词语的重要性排序、信息检索和文本分类等任务非常重要。
词性标注: 词表中的词语往往会被标注上其词性,例如名词、动词、形容词等。这对于语言分析和语法分析非常有用。
特征提取: 在自然语言处理任务中,如文本分类、情感分析等,词表可以用于提取文本的特征。通常会将每个词在词表中的位置作为特征向量的一部分。
减少计算量: 在很多自然语言处理任务中,词表的使用可以减少计算量。例如,在文本分类任务中,可以将文本表示成词语在词表中的出现情况,从而减少了文本向量的维度。
处理未登录词: 词表中记录了已知的词语,可以帮助系统处理那些没有出现在词表中的未登录词,通过一些特殊的处理方式来应对未登录词的问题
Bert模型的优点在于同一个词在不同语句中的向量表示是不同的,它是根据上下文得到的是一个动态的过程
1.使用数据集构建图表
2.数据长度处理问题
横轴是文本长度,纵轴是频率
解决长尾问题的方法
(1)在自然语言处理中,特别是在处理文本数据时,往往需要将文本数据转换成固定长度的向量或者矩阵,以便于输入到机器学习模型中进行训练或推理。而当原始文本长度不一致时,就需要使用一些方法对文本进行处理,其中包括“pad”和“truncate”。
-
Padding(填充): Padding 是指在文本的开头或结尾添加特定的标记(通常是一个特殊的符号,如0),使得文本的长度达到某个预设的长度。这通常用于处理文本长度不足的情况,以保证所有输入文本的长度相同。例如,假设设定了一个长度为10的文本输入,而某个文本只有5个词,则可以在文本结尾处添加5个特定标记,使得文本长度达到10。
-
Truncation(截断): Truncation 是指将文本的长度截断到某个预设的长度。当原始文本的长度超过所设定的长度时,可以通过截断的方式将其缩减至指定长度。通常有两种截断方式:
- 前向截断(前向截取): 保留文本的前部分,丢弃超过指定长度的部分。
- 后向截断(后向截取): 保留文本的后部分,丢弃超过指定长度的部分。
Pad + truncate 是指将文本数据首先进行填充(pad)或截断(truncate)处理,以保证所有输入文本的长度一致。这种方法常用于神经网络等模型的输入处理中,确保输入的数据具有相同的形状,从而可以被更方便地处理和应用于模型中。
(2)在计算机科学和数据处理领域,“分桶”(bucketing)是一种将数据分成特定区间或范围的技术。这个概念经常在数据处理、数据分析和机器学习等领域中被使用。
分桶的主要目的是将连续的数值型数据划分成离散的组,以便于统计、分析或者处理。常见的应用包括数据的分组统计、特征工程中的数值离散化等。
下面是分桶的一些常见应用和方法:
等宽分桶(Equal Width Bucketing): 在等宽分桶中,数据的范围被均匀地分成若干个区间。例如,如果将0到100的数据分成5个区间,则每个区间的范围为20。这种方法简单易行,但可能由于数据分布不均匀而导致一些桶中数据较少。
等频分桶(Equal Frequency Bucketing): 在等频分桶中,数据被划分成具有相似数据点数量的区间。这意味着每个区间中的数据点数量大致相等。这种方法可以有效地解决数据分布不均匀的问题,但可能由于数据点数量的不同而导致区间的宽度不均匀。
自定义分桶(Custom Bucketing): 在某些情况下,根据数据的特点,可以自定义分桶策略。例如,根据业务需求或领域知识,将数据划分成具有特定含义的区间。这种方法通常需要深入了解数据的特点和业务需求。
分位数分桶(Quantile Bucketing): 在分位数分桶中,数据被划分成具有相等百分比的区间。例如,四分位数分桶将数据分成四个区间,每个区间包含数据中25%的观测值。这种方法能够有效地捕捉数据的分布情况,但可能会导致每个区间中数据量不均匀。
总的来说,分桶是一种常见且实用的数据处理技术,可以在数据分析和机器学习等领域中起到重要的作用。选择合适的分桶方法需要考虑数据的分布情况、业务需求以及分析目的等因素。
三、data_processing模块
1.导入需要使用的库的模块
首先对需要的库进行一个导入,在想这个里边的collection跟java里边的会有什么联系吗?
答:在Python中,collections.defaultdict
是一个特殊的字典类型,它是collections
模块提供的一个工具类,用于创建字典对象。与普通字典相比,defaultdict
的特点在于当试图访问一个不存在的键时,它会自动创建这个键并将其对应的值初始化为默认值,而不会抛出KeyError异常。
与Java中的Collection接口不同,collections.defaultdict
更类似于Java中的HashMap。它们的相似之处在于都提供了一种映射数据结构,可以存储键值对,并支持通过键来快速查找值。但与Java中的Collection接口不同,defaultdict
只是Python中字典类型的一个特殊实现,而Java中的Collection是一个接口,有多种具体的实现类(如List、Set、Map等),用于表示不同的集合类型。
`import os # 导入操作系统模块`
`import pickle # 导入 pickle 序列化模块`
`import argparse # 导入命令行参数解析模块`
`import numpy as np # 导入 NumPy 数组操作库`
`import pandas as pd # 导入 Pandas 数据处理库`
`from tqdm import tqdm # 导入进度条模块`
`from rdkit import Chem # 导入 RDKit 化学信息处理库`
`from rdkit import DataStructs # 导入 RDKit 数据结构处理库`
`from rdkit.Chem import AllChem # 导入 RDKit 化学信息处理库的子模块`
`from collections import defaultdict # 导入默认字典模块`
`from sklearn.model_selection import StratifiedShuffleSplit # 导入 StratifiedShuffleSplit 分层随机分割模块`
`import networkx as nx # 导入网络图模块`
`from torch_geometric.data import Data # 导入 PyTorch Geometric 中的数据类`
`from torch.utils.data import Dataset, DataLoader # 导入 PyTorch 中的数据集类和数据加载器类`
`from utils import * # 导入自定义的工具函数`
`import pandas as pd # 导入 Pandas 数据处理库`
`import csv # 导入 CSV 文件处理模块`
`import random # 导入随机数生成模块`
`from tqdm import tqdm # 导入进度条模块`
`import copy # 导入复制模块`
`import numpy as np # 导入 NumPy 数组操作库`
以上就是导入了一些相关的库
2.为不同的模块设置随机数种子从而能够实现复现代码
`#设置随机种子函数`
`def set_random_seed(seed, deterministic=False):`
`torch.manual_seed(seed) # 设置 PyTorch 的随机种子`
`torch.cuda.manual_seed(seed) # 设置 PyTorch GPU 的随机种子`
`torch.cuda.manual_seed_all(seed) # 如果使用多 GPU,设置所有 GPU 的随机种子`
`np.random.seed(seed) # 设置 NumPy 的随机种子`
`random.seed(seed) # 设置 Python 自带的随机种子`
`torch.manual_seed(seed) # 重新设置 PyTorch 的随机种子`
`torch.backends.cudnn.benchmark = False # 关闭 cuDNN 的基准模式`
`torch.backends.cudnn.deterministic = True # 设置 cuDNN 的确定性模式为 True`
`#调用设置随机种子函数,并设置确定性为 True`
`set_random_seed(1, deterministic=True)``
(1)为不同的模块或操作设置相同的随机种子,如PyTorch、NumPy和Python自带的随机种子,可以确保它们在随机性操作时生成的随机数序列是相同的。
(2)这样做的目的是为了保证实验的可重复性和结果的稳定性。在机器学习中,通常会多次运行实验以获得可靠的结果,而设置相同的随机种子可以确保每次运行时产生的随机数序列是一致的,从而使结果具有可比性。
在具体的代码中,通过调用set_random_seed
函数并将deterministic
参数设置为True,可以关闭所有可能影响随机性的因素,确保每次运行时都产生相同的随机数序列。这样做有助于在不同的环境下获得相同的实验结果,提高了实验的可重复性和结果的可靠性。也就是说我们在实验过程中,需要注意每次设置的随机序列都是一致的,这样才可以展现出我们模型是否有所改进,不然的话相当于每次实验都是独立的没办法作比较
设置好随机种子之后,便是对于文件数据中的提取,
先设置一些方法,首先是对于类的初始化,将获取到的每列数值以实体的形式保存。
3.初始化类的方法就是将文件中的数据转换到数组中,同时通过随机数种子进行数据集的划分
def __init__(self, triple): # 定义类的初始化方法,接收一个参数 triple
self.entity1 = triple[:, 0] # 将 triple 参数的第一列赋值给 self.entity1
self.entity2 = triple[:, 1] # 将 triple 参数的第二列赋值给 self.entity2
self.relationtype = triple[:, 2] # 将 triple 参数的第三列赋值给 self.relationtype
#self.label = triple[:, 3] # 将 triple 参数的第四列赋值给 self.label(这行代码被注释掉了)
def __len__(self): # 定义 __len__ 方法,返回数据集的长度
return len(self.relationtype) # 返回关系类型(relationtype)的长度作为数据集的长度
def __getitem__(self, index): # 定义 __getitem__ 方法,用于根据索引获取数据项
return (self.entity1[index], self.entity2[index], self.relationtype[index]) # 返回索引对应位置的实体1、实体2和关系类型元组
以上代码定义了一个名为 Data_class 的类,用于创建一个数据集对象,该数据集对象包含了实体1、实体2和关系类型的数据。在类的初始化方法中,将传入的 triple 参数的每一列分别赋值给类的属性 entity1、entity2 和 relationtype。__len__ 方法返回了数据集的长度,即关系类型(relationtype)的长度。__getitem__ 方法用于根据索引获取数据项,返回了索引对应位置的实体1、实体2和关系类型的元组。
def load_data(args, val_ratio=0.1, test_ratio=0.2): # 定义一个名为 load_data 的函数,接收参数 args、val_ratio 和 test_ratio,默认值分别为 0.1 和 0.2
在函数 `load_data` 中,参数 `val_ratio` 和 `test_ratio` 是用来指定验证集和测试集所占总体数据的比例的。具体来说:
- `val_ratio` 表示验证集的比例,取值范围为 0 到 1 之间,表示验证集占总体数据的比例。例如,如果 `val_ratio` 设为 0.1,表示验证集占总体数据的 10%。
- `test_ratio` 表示测试集的比例,同样取值范围为 0 到 1 之间,表示测试集占总体数据的比例。例如,如果 `test_ratio` 设为 0.2,表示测试集占总体数据的 20%。
这样设置参数的目的是根据数据集的规模,将数据集划分为训练集、验证集和测试集三部分。通常的做法是将数据集按照 7:2:1 的比例划