HuggingfaceNLP笔记5.2Time to slice and dice

大部分情况下,用于训练模型的数据可能并未准备好。本节我们将探讨🤗 Datasets提供的各种功能,帮助你清理数据。

Slicing and dicing our data

类似于Pandas,🤗 Datasets提供了多个函数来操作DatasetDatasetDict对象。在第3章中,我们已经接触到了Dataset.map()方法,本节我们将探索更多可用的函数。

药物评论数据集为例,该数据集存储在UC Irvine机器学习库,包含患者对不同药物的评论,以及治疗的疾病和10星满意度评分。

首先,我们需要下载并解压数据,可以使用wgetunzip命令:

!wget "https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip"
!unzip drugsCom_raw.zip

由于TSV(Tab Separated Values)只是CSV(Comma Separated Values)的一种变体,使用制表符作为分隔符,我们可以使用csv加载脚本,并在load_dataset()函数中指定delimiter参数:

from datasets import load_dataset

data_files = {"train": "drugsComTrain_raw.tsv", "test": "drugsComTest_raw.tsv"}
# 在Python中,\t代表制表符
drug_dataset = load_dataset("csv", data_files=data_files, delimiter="\t")

在进行数据分析时,通常的做法是随机抽取一部分数据,以便快速了解数据类型。在🤗 Datasets中,我们可以通过链式调用Dataset.shuffle()Dataset.select()函数来创建随机样本:

drug_sample = drug_dataset["train"].shuffle(seed=42).select(range(1000))
# 查看前几项
drug_sample[:3]
{
  "Unnamed: 0": [87571, 178045, 80482],
  "drugName": ["Naproxen", "Duloxetine", "Mobic"],
  "condition": ["Gout, Acute", "ibromyalgia", "Inflammatory Conditions"],
  "review": [...],
  "rating": [9.0, 3.0, 10.0],
  "date": ["September 2, 2015", "November 7, 2011", "June 5, 2013"],
  "usefulCount": [36, 13, 128]
}

注意,我们在Dataset.shuffle()中设置了随机种子,以确保可重复性。Dataset.select()期望一个索引的可迭代对象,所以我们传递了range(1000)来从打乱的数据集中获取前1000个例子。从这个样本中,我们可以看到数据集的一些问题:

  • Unnamed: 0列看起来像是每个患者的匿名ID。
  • condition列包含了大小写混合的标签。
  • 评论的长度各不相同,且包含Python行分隔符(\r\n)以及HTML字符代码,如&\#039;

让我们看看如何使用 🤗 Datasets 来处理这些问题。要测试 Unnamed: 0 列的患者ID假设,我们可以使用 Dataset.unique() 函数来验证每个拆分中的ID数量是否与行数匹配:

for split in drug_dataset.keys():
    assert len(drug_dataset[split]) == len(drug_dataset[split].unique("Unnamed: 0"))

这似乎证实了我们的假设。接下来,我们可以稍微清理一下数据集,将 Unnamed: 0 列重命名为更易于理解的名称。我们可以使用 DatasetDict.rename_column() 函数一次对两个拆分进行重命名:

drug_dataset = drug_dataset.rename_column(
    original_column_name="Unnamed: 0", new_column_name="patient_id"
)
drug_dataset
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount'],
        num_rows: 161297
    })
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount'],
        num_rows: 53766
    })
})

📝 动手试试! 使用 Dataset.unique() 函数查找训练集和测试集中独特药物和条件的数量。

接下来,我们使用 Dataset.map() 对所有 condition 标签进行归一化。就像我们在 第3章 中处理分词一样,我们可以定义一个简单的函数,应用于 drug_dataset 的每个拆分中的每一行:

def lowercase_condition(example):
    return {"condition": example["condition"].lower()}

drug_dataset.map(lowercase_condition)
AttributeError: 'NoneType' object has no attribute 'lower'

哎呀,我们在 map 函数中遇到了问题!从错误中我们可以推断,condition 列中的一些条目是 None,无法将其转换为字符串并进行小写处理。我们可以使用 Dataset.filter() 来删除这些行,它的工作方式类似于 Dataset.map(),但期望一个接收单个数据集样例的函数。我们可以使用一个lambda函数来简化这个过程,而不是编写一个像下面的显式函数,然后运行 drug_dataset.filter(filter_nones) ,:

def filter_nones(x):
    return x["condition"] is not None

在Python中,lambda函数是一种特殊的函数,无需显式命名,其形式如下:

lambda <arguments> : <expression>

其中 lambda 是Python的关键字,<arguments> 是逗号分隔的输入值列表,<expression> 是你希望执行的操作。例如,我们可以定义一个简单的lambda函数来计算数字的平方,如下所示:

lambda x : x * x

要将此函数应用于输入,我们需要将函数和输入都包装在括号中:

(lambda x: x * x)(3)
 9

类似地,对于多参数的lambda函数,只需将它们用逗号分隔即可。例如,我们可以计算三角形的面积:

(lambda base, height: 0.5 * base * height)(4, 8)
16.0

Lambda函数在你想要定义小型、一次性使用的函数时非常有用(关于它们的更多信息,我们推荐阅读Andre Burgaud在Real Python上的优秀教程)。在🤗 Datasets的上下文中,我们可以使用lambda函数来定义简单的映射和过滤操作,所以让我们用这个技巧来消除数据集中的None条目:

drug_dataset = drug_dataset.filter(lambda x: x["condition"] is not None)

移除None条目后,我们可以标准化condition列:

drug_dataset = drug_dataset.map(lowercase_condition)
# 检查小写处理是否有效
drug_dataset["train"]["condition"][:3]
['left ventricular dysfunction', 'adhd', 'birth control']

成功了!现在我们已经清理了标签,接下来让我们看看如何清理评论本身。

Creating new columns

处理客户评论时,一个好的做法是检查每条评论的单词数量。评论可能只是一个单词,如“Great!”,也可能是一篇详尽的长篇大论,数千字不等。根据你的应用场景,你需要以不同的方式处理这些极端情况。要计算每条评论中的单词数量,我们将使用基于按空格分割文本的简单启发式方法。

让我们定义一个计算每条评论单词数量的简单函数:

def compute_review_length(example):
    return {"review_length": len(example["review"].split())}

lowercase_condition()函数不同,compute_review_length()返回的字典的键并不对应于数据集中任何列的名称。在这种情况下,当compute_review_length()被传递给Dataset.map()时,它将应用于数据集中的所有行,以创建一个名为review_length的新列:

drug_dataset = drug_dataset.map(compute_review_length)
# 检查第一个训练示例
drug_dataset["train"][0]
{'patient_id': 206461,
 'drugName': 'Valsartan',
 'condition': 'left ventricular dysfunction',
 'review': '"It has no side effect, I take it in combination of Bystolic 5 Mg and Fish Oil"',
 'rating': 9.0,
 'date': 'May 20, 2012',
 'usefulCount': 27,
 'review_length': 17}

正如预期的那样,我们看到review_length列已添加到我们的训练集中。我们可以使用Dataset.sort()对这个新列进行排序,以查看极端值:

drug_dataset["train"].sort("review_length")[:3]
{'patient_id': [103488, 23627, 20558],
 'drugName': ['Loestrin 21 1 / 20', 'Chlorzoxazone', 'Nucynta'],
 'condition': ['birth control', 'muscle spasm', 'pain'],
 'review': ['"Excellent."', '"useless"', '"ok"'],
 'rating': [10.0, 1.0, 6.0],
 'date': ['November 4, 2008', 'March 24, 2017', 'August 20, 2016'],
 'usefulCount': [5, 2, 10],
 'review_length': [1, 1, 1]}

正如我们所料,有些评论只包含一个单词,虽然这对于情感分析可能没问题,但如果我们想预测条件,这些信息可能就不太有用了。

💡 添加数据集新列的另一种方法是使用Dataset.add_column()函数。这允许你提供一个Python列表或NumPy数组作为列,在Dataset.map()不适合你的分析时,这会很有用。

让我们使用Dataset.filter()函数移除包含少于30个单词的评论。就像我们处理condition列一样,我们可以通过要求评论长度超过这个阈值来过滤掉非常短的评论:

drug_dataset = drug_dataset.filter(lambda x: x["review_length"] > 30)
print(drug_dataset.num_rows)
{'train': 138514, 'test': 46108}

如您所见,我们已经从原始训练集和测试集中移除了大约15%的评论。

📝 试试看! 使用Dataset.sort()函数查看评论中单词数量最多的那些。查看文档,了解如何按长度降序对评论进行排序。

接下来要处理的是评论中存在HTML字符代码的问题。我们可以使用Python的html模块来解码这些字符,如下所示:

import html

text = "I&#039;m a transformer called BERT"
html.unescape(text)
"I'm a transformer called BERT"

我们将使用Dataset.map()方法来解码我们语料库中的所有HTML字符:

drug_dataset = drug_dataset.map(lambda x: {"review": html.unescape(x["review"])})

如您所见,Dataset.map()方法对于处理数据非常有用——我们甚至还没有充分利用它的所有功能!

The map() method’s superpowers

Dataset.map()方法有一个名为batched的参数,如果设置为True,它会将一批示例一次性发送到映射函数(批大小可配置,默认为1000)。例如,上一个解码HTML字符的映射函数运行时间较长(您可以在进度条中读取耗时)。我们可以使用列表推导式来加快这个过程,同时处理多个元素。

当您指定batched=True时,函数会接收一个包含数据集字段的字典,但每个值现在是一个值的列表,而不仅仅是单个值。Dataset.map()的返回值应与我们想要更新或添加到数据集的字段相同的字典,以及一个值的列表。例如,这是另一种使用batched=True解码所有HTML字符的方法:

new_drug_dataset = drug_dataset.map(
    lambda x: {"review": [html.unescape(o) for o in x["review"]]}, batched=True
)

如果您在笔记本中运行这段代码,您会发现这个命令比之前的执行速度快得多。这并不是因为我们的评论已经解码过HTML了——如果您重新执行上一节中的指令(不使用batched=True),它仍然会花费相同的时间。这是因为列表推导式通常比在for循环中执行相同代码更快,而且我们通过同时访问大量元素而不是逐个访问,从而提高了性能。

使用batched=TrueDataset.map()对于解锁第6章中我们将遇到的“快速”分词器的速度至关重要,这些分词器可以快速对大量文本列表进行分词。例如,要使用快速分词器对所有药物评论进行分词,我们可以使用如下函数:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased", use_fast=True)


def tokenize_function(examples):
    return tokenizer(examples["review"], truncation=True)

如您在第3章中所见,我们可以将一个或多个示例传递给分词器,因此我们可以使用此函数,无论是否使用batched=True。现在,我们借此机会比较不同选项的性能。在笔记本中,您可以在要测量的代码行前添加%time

%time tokenized_dataset = drug_dataset.map(tokenize_function, batched=True)

您也可以在单元格开头添加%%time来测量整个单元格的运行时间。在我们执行的硬件上,这个指令显示了10.8秒(“Wall time”后的数字)。

📝 试试看!batched=Truebatched=False执行相同的指令,然后尝试使用一个慢速分词器(在AutoTokenizer.from_pretrained()方法中添加use_fast=False),看看您的硬件上能得到什么结果。

以下是使用和不使用批处理,以及使用快速和慢速分词器的结果:

这是Markdown文件,将其翻译成中文,不会修改现有的Markdown指令:

选项快速分词器慢速分词器
batched=True10.8s4min41s
batched=False59.2s5min3s

这意味着使用batched=True的快速分词器比无批处理的慢速分词器快30倍,这真是惊人!这就是为什么在使用AutoTokenizer时,快速分词器是默认选项的原因(也是为什么它们被称为“快速”)。它们能够实现这样的速度提升,是因为背后的分词代码在Rust中执行,这是一种易于并行化代码执行的语言。

并行化也是快速分词器通过批处理实现近6倍速度提升的原因:你不能并行化单个分词操作,但当你需要同时对大量文本进行分词时,你可以将执行任务分解到多个进程中,每个进程负责自己的文本。

Dataset.map()也有自己的并行处理能力。由于它们不是由Rust支持的,所以它们无法让慢速分词器追上快速分词器,但它们仍然很有帮助(特别是当你使用没有快速版本的分词器时)。要启用多进程,使用num_proc参数,并在调用Dataset.map()时指定要使用的进程数:

slow_tokenizer = AutoTokenizer.from_pretrained("bert-base-cased", use_fast=False)


def slow_tokenize_function(examples):
    return slow_tokenizer(examples["review"], truncation=True)


tokenized_dataset = drug_dataset.map(slow_tokenize_function, batched=True, num_proc=8)

你可以尝试一些时间测试来确定最佳的进程数;在我们的例子中,8个进程似乎产生了最佳的加速效果。以下是使用和不使用多进程的性能数据:

选项快速分词器慢速分词器
batched=True10.8s4min41s
batched=False59.2s5min3s
batched=True, num_proc=86.52s41.3s
batched=False, num_proc=89.49s45.2s

对于慢速分词器,这些结果要合理得多,但快速分词器的性能也有了显著提升。然而,这并不总是适用的——对于num_proc不为8的情况,我们的测试显示,使用batched=True而不使用该选项更快。通常,我们不建议为batched=True的快速分词器使用Python多进程。

使用num_proc来加速处理通常是个好主意,只要你的函数没有自己进行某种类型的并行处理。

所有这些功能都浓缩在一个方法中已经非常棒了,但还有更多!使用Dataset.map()batched=True,你可以改变数据集中的元素数量。这对于许多情况下非常有用,例如,你想要从一个示例中创建多个训练特征,而我们在第7章中将要进行的许多NLP任务都需要这样做。

💡 在机器学习中,一个示例通常定义为我们提供给模型的特征集合。在某些上下文中,这些特征可能就是Dataset中的列,但在其他情况下(如这里和问答任务中),一个示例可以从一个单一的列中提取出多个特征。

让我们看看它是如何工作的!这里,我们将对示例进行分词并截断到最大长度为128,但我们将要求分词器返回所有文本的片段,而不仅仅是第一个片段。这可以通过return_overflowing_tokens=True实现:

def tokenize_and_split(examples):
    return tokenizer(
        examples["review"],
        truncation=True,
        max_length=128,
        return_overflowing_tokens=True,
    )

在对整个数据集使用Dataset.map()之前,让我们先在一个示例上测试一下:

result = tokenize_and_split(drug_dataset["train"][0])
[len(inp) for inp in result["input_ids"]]
[128, 49]

那么,我们在训练集中第一个示例被分成了两个特征,因为它被分词成了超过我们指定的最大令牌数:第一个长度为128,第二个长度为49。现在让我们对数据集中的所有元素都这样做!

tokenized_dataset = drug_dataset.map(tokenize_and_split, batched=True)

哎呀!那不起作用!为什么会这样呢?看看错误信息就能找到线索:其中一个列的长度不匹配,一个长度为1,463,另一个长度为1,000。如果你查看了Dataset.map()文档,你可能会记得我们传递给映射函数的样本数量;这里,1,000个示例产生了1,463个新特征,导致形状错误。

问题在于我们试图混合两个不同大小的数据集:drug_dataset的列会有一定数量的示例(在我们的错误中是1,000个),但我们在构建的tokenized_dataset会有更多(错误消息中的1,463;它大于1,000,因为我们使用return_overflowing_tokens=True将长评论分成了多个示例)。这对Dataset来说是行不通的,所以我们需要要么从旧数据集中移除列,要么让它们的大小与新数据集中的相同。我们可以使用remove_columns参数来实现前者:

tokenized_dataset = drug_dataset.map(
    tokenize_and_split, batched=True, remove_columns=drug_dataset["train"].column_names
)

现在这可以正常工作了。我们可以比较长度来确认新数据集确实比原始数据集多了很多元素:

len(tokenized_dataset["train"]), len(drug_dataset["train"])
(206772, 138514)

我们提到过,我们也可以通过让旧列的大小与新列相同来处理长度不匹配的问题。要做到这一点,我们需要使用return_overflowing_tokens=True时tokenizer返回的overflow_to_sample_mapping字段。它给出了新特征索引到其来源样本索引的映射。使用这个映射,我们可以将原始数据集中每个键关联到一个正确大小的值列表,通过重复每个示例的值,直到它生成的新特征数量。

def tokenize_and_split(examples):
    result = tokenizer(
        examples["review"],
        truncation=True,
        max_length=128,
        return_overflowing_tokens=True,
    )
    # 提取新旧索引之间的映射
    sample_map = result.pop("overflow_to_sample_mapping")
    for key, values in examples.items():
        result[key] = [values[i] for i in sample_map]
    return result

这样,我们就可以使用Dataset.map()而无需移除旧列:

tokenized_dataset = drug_dataset.map(tokenize_and_split, batched=True)
tokenized_dataset
DatasetDict({
    train: Dataset({
        features: ['attention_mask', 'condition', 'date', 'drugName', 'input_ids', 'patient_id', 'rating', 'review', 'review_length', 'token_type_ids', 'usefulCount'],
        num_rows: 206772
    })
    test: Dataset({
        features: ['attention_mask', 'condition', 'date', 'drugName', 'input_ids', 'patient_id', 'rating', 'review', 'review_length', 'token_type_ids', 'usefulCount'],
        num_rows: 68876
    })
})

我们得到了与之前相同的训练特征数量,但这里我们保留了所有旧字段。如果你在应用模型后需要这些字段进行后处理,你可能会选择这种方法。

现在你已经看到了如何使用🤗 Datasets以各种方式预处理数据集。尽管🤗 Datasets的处理函数能满足大多数模型训练需求,但有时你可能需要切换到Pandas,以利用更强大的功能,如DataFrame.groupby()或可视化高级API。幸运的是,🤗 Datasets设计为与Pandas、NumPy、PyTorch、TensorFlow和JAX等库兼容。让我们看看这如何工作。

From Dataset s to DataFrame s and back

为了在不同的第三方库之间转换,🤗 Datasets 提供了一个 Dataset.set_format() 函数。这个函数只改变数据集的 输出格式,因此你可以轻松地切换到其他格式,而不会影响底层的 数据格式,即 Apache Arrow。格式化是就地进行的。让我们演示如何将数据集转换为 Pandas 格式:

drug_dataset.set_format("pandas")

现在,当我们访问数据集的元素时,我们会得到一个 pandas.DataFrame,而不是字典:

drug_dataset["train"][:3]
patient_iddrugNameconditionreviewratingdateusefulCountreview_length
095260Guanfacineadhd“My son is halfway through his fourth week of Intuniv…”8.0April 27, 2010192141
192703Lybrelbirth control“I used to take another oral contraceptive, which had 21 pill cycle, and was very happy- very light periods, max 5 days, no other side effects…”5.0December 14, 200917134
2138000Ortho Evrabirth control“This is my first time using any form of birth control…”8.0November 3, 20151089

我们可以通过选择 drug_dataset["train"] 中的所有元素来创建整个训练集的 pandas.DataFrame

train_df = drug_dataset["train"][:]

请注意,Dataset.set_format() 实际上改变了数据集的 __getitem__() 方法的返回格式。这意味着,当我们想要从 Dataset 中以 "pandas" 格式创建新对象,如 train_df 时,需要切片整个数据集以获得 pandas.DataFrame。你可以自行验证,无论输出格式如何,drug_dataset["train"] 的类型都是 Dataset

从这里,我们可以使用所有 Pandas 功能。例如,我们可以进行复杂的链式操作来计算 condition 列的类别分布:

frequencies = (
    train_df["condition"]
    .value_counts()
    .to_frame()
    .reset_index()
    .rename(columns={"index": "condition", "condition": "frequency"})
)
frequencies.head()
conditionfrequency
0birth control27655
1depression8023
2acne5209
3anxiety4991
4pain4744

当我们完成 Pandas 分析后,我们始终可以使用 Dataset.from_pandas() 函数创建新的 Dataset 对象,如下所示:

from datasets import Dataset

freq_dataset = Dataset.from_pandas(frequencies)
freq_dataset
Dataset({
    features: ['condition', 'frequency'],
    num_rows: 819
})

现在,让我们尝试一下!计算每个药物的平均评分,并将结果存储在新的 Dataset 中。

我们对 🤗 数据集中可用的各种预处理技术的了解到此结束。为了结束这一部分,我们将创建一个验证集,为训练分类器做准备。在这样做之前,我们将把 drug_dataset 的输出格式从 "pandas" 重置为 "arrow"

drug_dataset.reset_format()

Creating a validation set

尽管我们有一个测试集可以用于评估,但在开发过程中创建一个单独的验证集是一个好习惯。一旦你对模型在验证集上的性能感到满意,你可以在测试集上进行最终的检查,以降低过度拟合测试集并部署在实际数据上失败的风险。

🤗 Datasets 提供了一个基于 scikit-learn 中著名功能的 Dataset.train_test_split() 函数。让我们使用它将训练集划分为 trainvalidation 部分(我们设置 seed 参数以确保可重复性):

drug_dataset_clean = drug_dataset["train"].train_test_split(train_size=0.8, seed=42)
# 将默认的 "test" 切分重命名为 "validation"
drug_dataset_clean["validation"] = drug_dataset_clean.pop("test")
# 将 "test" 集合添加到我们的 `DatasetDict` 中
drug_dataset_clean["test"] = drug_dataset["test"]
drug_dataset_clean
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 110811
    })
    validation: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 27703
    })
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 46108
    })
})

太好了,现在我们已经准备好训练模型了!在第5章中,我们将向您展示如何将数据集上传到Hugging Face Hub,但在这里,让我们通过查看保存数据集的几种方式来结束我们的分析。

Saving a dataset

虽然🤗 Datasets会缓存下载的每个数据集及其操作结果,但有时您可能希望将数据集保存到本地磁盘(例如,如果缓存被删除)。如表所示,🤗 Datasets提供了三种主要的函数,以不同的格式保存您的数据集:

数据格式函数
ArrowDataset.save_to_disk()
CSVDataset.to_csv()
JSONDataset.to_json()

例如,让我们将清理后的数据集以Arrow格式保存:

drug_dataset_clean.save_to_disk("drug-reviews")

这将创建一个目录结构如下:

drug-reviews/
├── dataset_dict.json
├── test
│   ├── dataset.arrow
│   ├── dataset_info.json
│   └── state.json
├── train
│   ├── dataset.arrow
│   ├── dataset_info.json
│   ├── indices.arrow
│   └── state.json
└── validation
    ├── dataset.arrow
    ├── dataset_info.json
    ├── indices.arrow
    └── state.json

我们可以看到每个切分都与其自己的 dataset.arrow 表以及 dataset_info.jsonstate.json 中的一些元数据相关联。您可以将Arrow格式视为一个优化用于构建处理和传输大型数据集的高性能应用程序的列和行的高级表格。

数据集保存后,我们可以使用load_from_disk()函数加载它:

from datasets import load_from_disk

drug_dataset_reloaded = load_from_disk("drug-reviews")
drug_dataset_reloaded
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 110811
    }),
    validation: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 27703
    }),
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 46108
    })
})

对于CSV和JSON格式,我们需要将每个拆分保存为单独的文件。一种方法是遍历DatasetDict对象中的键值对:

for split, dataset in 药物数据集清理.items():
    dataset.to_json(f"drug-reviews-{split}.jsonl")

这将每个拆分保存为JSON Lines格式,其中每个数据集行存储为单行JSON。第一个示例如下:

!head -n 1 drug-reviews-train.jsonl
{"patient_id":141780,"drugName":"Escitalopram","condition":"depression","review":"\"I seemed to experience the regular side effects of LEXAPRO, insomnia, low sex drive, sleepiness during the day. I am taking it at night because my doctor said if it made me tired to take it at night. I assumed it would and started out taking it at night. Strange dreams, some pleasant. I was diagnosed with fibromyalgia. Seems to be helping with the pain. Have had anxiety and depression in my family, and have tried quite a few other medications that haven't worked. Only have been on it for two weeks but feel more positive in my mind, want to accomplish more in my life. Hopefully the side effects will dwindle away, worth it to stick with it from hearing others responses. Great medication.\"","rating":9.0,"date":"May 29, 2011","usefulCount":10,"review_length":125}

然后,我们可以使用第2章中的技术来加载JSON文件,如下所示:

data_files = {
    "train": "drug-reviews-train.jsonl",
    "validation": "drug-reviews-validation.jsonl",
    "test": "drug-reviews-test.jsonl",
}
drug_dataset_reloaded = load_dataset("json", data_files=data_files)

这就是我们对数据清洗与🤗 Datasets交互的探索!现在我们有了训练模型的清理数据集,你可以尝试以下几点:

  1. 使用第3章中的技术训练一个分类器,根据药物评论预测患者状况。
  2. 使用第1章中的summarization管道生成评论的摘要。

接下来,我们将看看如何使用🤗 Datasets处理巨大的数据集,而不会让笔记本崩溃!

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HITzwx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值