Skip to content

Commit

Permalink
2024-02-09 01:39:06
Browse files Browse the repository at this point in the history
  • Loading branch information
wizardforcel committed Feb 8, 2024
1 parent 83046c7 commit 51349f0
Show file tree
Hide file tree
Showing 97 changed files with 8,791 additions and 8,791 deletions.
110 changes: 55 additions & 55 deletions totrans/dl-cb_00.md

Large diffs are not rendered by default.

172 changes: 86 additions & 86 deletions totrans/dl-cb_01.md

Large diffs are not rendered by default.

58 changes: 29 additions & 29 deletions totrans/dl-cb_02.md

Large diffs are not rendered by default.

78 changes: 39 additions & 39 deletions totrans/dl-cb_03.md

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions totrans/dl-cb_04.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 第4章。基于维基百科外部链接构建推荐系统
# 第四章。基于维基百科外部链接构建推荐系统

推荐系统传统上是根据用户先前收集的评分进行训练的。我们希望预测用户的评分,因此从历史评分开始似乎是一个自然的选择。然而,这要求我们在开始之前有一个大量的评分集,并且不允许我们对尚未评分的新项目做出良好的工作。此外,我们故意忽略了我们对项目的元信息。

Expand All @@ -23,7 +23,7 @@

###### 注意

本配方中的代码展示了如何从维基百科获取和提取训练数据,这是一个非常有用的技能。然而,下载和处理完整的转储文件需要相当长的时间。笔记本文件夹的*data*目录包含了预先提取的前10000部电影,我们将在本章的其余部分中使用,因此您不需要运行本配方中的步骤。
本配方中的代码展示了如何从维基百科获取和提取训练数据,这是一个非常有用的技能。然而,下载和处理完整的转储文件需要相当长的时间。笔记本文件夹的*data*目录包含了预先提取的前 10000 部电影,我们将在本章的其余部分中使用,因此您不需要运行本配方中的步骤。

让我们从维基百科下载最新的转储文件开始。您可以使用您喜欢的浏览器轻松完成这一操作,如果您不需要最新版本,您可能应该选择附近的镜像。但您也可以通过编程方式完成。以下是获取最新转储页面的方法:

Expand Down Expand Up @@ -59,7 +59,7 @@ path = get_file(wikipedia_dump, url)
path
```

我们检索到的转储文件是一个bz2压缩的XML文件。我们将使用`sax`来解析维基百科的XML。我们对`<title>``<page>`标签感兴趣,因此我们的`Content​Handler`看起来像这样:
我们检索到的转储文件是一个 bz2 压缩的 XML 文件。我们将使用`sax`来解析维基百科的 XML。我们对`<title>``<page>`标签感兴趣,因此我们的`Content​Handler`看起来像这样:

```py
class WikiXmlHandler(xml.sax.handler.ContentHandler):
Expand Down Expand Up @@ -91,7 +91,7 @@ class WikiXmlHandler(xml.sax.handler.ContentHandler):

对于每个`<page>`标签,这将收集标题和文本内容到`self._values`字典中,并使用收集到的值调用`process_article`

尽管维基百科最初是一个超链接文本型百科全书,但多年来它已经发展成一个更结构化的数据转储。其中一种方法是让页面链接回所谓的*分类页面*。这些链接起到标签的作用。电影《飞越疯人院》的页面链接到“1975年电影”分类页面,因此我们知道这是一部1975年的电影。不幸的是,并没有仅仅针对电影的分类页面。幸运的是,有一个更好的方法:维基百科模板。
尽管维基百科最初是一个超链接文本型百科全书,但多年来它已经发展成一个更结构化的数据转储。其中一种方法是让页面链接回所谓的*分类页面*。这些链接起到标签的作用。电影《飞越疯人院》的页面链接到“1975 年电影”分类页面,因此我们知道这是一部 1975 年的电影。不幸的是,并没有仅仅针对电影的分类页面。幸运的是,有一个更好的方法:维基百科模板。

模板最初是一种确保包含相似信息的页面以相同方式呈现该信息的方法。“信息框”模板对数据处理非常有用。它不仅包含适用于页面主题的键/值对列表,还有一个类型。其中之一是“电影”,这使得提取所有电影的任务变得更加容易。

Expand Down Expand Up @@ -119,7 +119,7 @@ def process_article(title, text):
return (title, properties, links) + rating
```

现在我们可以将bzipped转储文件输入解析器
现在我们可以将 bzipped 转储文件输入解析器

```py
parser = xml.sax.make_parser()
Expand All @@ -146,11 +146,11 @@ with open('wp_movies.ndjson', 'wt') as fout:

维基百科不仅是回答几乎任何人类知识领域问题的重要资源;它也是许多深度学习实验的起点。了解如何解析转储文件并提取相关部分是许多项目中有用的技能。

13 GB的数据转储是相当大的下载。解析维基百科标记语言带来了自己的挑战:这种语言多年来有机地发展,似乎没有强大的基础设计。但是随着今天快速的连接和一些出色的开源库来帮助解析,这一切都变得相当可行。
13 GB 的数据转储是相当大的下载。解析维基百科标记语言带来了自己的挑战:这种语言多年来有机地发展,似乎没有强大的基础设计。但是随着今天快速的连接和一些出色的开源库来帮助解析,这一切都变得相当可行。

在某些情况下,维基百科API可能更合适。这个对维基百科的REST接口允许您以多种强大的方式搜索和查询,并且只获取您需要的文章。考虑到速率限制,以这种方式获取所有电影将需要很长时间,但对于较小的领域来说,这是一个选择。
在某些情况下,维基百科 API 可能更合适。这个对维基百科的 REST 接口允许您以多种强大的方式搜索和查询,并且只获取您需要的文章。考虑到速率限制,以这种方式获取所有电影将需要很长时间,但对于较小的领域来说,这是一个选择。

如果您最终要为许多项目解析维基百科,那么首先将转储导入到像Postgres这样的数据库中可能是值得的,这样您就可以直接查询数据集。
如果您最终要为许多项目解析维基百科,那么首先将转储导入到像 Postgres 这样的数据库中可能是值得的,这样您就可以直接查询数据集。

# 4.2 训练电影嵌入

Expand All @@ -160,9 +160,9 @@ with open('wp_movies.ndjson', 'wt') as fout:

## 解决方案

使用一些元信息作为连接器来训练嵌入。这个示例建立在之前的示例之上,使用了那里提取的电影和链接。为了使数据集变得更小且更少噪音,我们将仅使用维基百科上受欢迎程度确定的前10,000部电影
使用一些元信息作为连接器来训练嵌入。这个示例建立在之前的示例之上,使用了那里提取的电影和链接。为了使数据集变得更小且更少噪音,我们将仅使用维基百科上受欢迎程度确定的前 10,000 部电影

我们将外链视为连接器。这里的直觉是链接到同一页面的电影是相似的。它们可能有相同的导演或属于相同的类型。随着模型的训练,它不仅学习哪些电影相似,还学习哪些链接相似。这样它可以泛化并发现指向1978年的链接与指向1979年的链接具有相似的含义,从而有助于电影的相似性。
我们将外链视为连接器。这里的直觉是链接到同一页面的电影是相似的。它们可能有相同的导演或属于相同的类型。随着模型的训练,它不仅学习哪些电影相似,还学习哪些链接相似。这样它可以泛化并发现指向 1978 年的链接与指向 1979 年的链接具有相似的含义,从而有助于电影的相似性。

我们将从计算外链开始,这是一个快速查看我们是否合理的方法:

Expand Down Expand Up @@ -250,7 +250,7 @@ model.fit_generator(
)
```

训练时间将取决于您的硬件,但如果您从10,000部电影数据集开始,即使在没有GPU加速的笔记本电脑上,训练时间也应该相当短。
训练时间将取决于您的硬件,但如果您从 10,000 部电影数据集开始,即使在没有 GPU 加速的笔记本电脑上,训练时间也应该相当短。

我们现在可以通过访问`movie_embedding`层的权重从我们的模型中提取电影嵌入。我们对它们进行归一化,以便我们可以使用点积作为余弦相似度的近似:

Expand Down Expand Up @@ -292,9 +292,9 @@ neighbors('Rogue One')

我们在这里训练的模型非常简单。我们只需要让它提供一个嵌入空间,使得电影的向量和链接的向量的组合可以用来预测它们是否会共同出现。这迫使网络将电影投影到一个空间中,使得相似的电影最终位于相似的位置。我们可以使用这个空间来找到相似的电影。

在Word2vec模型中,我们使用一个词的上下文来预测这个词。在这个示例中,我们不使用链接的上下文。对于外部链接来说,这似乎不是一个特别有用的信号,但如果我们使用的是内部链接,这可能是有意义的。链接到电影的页面以一定的顺序进行链接,我们可以利用链接的上下文来改进我们的嵌入。
在 Word2vec 模型中,我们使用一个词的上下文来预测这个词。在这个示例中,我们不使用链接的上下文。对于外部链接来说,这似乎不是一个特别有用的信号,但如果我们使用的是内部链接,这可能是有意义的。链接到电影的页面以一定的顺序进行链接,我们可以利用链接的上下文来改进我们的嵌入。

或者,我们可以使用实际的Word2vec代码,并在链接到电影的任何页面上运行它,但保留电影链接作为特殊标记。这样就会创建一个混合的电影和单词嵌入空间。
或者,我们可以使用实际的 Word2vec 代码,并在链接到电影的任何页面上运行它,但保留电影链接作为特殊标记。这样就会创建一个混合的电影和单词嵌入空间。

# 4.3 建立电影推荐系统

Expand All @@ -306,7 +306,7 @@ neighbors('Rogue One')

使用支持向量机将排名靠前的项目与排名靠后的项目分开。

前面的方法让我们对电影进行聚类,并提出建议,比如“如果你喜欢《侠盗一号》,你也应该看看《星际穿越》。”在典型的推荐系统中,我们希望根据用户评分的一系列电影来显示建议。就像我们在[第3章](ch03.html#word_embeddings)中所做的那样,我们可以使用SVM来做到这一点。让我们按照*滚石*杂志2015年评选的最佳和最差电影,并假装它们是用户评分:
前面的方法让我们对电影进行聚类,并提出建议,比如“如果你喜欢《侠盗一号》,你也应该看看《星际穿越》。”在典型的推荐系统中,我们希望根据用户评分的一系列电影来显示建议。就像我们在第三章中所做的那样,我们可以使用 SVM 来做到这一点。让我们按照*滚石*杂志 2015 年评选的最佳和最差电影,并假装它们是用户评分:

```py
best = ['Star Wars: The Force Awakens', 'The Martian (film)',
Expand All @@ -321,7 +321,7 @@ X = np.asarray([normalized_movies[movie_to_idx[movie]]
for movie in best + worst])
```

基于此构建和训练一个简单的SVM分类器很容易
基于此构建和训练一个简单的 SVM 分类器很容易

```py
clf = svm.SVC(kernel='linear')
Expand Down Expand Up @@ -382,15 +382,15 @@ rotten_X = np.asarray([normalized_movies[movie_to_idx[movie[0]]]
for movie in movies if movie[-2]])
```

这应该为我们大约一半的电影提供数据。让我们在前80%的数据上进行训练:
这应该为我们大约一半的电影提供数据。让我们在前 80%的数据上进行训练:

```py
TRAINING_CUT_OFF = int(len(rotten_X) * 0.8)
regr = LinearRegression()
regr.fit(rotten_X[:TRAINING_CUT_OFF], rotten_y[:TRAINING_CUT_OFF])
```

现在让我们看看我们在最后20%的进展如何:
现在让我们看看我们在最后 20%的进展如何:

```py
error = (regr.predict(rotten_X[TRAINING_CUT_OFF:]) -
Expand All @@ -402,7 +402,7 @@ error = (regr.predict(rotten_X[TRAINING_CUT_OFF:]) -
mean square error 0.06
```

看起来真的很令人印象深刻!但虽然这证明了线性回归的有效性,但我们的数据存在一个问题,使得预测烂番茄评分变得更容易:我们一直在训练前10000部电影,而热门电影并不总是更好,但平均来说它们得到更高的评分。
看起来真的很令人印象深刻!但虽然这证明了线性回归的有效性,但我们的数据存在一个问题,使得预测烂番茄评分变得更容易:我们一直在训练前 10000 部电影,而热门电影并不总是更好,但平均来说它们得到更高的评分。

通过将我们的预测与始终预测平均分数进行比较,我们可以大致了解我们的表现如何:

Expand Down
Loading

0 comments on commit 51349f0

Please sign in to comment.