修改在线阅读文档排版

This commit is contained in:
RuyiLuo
2022-04-21 21:08:21 +08:00
parent 1db182f635
commit cc4a7e5470
11 changed files with 278 additions and 280 deletions
+67 -67
View File
@@ -21,62 +21,62 @@
## 内容导航 ## 内容导航
### 推荐系统概述 ### 推荐系统概述
- [推荐系统的意义](/推荐系统概述/推荐系统的意义) - [1.1 推荐系统的意义](/ch01/ch1.1)
- [推荐系统架构](/推荐系统概述/推荐系统架构) - [1.2 推荐系统架构](ch01/ch1.2)
- [推荐系统技术栈](/推荐系统概述/推荐系统技术栈) - [1.3 推荐系统技术栈](ch01/ch1.3)
### 推荐系统算法基础 ### 推荐系统算法基础
#### 经典召回模型 {docsify-ignore} #### 经典召回模型 {docsify-ignore}
- **基于协同过滤的召回** - **基于协同过滤的召回**
- UserCF【已完成,待优化】 - UserCF
- ItemCF【已完成,待优化】 - ItemCF
- [Swing(Graph-based)](/推荐算法基础/经典召回模型/基于协同过滤的召回/Swing(Graph-based)) - [Swing](ch02/ch2.1/ch2.1.1/Swing)
- 矩阵分解系列(ALS,SVD++)【已完成,待优化】 - 矩阵分解
- **基于向量的召回** - **基于向量的召回**
- FM召回【未完成】 - FM召回
- **word2vec召回** - **word2vec召回**
- word2vec原理【未完成】 - word2vec原理
- Airbnb召回【未完成】 - Airbnb召回
- YoutubeDNN召回【完成一半,待优化】 - YoutubeDNN召回
- **双塔召回** - **双塔召回**
- 经典双塔【未完成】 - 经典双塔
- Youtube双塔【未完成】 - Youtube双塔
- MOBIUS【未完成】 - MOBIUS
- **图召回** - **图召回**
- [EGES](/推荐算法基础/经典召回模型/基于图的召回/EGES) - [EGES](ch02/ch2.1/ch2.1.3/EGES)
- PinSAGE【未完成】 - PinSAGE
- **序列召回** - **序列召回**
- [MIND](/推荐算法基础/经典召回模型/基于序列的召回/MIND模型) - [MIND](ch02/ch2.1/ch2.1.4/MIND)
- [SDM](/推荐算法基础/经典召回模型/基于序列的召回/SDM模型) - [SDM](ch02/ch2.1/ch2.1.4/SDM)
- **树模型召回** - **树模型召回**
- TDM【未完成】 - TDM
#### 经典排序模型 #### 经典排序模型
- **[GBDT+LR](/推荐算法基础/经典排序模型/GBDT+LR)** - **[GBDT+LR](ch02/ch2.2/ch2.2.1)**
- **特征交叉** - **特征交叉**
- [FM](/推荐算法基础/经典排序模型/特征交叉/FM) - [FM](ch02/ch2.2/ch2.2.2/FM)
- [PNN](/推荐算法基础/经典排序模型/特征交叉/PNN) - [PNN](ch02/ch2.2/ch2.2.2/PNN)
- [DCN](/推荐算法基础/经典排序模型/特征交叉/DCN) - [DCN](ch02/ch2.2/ch2.2.2/DCN)
- AutoInt【完成一半,待优化】 - AutoInt
- FiBiNET【完成一半,待优化】 - FiBiNET
- **WideNDeep系列** - **WideNDeep系列**
- **[Wide&Deep](/推荐算法基础/经典排序模型/Wide&Deep系列/Wide&Deep)** - **[Wide&Deep](ch02/ch2.2/ch2.2.3/WideNDeep)**
- **改进Deep侧** - **改进Deep侧**
- [NFM](/推荐算法基础/经典排序模型/Wide&Deep系列/NFM) - [NFM](ch02/ch2.2/ch2.2.3/NFM)
- [AFM](/推荐算法基础/经典排序模型/Wide&Deep系列/AFM) - [AFM](ch02/ch2.2/ch2.2.3/AFM)
- **改进Wide侧** - **改进Wide侧**
- [DeepFM](/推荐算法基础/经典排序模型/Wide&Deep系列/DeepFM) - [DeepFM](ch02/ch2.2/ch2.2.3/DeepFM)
- xDeepFM【未完成】 - xDeepFM
- **序列模型** - **序列模型**
- [DIN](/推荐算法基础/经典排序模型/序列模型/DIN) - [DIN](ch02/ch2.2/ch2.2.4/DIN)
- [DIEN](/推荐算法基础/经典排序模型/序列模型/DIEN) - [DIEN](ch02/ch2.2/ch2.2.4/DIEN)
- DISN【未完成】 - DISN
- BST【未完成】 - BST
- **多任务学习** - **多任务学习**
- SharedBottom【已完成,待优化】 - SharedBottom
- ESSM【已完成,待优化】 - ESSM
- MMOE【已完成,待优化】 - MMOE
- PLE【已完成,待优化】 - PLE
### 推荐系统实战 ### 推荐系统实战
@@ -87,46 +87,46 @@
- [特征工程](https://www.bilibili.com/video/BV1do4y1d7FP?p=2) - [特征工程](https://www.bilibili.com/video/BV1do4y1d7FP?p=2)
- [上分技巧](https://www.bilibili.com/video/BV1do4y1d7FP?p=3) - [上分技巧](https://www.bilibili.com/video/BV1do4y1d7FP?p=3)
- **文档** - **文档**
- [赛题理解&Baseline](/推荐系统实战/竞赛实践/markdown/赛题理解+Baseline) - [赛题理解&Baseline](ch03/ch3.1/markdown/ch3.1.1)
- [数据分析](/推荐系统实战/竞赛实践/markdown/数据分析) - [数据分析](ch03/ch3.1/markdown/ch3.1.2)
- [多路召回](/推荐系统实战/竞赛实践/markdown/多路召回) - [多路召回](ch03/ch3.1/markdown/ch3.1.3)
- [特征工程](/推荐系统实战/竞赛实践/markdown/特征工程) - [特征工程](ch03/ch3.1/markdown/ch3.1.4)
- [排序模型&模型融合](/推荐系统实战/竞赛实践/markdown/排序模型+模型融合) - [排序模型&模型融合](ch03/ch3.1/markdown/ch3.1.5)
#### 新闻推荐系统实践 #### 新闻推荐系统实践
- **视频** - **视频**
- [新闻推荐系统流程的构建视频讲解](https://datawhale.feishu.cn/minutes/obcnzns778b725r5l535j32o) - [新闻推荐系统流程的构建视频讲解](https://datawhale.feishu.cn/minutes/obcnzns778b725r5l535j32o)
- **文档** - **文档**
- **离线物料系统的构建** - **离线物料系统的构建**
- [Mysql基础](/推荐系统实战/新闻推荐系统实践/Mysql基础) - [Mysql基础](ch03/ch3.2/3.2.1.1)
- [MongoDB基础](/推荐系统实战/新闻推荐系统实践/MongoDB基础) - [MongoDB基础](ch03/ch3.2/3.2.1.2)
- [Redis基础](/推荐系统实战/新闻推荐系统实践/Redis基础) - [Redis基础](ch03/ch3.2/3.2.1.3)
- [Scrapy基础及新闻爬取实战](/推荐系统实战/新闻推荐系统实践/scrapy基础及新闻爬取实战) - [Scrapy基础及新闻爬取实战](ch03/ch3.2/3.2.1.4)
- [自动化构建用户及物料画像](/推荐系统实战/新闻推荐系统实践/自动化构建用户及物料画像) - [自动化构建用户及物料画像](ch03/ch3.2/3.2.1.5)
- **前后端基础及交互** - **前后端基础及交互**
- [前端基础及Vue实战](/推荐系统实战/新闻推荐系统实践/前端基础及Vue实战) - [前端基础及Vue实战](ch03/ch3.2/3.2.2.1)
- [flask简介及基础](/推荐系统实战/新闻推荐系统实践/flask简介及基础) - [flask简介及基础](ch03/ch3.2/3.2.2.2)
- [前后端交互](/推荐系统实战/新闻推荐系统实践/前后端交互) - [前后端交互](ch03/ch3.2/3.2.2.3)
- [推荐系统流程的构建](/推荐系统实战/新闻推荐系统实践/推荐系统流程的构建) - [推荐系统流程的构建](ch03/ch3.2/3.2.3)
- **召回** - **召回**
- 热度召回【完成一半,待优化】 - 热度召回
- 地域召回【完成一半,待优化】 - 地域召回
- [YoutubeDNN召回](/推荐系统实战/新闻推荐系统实践/YouTubeDNN召回) - [YoutubeDNN召回](ch03/ch3.2/3.2.4.3)
- [DSSM召回](/推荐系统实战/新闻推荐系统实践/DSSM召回) - [DSSM召回](ch03/ch3.2/3.2.4.4)
- DeepFM排序模型【已完成,待优化】 - DeepFM排序模型
- 规则与重排【完成一半,待优化】 - 规则与重排
- 任务监控与调度【完成一半,待优化】 - 任务监控与调度
- **当前问题汇总** - **当前问题汇总**
- [熟悉推荐系统基本流程问答整理](/推荐系统实战/新闻推荐系统实践/熟悉推荐系统基本流程问答整理) - [熟悉推荐系统基本流程问答整理](ch03/ch3.2/3.2.8.1)
- [数据库的基本使用问答整理](/推荐系统实战/新闻推荐系统实践/数据库的基本使用问答整理) - [数据库的基本使用问答整理](ch03/ch3.2/3.2.8.2)
- [离线物料系统的构建问答整理](/推荐系统实战/新闻推荐系统实践/离线物料系统的构建问答整理) - [离线物料系统的构建问答整理](ch03/ch3.2/3.2.8.3)
### 推荐系统算法面经 ### 推荐系统算法面经
- [ML与DL基础](/推荐算法面经/ML与DL基础) - [ML与DL基础](ch04/ch4.1)
- [推荐模型相关](/推荐算法面经/推荐模型相关) - [推荐模型相关](ch04/ch4.2)
- [热门技术相关](/推荐算法面经/热门技术相关) - [热门技术相关](ch04/ch4.3)
- [业务场景相关](/推荐算法面经/业务场景相关) - [业务场景相关](ch04/ch4.4)
- [HR及其他](/推荐算法面经/HR及其他) - [HR及其他](ch04/ch4.5)
## 致谢 ## 致谢
+57 -59
View File
@@ -1,93 +1,91 @@
<!-- docs/_sidebar.md --> <!-- docs/_sidebar.md -->
- [目录](README) - 目录
- [第一章 推荐系统概述]() - 第一章 推荐系统概述
- [1.1 推荐系统的意义](ch01/1.1) - [1.1 推荐系统的意义](/ch01/ch1.1)
- [1.2 推荐系统架构](ch01/1.2) - [1.2 推荐系统架构](ch01/ch1.2)
- [1.3 推荐系统技术栈](ch01/1.3) - [1.3 推荐系统技术栈](ch01/ch1.3)
- [第二章 推荐系统算法基础]() - 第二章 推荐系统算法基础
- [2.1 经典召回模型]() - 2.1 经典召回模型
- [2.1.1 基于协同过滤的召回]() - 2.1.1 基于协同过滤的召回
- [UserCF]() - UserCF
- [ItemCF]() - ItemCF
- [Swing(Graph-based)](ch02/ch2.2/ch2.2.1/Swing) - [Swing](ch02/ch2.1/ch2.1.1/Swing)
- [矩阵分解系列(ALS,SVD++)]() - 矩阵分解
- [2.1.2 基于向量的召回]() - 2.1.2 基于向量的召回
- [FM召回]() - FM召回
- [item2vec召回]() - item2vec召回
- [word2vec原理]() - word2vec原理
- [Airbnb召回]() - Airbnb召回
- [YoutubeDNN召回]() - YoutubeDNN召回
- [双塔召回]() - 双塔召回
- [经典双塔]() - 经典双塔
- [Youtube双塔]() - Youtube双塔
- [MOBIUS]() - MOBIUS
- [2.1.3 基于图的召回]() - 2.1.3 基于图的召回
- [EGES](ch02/ch2.1/ch2.1.3/EGES) - [EGES](ch02/ch2.1/ch2.1.3/EGES)
- [PinSAGE]() - PinSAGE
- [2.1.4 基于序列的召回]() - 2.1.4 基于序列的召回
- [MIND](ch02/ch2.1/ch2.1.4/MIND) - [MIND](ch02/ch2.1/ch2.1.4/MIND)
- [SDM](ch02/ch2.1/ch2.1.4/SDM) - [SDM](ch02/ch2.1/ch2.1.4/SDM)
- [2.1.5 基于树模型的召回]() - 2.1.5 基于树模型的召回
- [TDM]() - TDM
- [2.2 经典排序模型]() - 2.2 经典排序模型
- [2.2.1 GBDT+LR](ch02/ch2.2/ch2.2.1) - [2.2.1 GBDT+LR](ch02/ch2.2/ch2.2.1)
- [2.2.2 特征交叉]() - 2.2.2 特征交叉
- [FM](ch02/ch2.2/ch2.2.2/FM) - [FM](ch02/ch2.2/ch2.2.2/FM)
- [PNN](ch02/ch2.2/ch2.2.2/PNN) - [PNN](ch02/ch2.2/ch2.2.2/PNN)
- [DCN](ch02/ch2.2/ch2.2.2/DCN) - [DCN](ch02/ch2.2/ch2.2.2/DCN)
- [AutoInt]() - AutoInt
- [FiBiNet]() - FiBiNet
- [2.2.3 Wide&Deep系列]() - 2.2.3 Wide&Deep系列
- [Wide&Deep](ch02/ch2.2/ch2.2.3/WideNDeep) - [Wide&Deep](ch02/ch2.2/ch2.2.3/WideNDeep)
- [改进Deep侧]() - [NFM](ch02/ch2.2/ch2.2.3/NFM)
- [NFM](ch02/ch2.2/ch2.2.3/NFM.md) - [AFM](ch02/ch2.2/ch2.2.3/AFM)
- [AFM](ch02/ch2.2/ch2.2.3/AFM) - [DeepFM](ch02/ch2.2/ch2.2.3/DeepFM)
- [改进Wide侧]() - xDeepFM
- [DeepFM](ch02/ch2.2/ch2.2.3/DeepFM) - 2.2.4 序列模型
- [xDeepFM]()
- [2.2.4 序列模型]()
- [DIN](ch02/ch2.2/ch2.2.4/DIN) - [DIN](ch02/ch2.2/ch2.2.4/DIN)
- [DIEN](ch02/ch2.2/ch2.2.4/DIEN) - [DIEN](ch02/ch2.2/ch2.2.4/DIEN)
- [DISN]() - DISN
- [BST]() - BST
- [2.2.5 多任务学习]() - 2.2.5 多任务学习
- [SharedBottom]() - SharedBottom
- [ESSM]() - ESSM
- [MMOE]() - MMOE
- [PLE]() - PLE
- [第三章 推荐系统实战]() - 第三章 推荐系统实战
- [3.1 竞赛实践(天池入门赛-新闻推荐)]() - 3.1 天池入门赛-新闻推荐
- [3.1.1 赛题理解&Baseline](ch03/ch3.1/markdown/ch3.1.1) - [3.1.1 赛题理解&Baseline](ch03/ch3.1/markdown/ch3.1.1)
- [3.1.2 数据分析](ch03/ch3.1/markdown/ch3.1.2) - [3.1.2 数据分析](ch03/ch3.1/markdown/ch3.1.2)
- [3.1.3 多路召回](ch03/ch3.1/markdown/ch3.1.3) - [3.1.3 多路召回](ch03/ch3.1/markdown/ch3.1.3)
- [3.1.4 特征工程](ch03/ch3.1/markdown/ch3.1.4) - [3.1.4 特征工程](ch03/ch3.1/markdown/ch3.1.4)
- [3.1.5 排序模型&模型融合](ch03/ch3.1/markdown/ch3.1.5) - [3.1.5 排序模型&模型融合](ch03/ch3.1/markdown/ch3.1.5)
- [3.2 新闻推荐系统的实践]() - 3.2 新闻推荐系统的实践
- [3.2.1 离线物料系统的构建]() - 3.2.1 离线物料系统的构建
- [Mysql](ch03/ch3.2/3.2.1.1) - [Mysql](ch03/ch3.2/3.2.1.1)
- [MongoDB](ch03/ch3.2/3.2.1.2) - [MongoDB](ch03/ch3.2/3.2.1.2)
- [Redis](ch03/ch3.2/3.2.1.3) - [Redis](ch03/ch3.2/3.2.1.3)
- [Scrapy](ch03/ch3.2/3.2.1.4) - [Scrapy](ch03/ch3.2/3.2.1.4)
- [自动化构建用户及物料画像](ch03/ch3.2/3.2.1.5) - [自动化构建用户及物料画像](ch03/ch3.2/3.2.1.5)
- [3.2.2 前后端基础及交互]() - 3.2.2 前后端基础及交互
- [前端基础及Vue实战](ch03/ch3.2/3.2.2.1) - [前端基础及Vue实战](ch03/ch3.2/3.2.2.1)
- [flask简介及基础](ch03/ch3.2/3.2.2.2) - [flask简介及基础](ch03/ch3.2/3.2.2.2)
- [前后端交互](ch03/ch3.2/3.2.2.3) - [前后端交互](ch03/ch3.2/3.2.2.3)
- [3.2.3 推荐系统流程的构建](ch03/ch3.2/3.2.3) - [3.2.3 推荐系统流程的构建](ch03/ch3.2/3.2.3)
- [3.2.4 召回]() - 3.2.4 召回
- [热度召回]() - 热度召回
- [地域召回]() - 地域召回
- [YouTubeDNN召回](ch03/ch3.2/3.2.4.3) - [YouTubeDNN召回](ch03/ch3.2/3.2.4.3)
- [DSSM召回](ch03/ch3.2/3.2.4.4) - [DSSM召回](ch03/ch3.2/3.2.4.4)
- [3.2.5 DeepFM排序]() - 3.2.5 DeepFM排序
- [3.2.6 规则与重排]() - 3.2.6 规则与重排
- [3.2.7 任务调度与监控]() - 3.2.7 任务调度与监控
- [3.2.8 当前问题汇总]() - 3.2.8 当前问题汇总
- [熟悉推荐系统基本流程问答整理](ch03/ch3.2/3.2.8.1) - [熟悉推荐系统基本流程问答整理](ch03/ch3.2/3.2.8.1)
- [数据库的基本使用问答整理](ch03/ch3.2/3.2.8.2) - [数据库的基本使用问答整理](ch03/ch3.2/3.2.8.2)
- [离线物料系统的构建问答整理](ch03/ch3.2/3.2.8.3) - [离线物料系统的构建问答整理](ch03/ch3.2/3.2.8.3)
- [第四章 推荐系统算法面经]() - 第四章 推荐系统算法面经
- [4.1 ML与DL基础](ch04/ch4.1) - [4.1 ML与DL基础](ch04/ch4.1)
- [4.2 推荐模型相关](ch04/ch4.2) - [4.2 推荐模型相关](ch04/ch4.2)
- [4.3 热门技术相关](ch04/ch4.3) - [4.3 热门技术相关](ch04/ch4.3)
+2 -2
View File
@@ -32,7 +32,7 @@
</div> </div>
接下来详细介绍一下这三个模块。 接下来详细介绍一下这三个模块。
## 离线层 ### 离线层
离线层是计算量最大的一个部分,它的特点是不依赖实时数据,也不需要实时提供服务。需要实现的主要功能模块是: 离线层是计算量最大的一个部分,它的特点是不依赖实时数据,也不需要实时提供服务。需要实现的主要功能模块是:
1. 数据处理、数据存储; 1. 数据处理、数据存储;
@@ -52,7 +52,7 @@
但是同样的,如果我们只使用用户离线数据,最大的不足就是无法反应用户的实时兴趣变化,这就促使了近线层的产生。 但是同样的,如果我们只使用用户离线数据,最大的不足就是无法反应用户的实时兴趣变化,这就促使了近线层的产生。
## 近线层 ### 近线层
近线层的主要特点是准实时,它可以获得实时数据,然后快速计算提供服务,但是并不要求它和在线层一样达到几十毫秒这种延时要求。近线层的产生是同时想要弥补离线层和在线层的不足,折中的产物。 近线层的主要特点是准实时,它可以获得实时数据,然后快速计算提供服务,但是并不要求它和在线层一样达到几十毫秒这种延时要求。近线层的产生是同时想要弥补离线层和在线层的不足,折中的产物。
它适合处理一些对延时比较敏感的任务,比如: 它适合处理一些对延时比较敏感的任务,比如:
+20 -20
View File
@@ -1,4 +1,4 @@
## 1. 写在前面 ## 写在前面
MIND模型(Multi-Interest Network with Dynamic Routing) 是阿里团队2019年在CIKM上发的一篇paper,该模型依然是用在召回阶段的一个模型,解决的痛点是之前在召回阶段的模型,比如双塔,YouTubeDNN召回模型等,在模拟用户兴趣的时候,总是基于用户的历史点击,最后通过pooling的方式得到一个兴趣向量,用该向量来表示用户的兴趣,但是该篇论文的作者认为,**用一个向量来表示用户的广泛兴趣未免有点太过于单一**,这是作者基于天猫的实际场景出发的发现,每个用户每天与数百种产品互动, 而互动的产品往往来自于很多个类别,这就说明用户的兴趣极其广泛,**用一个向量是无法表示这样广泛的兴趣的**,于是乎,就自然而然的引出一个问题,**有没有可能用多个向量来表示用户的多种兴趣呢?** MIND模型(Multi-Interest Network with Dynamic Routing) 是阿里团队2019年在CIKM上发的一篇paper,该模型依然是用在召回阶段的一个模型,解决的痛点是之前在召回阶段的模型,比如双塔,YouTubeDNN召回模型等,在模拟用户兴趣的时候,总是基于用户的历史点击,最后通过pooling的方式得到一个兴趣向量,用该向量来表示用户的兴趣,但是该篇论文的作者认为,**用一个向量来表示用户的广泛兴趣未免有点太过于单一**,这是作者基于天猫的实际场景出发的发现,每个用户每天与数百种产品互动, 而互动的产品往往来自于很多个类别,这就说明用户的兴趣极其广泛,**用一个向量是无法表示这样广泛的兴趣的**,于是乎,就自然而然的引出一个问题,**有没有可能用多个向量来表示用户的多种兴趣呢?**
这篇paper的核心是胶囊网络,**该网络采用了动态路由算法能非常自然的将历史商品聚成多个集合,每个集合的历史行为进一步推断对应特定兴趣的用户表示向量。这样,对于一个特定的用户,MND输出了多个表示向量,它们代表了用户的不同兴趣。当用户再有新的交互时,通过胶囊网络,还能实时的改变用户的兴趣表示向量,做到在召回阶段的实时个性化**。那么,胶囊网络究竟是怎么做到的呢? 胶囊网络又是什么原理呢? 这篇paper的核心是胶囊网络,**该网络采用了动态路由算法能非常自然的将历史商品聚成多个集合,每个集合的历史行为进一步推断对应特定兴趣的用户表示向量。这样,对于一个特定的用户,MND输出了多个表示向量,它们代表了用户的不同兴趣。当用户再有新的交互时,通过胶囊网络,还能实时的改变用户的兴趣表示向量,做到在召回阶段的实时个性化**。那么,胶囊网络究竟是怎么做到的呢? 胶囊网络又是什么原理呢?
@@ -10,7 +10,7 @@ MIND模型(Multi-Interest Network with Dynamic Routing) 是阿里团队2019
* MIND模型之简易代码复现 * MIND模型之简易代码复现
* 总结 * 总结
## 2. 背景与动机 ## 背景与动机
本章是基于天猫APP的背景来探索十亿级别的用户个性化推荐。天猫的推荐的流程主要分为召回阶段和排序阶段。召回阶段负责检索数千个与用户兴趣相关的候选物品,之后,排序阶段预测用户与这些候选物品交互的精确概率。这篇文章做的是召回阶段的工作,来对满足用户兴趣的物品的有效检索。 本章是基于天猫APP的背景来探索十亿级别的用户个性化推荐。天猫的推荐的流程主要分为召回阶段和排序阶段。召回阶段负责检索数千个与用户兴趣相关的候选物品,之后,排序阶段预测用户与这些候选物品交互的精确概率。这篇文章做的是召回阶段的工作,来对满足用户兴趣的物品的有效检索。
作者这次的出发点是基于场景出发,在天猫的推荐场景中,作者发现**用户的兴趣存在多样性**。平均上,10亿用户访问天猫,每个用户每天与数百种产品互动。交互后的物品往往属于不同的类别,说明用户兴趣的多样性。 一张图片会更加简洁直观: 作者这次的出发点是基于场景出发,在天猫的推荐场景中,作者发现**用户的兴趣存在多样性**。平均上,10亿用户访问天猫,每个用户每天与数百种产品互动。交互后的物品往往属于不同的类别,说明用户兴趣的多样性。 一张图片会更加简洁直观:
@@ -27,8 +27,8 @@ MIND模型(Multi-Interest Network with Dynamic Routing) 是阿里团队2019
这就是MIND的提出动机以及初步思路了,这里面的核心是Multi-interest extractor layer, 而这里面重点是动态路由与胶囊网络,所以接下来先补充这方面的相关知识。 这就是MIND的提出动机以及初步思路了,这里面的核心是Multi-interest extractor layer, 而这里面重点是动态路由与胶囊网络,所以接下来先补充这方面的相关知识。
## 3. 胶囊网络与动态路由机制 ## 胶囊网络与动态路由机制
### 3.1 胶囊网络初识 ### 胶囊网络初识
Hinton大佬在2011年的时候,就首次提出了"胶囊"的概念, "胶囊"可以看成是一组聚合起来输出整个向量的小神经元组合,这个向量的每个维度(每个小神经元),代表着某个实体的某个特征。 Hinton大佬在2011年的时候,就首次提出了"胶囊"的概念, "胶囊"可以看成是一组聚合起来输出整个向量的小神经元组合,这个向量的每个维度(每个小神经元),代表着某个实体的某个特征。
胶囊网络其实可以和神经网络对比着看可能更好理解,我们知道神经网络的每一层的神经元输出的是单个的标量值,接收的输入,也是多个标量值,所以这是一种value to value的形式,而胶囊网络每一层的胶囊输出的是一个向量值,接收的输入也是多个向量,所以它是vector to vector形式的。来个图对比下就清楚了: 胶囊网络其实可以和神经网络对比着看可能更好理解,我们知道神经网络的每一层的神经元输出的是单个的标量值,接收的输入,也是多个标量值,所以这是一种value to value的形式,而胶囊网络每一层的胶囊输出的是一个向量值,接收的输入也是多个向量,所以它是vector to vector形式的。来个图对比下就清楚了:
@@ -50,7 +50,7 @@ $$
所以这里的问题,就是怎么通过动态路由机制得到$c_i$,下面是动态路由机制的过程。 所以这里的问题,就是怎么通过动态路由机制得到$c_i$,下面是动态路由机制的过程。
### 3.2 动态路由机制原理 ### 动态路由机制原理
我们先来一个胶囊结构: 我们先来一个胶囊结构:
![在这里插入图片描述](https://img-blog.csdnimg.cn/12fca14263d943318bf3d83180b55e01.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_1,color_FFFFFF,t_70,g_se,x_16#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/12fca14263d943318bf3d83180b55e01.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_1,color_FFFFFF,t_70,g_se,x_16#pic_center)
@@ -73,17 +73,17 @@ $$
Ok, 有了上面的这些铺垫,再来看MIND就会比较简单了。下面正式对MIND模型的网络架构剖析。 Ok, 有了上面的这些铺垫,再来看MIND就会比较简单了。下面正式对MIND模型的网络架构剖析。
## 4. MIND模型的网络结构与细节剖析 ## MIND模型的网络结构与细节剖析
### 4.1 网络整体结构 ### 网络整体结构
MIND网络的架构如下: MIND网络的架构如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/33b251f8dcb242ad82b2ed0313f6df73.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_2,color_FFFFFF,t_70,g_se,x_16#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/33b251f8dcb242ad82b2ed0313f6df73.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_2,color_FFFFFF,t_70,g_se,x_16#pic_center)
初步先分析这个网络结构的运作: 首先接收的输入有三类特征,用户base属性,历史行为属性以及商品的属性,用户的历史行为序列属性过了一个多兴趣提取层得到了多个兴趣胶囊,接下来和用户base属性拼接过DNN,得到了交互之后的用户兴趣。然后在训练阶段,用户兴趣和当前商品向量过一个label-aware attention,然后求softmax损失。 在服务阶段,得到用户的向量之后,就可以直接进行近邻检索,找候选商品了。 这就是宏观过程,但是,多兴趣提取层以及这个label-aware attention是在做什么事情呢? 如果单独看这个图,感觉得到多个兴趣胶囊之后,直接把这些兴趣胶囊以及用户的base属性拼接过全连接,那最终不就成了一个用户向量,此时label-aware attention的意义不就没了? 所以这个图初步感觉画的有问题,和论文里面描述的不符。所以下面先以论文为主,正式开始描述具体细节。 初步先分析这个网络结构的运作: 首先接收的输入有三类特征,用户base属性,历史行为属性以及商品的属性,用户的历史行为序列属性过了一个多兴趣提取层得到了多个兴趣胶囊,接下来和用户base属性拼接过DNN,得到了交互之后的用户兴趣。然后在训练阶段,用户兴趣和当前商品向量过一个label-aware attention,然后求softmax损失。 在服务阶段,得到用户的向量之后,就可以直接进行近邻检索,找候选商品了。 这就是宏观过程,但是,多兴趣提取层以及这个label-aware attention是在做什么事情呢? 如果单独看这个图,感觉得到多个兴趣胶囊之后,直接把这些兴趣胶囊以及用户的base属性拼接过全连接,那最终不就成了一个用户向量,此时label-aware attention的意义不就没了? 所以这个图初步感觉画的有问题,和论文里面描述的不符。所以下面先以论文为主,正式开始描述具体细节。
### 4.2 任务目标 ### 任务目标
召回任务的目标是对于每一个用户$u \in \mathcal{U}$从十亿规模的物品池$\mathcal{I}$检索出包含与用户兴趣相关的上千个物品集。 召回任务的目标是对于每一个用户$u \in \mathcal{U}$从十亿规模的物品池$\mathcal{I}$检索出包含与用户兴趣相关的上千个物品集。
#### 4.2.1 模型的输入 #### 模型的输入
对于模型,每个样本的输入可以表示为一个三元组:$\left(\mathcal{I}_{u}, \mathcal{P}_{u}, \mathcal{F}_{i}\right)$,其中$\mathcal{I}_{u}$代表与用户$u$交互过的物品集,即用户的历史行为;$\mathcal{P}_{u}$表示用户的属性,例如性别、年龄等;$\mathcal{F}_{i}$定义为目标物品$i$的一些特征,例如物品id和种类id等。 对于模型,每个样本的输入可以表示为一个三元组:$\left(\mathcal{I}_{u}, \mathcal{P}_{u}, \mathcal{F}_{i}\right)$,其中$\mathcal{I}_{u}$代表与用户$u$交互过的物品集,即用户的历史行为;$\mathcal{P}_{u}$表示用户的属性,例如性别、年龄等;$\mathcal{F}_{i}$定义为目标物品$i$的一些特征,例如物品id和种类id等。
#### 4.2.2 任务描述 #### 任务描述
MIND的核心任务是学习一个从原生特征映射到**用户表示**的函数,用户表示定义为: MIND的核心任务是学习一个从原生特征映射到**用户表示**的函数,用户表示定义为:
$$ $$
\mathrm{V}_{u}=f_{u s e r}\left(\mathcal{I}_{u}, \mathcal{P}_{u}\right) \mathrm{V}_{u}=f_{u s e r}\left(\mathcal{I}_{u}, \mathcal{P}_{u}\right)
@@ -95,27 +95,27 @@ $$
\overrightarrow{\mathbf{e}}_{i}=f_{\text {item }}\left(\mathcal{F}_{i}\right) \overrightarrow{\mathbf{e}}_{i}=f_{\text {item }}\left(\mathcal{F}_{i}\right)
$$ $$
其中,$\overrightarrow{\mathbf{e}}_{i} \in \mathbb{R}^{d \times 1}, \quad f_{i t e m}(\cdot)$表示一个embedding&pooling层。 其中,$\overrightarrow{\mathbf{e}}_{i} \in \mathbb{R}^{d \times 1}, \quad f_{i t e m}(\cdot)$表示一个embedding&pooling层。
#### 4.2.3 最终结果 #### 最终结果
根据评分函数检索(根据**目标物品与用户表示向量的内积的最大值作为相似度依据**,DIN的Attention部分也是以这种方式来衡量两者的相似度),得到top N个候选项: 根据评分函数检索(根据**目标物品与用户表示向量的内积的最大值作为相似度依据**,DIN的Attention部分也是以这种方式来衡量两者的相似度),得到top N个候选项:
$$ $$
f_{\text {score }}\left(\mathbf{V}_{u}, \overrightarrow{\mathbf{e}}_{i}\right)=\max _{1 \leq k \leq K} \overrightarrow{\mathbf{e}}_{i}^{\mathrm{T}} \overrightarrow{\mathbf{V}}_{u}^{\mathrm{k}} f_{\text {score }}\left(\mathbf{V}_{u}, \overrightarrow{\mathbf{e}}_{i}\right)=\max _{1 \leq k \leq K} \overrightarrow{\mathbf{e}}_{i}^{\mathrm{T}} \overrightarrow{\mathbf{V}}_{u}^{\mathrm{k}}
$$ $$
### 4.3 Embedding & Pooling层 ### Embedding & Pooling层
Embedding层的输入由三部分组成,用户属性$\mathcal{P}_{u}$、用户行为$\mathcal{I}_{u}$和目标物品标签$\mathcal{F}_{i}$。每一部分都由多个id特征组成,则是一个高维的稀疏数据,因此需要Embedding技术将其映射为低维密集向量。具体来说, Embedding层的输入由三部分组成,用户属性$\mathcal{P}_{u}$、用户行为$\mathcal{I}_{u}$和目标物品标签$\mathcal{F}_{i}$。每一部分都由多个id特征组成,则是一个高维的稀疏数据,因此需要Embedding技术将其映射为低维密集向量。具体来说,
* 对于$\mathcal{P}_{u}$的id特征(年龄、性别等)是将其Embedding的向量进行Concat,组成用户属性Embedding$\overrightarrow{\mathbf{p}}_{u}$ * 对于$\mathcal{P}_{u}$的id特征(年龄、性别等)是将其Embedding的向量进行Concat,组成用户属性Embedding$\overrightarrow{\mathbf{p}}_{u}$
* 目标物品$\mathcal{F}_{i}$通常包含其他分类特征id(品牌id、店铺id等) ,这些特征有利于物品的冷启动问题,需要将所有的分类特征的Embedding向量进行平均池化,得到一个目标物品向量$\overrightarrow{\mathbf{e}}_{i}$ * 目标物品$\mathcal{F}_{i}$通常包含其他分类特征id(品牌id、店铺id等) ,这些特征有利于物品的冷启动问题,需要将所有的分类特征的Embedding向量进行平均池化,得到一个目标物品向量$\overrightarrow{\mathbf{e}}_{i}$
* 对于用户行为$\mathcal{I}_{u}$,由物品的Embedding向量组成用户行为Embedding列表$E_{u}=\overrightarrow{\mathbf{e}}_{j}, j \in \mathcal{I}_{u}$ 当然这里不仅只有物品embedding哈,也可能有类别,品牌等其他的embedding信息。 * 对于用户行为$\mathcal{I}_{u}$,由物品的Embedding向量组成用户行为Embedding列表$E_{u}=\overrightarrow{\mathbf{e}}_{j}, j \in \mathcal{I}_{u}$ 当然这里不仅只有物品embedding哈,也可能有类别,品牌等其他的embedding信息。
### 4.4 Multi-Interest Extractor Layer(核心) ### Multi-Interest Extractor Layer(核心)
作者认为,单一的向量不足以表达用户的多兴趣。所以作者采用**多个表示向量**来分别表示用户不同的兴趣。通过这个方式,在召回阶段,用户的多兴趣可以分别考虑,对于兴趣的每一个方面,能够更精确的进行物品检索。 作者认为,单一的向量不足以表达用户的多兴趣。所以作者采用**多个表示向量**来分别表示用户不同的兴趣。通过这个方式,在召回阶段,用户的多兴趣可以分别考虑,对于兴趣的每一个方面,能够更精确的进行物品检索。
为了学习多兴趣表示,作者利用胶囊网络表示学习的动态路由将用户的历史行为分组到多个簇中。来自一个簇的物品应该密切相关,并共同代表用户兴趣的一个特定方面。 为了学习多兴趣表示,作者利用胶囊网络表示学习的动态路由将用户的历史行为分组到多个簇中。来自一个簇的物品应该密切相关,并共同代表用户兴趣的一个特定方面。
由于多兴趣提取器层的设计灵感来自于胶囊网络表示学习的动态路由,所以这里作者回顾了动态路由机制。当然,如果之前对胶囊网络或动态路由不了解,这里读起来就会有点艰难,但由于我上面进行了铺垫,这里就直接拿过原文并解释即可。 由于多兴趣提取器层的设计灵感来自于胶囊网络表示学习的动态路由,所以这里作者回顾了动态路由机制。当然,如果之前对胶囊网络或动态路由不了解,这里读起来就会有点艰难,但由于我上面进行了铺垫,这里就直接拿过原文并解释即可。
#### 4.4.1 动态路由 #### 动态路由
动态路由是胶囊网络中的迭代学习算法,用于学习低水平胶囊和高水平胶囊之间的路由对数(logit)$b_{ij}$,来得到高水平胶囊的表示。 动态路由是胶囊网络中的迭代学习算法,用于学习低水平胶囊和高水平胶囊之间的路由对数(logit)$b_{ij}$,来得到高水平胶囊的表示。
我们假设胶囊网络有两层,即低水平胶囊$\vec{c}_{i}^{l} \in \mathbb{R}^{N_{l} \times 1}, i \in\{1, \ldots, m\}$和高水平胶囊$\vec{c}_{j}^{h} \in \mathbb{R}^{N_{h} \times 1}, j \in\{1, \ldots, n\}$,其中$m,n$表示胶囊的个数, $N_l,N_h$表示胶囊的维度。 路由对数$b_{ij}$计算公式如下: 我们假设胶囊网络有两层,即低水平胶囊$\vec{c}_{i}^{l} \in \mathbb{R}^{N_{l} \times 1}, i \in\{1, \ldots, m\}$和高水平胶囊$\vec{c}_{j}^{h} \in \mathbb{R}^{N_{h} \times 1}, j \in\{1, \ldots, n\}$,其中$m,n$表示胶囊的个数, $N_l,N_h$表示胶囊的维度。 路由对数$b_{ij}$计算公式如下:
@@ -151,7 +151,7 @@ $$
所以,这样解释完之后就会发现,其实上面的一顿操作就是说的传统的动态路由机制。 所以,这样解释完之后就会发现,其实上面的一顿操作就是说的传统的动态路由机制。
#### 4.4.2 B2I动态路由 #### B2I动态路由
作者设计的多兴趣提取层就是就是受到了上述胶囊网络的启发。 作者设计的多兴趣提取层就是就是受到了上述胶囊网络的启发。
如果把用户的行为序列看成是行为胶囊, 把用户的多兴趣看成兴趣胶囊,那么多兴趣提取层就是利用动态路由机制学习行为胶囊`->`兴趣胶囊的映射关系。但是原始路由算法无法直接应用于处理用户行为数据。因此,提出了**行为(Behavior)到兴趣(Interest)B2I)动态路由**来自适应地将用户的行为聚合到兴趣表示向量中,它与原始路由算法有三个不同之处: 如果把用户的行为序列看成是行为胶囊, 把用户的多兴趣看成兴趣胶囊,那么多兴趣提取层就是利用动态路由机制学习行为胶囊`->`兴趣胶囊的映射关系。但是原始路由算法无法直接应用于处理用户行为数据。因此,提出了**行为(Behavior)到兴趣(Interest)B2I)动态路由**来自适应地将用户的行为聚合到兴趣表示向量中,它与原始路由算法有三个不同之处:
@@ -176,7 +176,7 @@ $$
![在这里插入图片描述](https://img-blog.csdnimg.cn/37cc4943b91c494d987a8aa844077c42.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_1,color_FFFFFF,t_70,g_se,x_16#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/37cc4943b91c494d987a8aa844077c42.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_1,color_FFFFFF,t_70,g_se,x_16#pic_center)
应该很好理解了吧。 应该很好理解了吧。
### 4.5 Label-aware Attention Layer ### Label-aware Attention Layer
通过多兴趣提取器层,从用户的行为embedding中生成多个兴趣胶囊。不同的兴趣胶囊代表用户兴趣的不同方面,相应的兴趣胶囊用于评估用户对特定类别的偏好。所以,在训练的期间,最后需要设置一个Label-aware的注意力层,对于当前的商品,根据相关性选择最相关的兴趣胶囊。这里其实就是一个普通的注意力机制,和DIN里面的那个注意力层基本上是一模一样,计算公式如下: 通过多兴趣提取器层,从用户的行为embedding中生成多个兴趣胶囊。不同的兴趣胶囊代表用户兴趣的不同方面,相应的兴趣胶囊用于评估用户对特定类别的偏好。所以,在训练的期间,最后需要设置一个Label-aware的注意力层,对于当前的商品,根据相关性选择最相关的兴趣胶囊。这里其实就是一个普通的注意力机制,和DIN里面的那个注意力层基本上是一模一样,计算公式如下:
$$ $$
\begin{aligned} \begin{aligned}
@@ -187,7 +187,7 @@ $$
首先这里的$\overrightarrow{\boldsymbol{e}}_{i}$表示当前的商品向量,$V_u$表示用户的多兴趣向量组合,里面有$K$个向量,表示用户的$K$的兴趣。用户的各个兴趣向量与目标商品做内积,然后softmax转成权重,然后反乘到多个兴趣向量进行加权求和。 但是这里需要注意的一个小点,就是这里做内积求完相似性之后,先做了一个指数操作,**这个操作其实能放大或缩小相似程度**,至于放大或者缩小的程度,由$p$控制。 比如某个兴趣向量与当前商品非常相似,那么再进行指数操作之后,如果$p$也很大,那么显然这个兴趣向量就占了主导作用。$p$是一个可调节的参数来调整注意力分布。当$p$接近0,每一个兴趣胶囊都得到相同的关注。当$p$大于1时,随着$p$的增加,具有较大值的点积将获得越来越多的权重。考虑极限情况,当$p$趋近于无穷大时,注意机制就变成了一种硬注意,选关注最大的值而忽略其他值。在实验中,发现使用硬注意导致更快的收敛。 首先这里的$\overrightarrow{\boldsymbol{e}}_{i}$表示当前的商品向量,$V_u$表示用户的多兴趣向量组合,里面有$K$个向量,表示用户的$K$的兴趣。用户的各个兴趣向量与目标商品做内积,然后softmax转成权重,然后反乘到多个兴趣向量进行加权求和。 但是这里需要注意的一个小点,就是这里做内积求完相似性之后,先做了一个指数操作,**这个操作其实能放大或缩小相似程度**,至于放大或者缩小的程度,由$p$控制。 比如某个兴趣向量与当前商品非常相似,那么再进行指数操作之后,如果$p$也很大,那么显然这个兴趣向量就占了主导作用。$p$是一个可调节的参数来调整注意力分布。当$p$接近0,每一个兴趣胶囊都得到相同的关注。当$p$大于1时,随着$p$的增加,具有较大值的点积将获得越来越多的权重。考虑极限情况,当$p$趋近于无穷大时,注意机制就变成了一种硬注意,选关注最大的值而忽略其他值。在实验中,发现使用硬注意导致更快的收敛。
>理解:$p$小意味着所有的相似程度都缩小了, 使得之间的差距会变小,所以相当于每个胶囊都会受到关注,而越大的话,使得各个相似性差距拉大,相似程度越大的会更大,就类似于贫富差距, 最终使得只关注于比较大的胶囊。 >理解:$p$小意味着所有的相似程度都缩小了, 使得之间的差距会变小,所以相当于每个胶囊都会受到关注,而越大的话,使得各个相似性差距拉大,相似程度越大的会更大,就类似于贫富差距, 最终使得只关注于比较大的胶囊。
### 4.6 训练与服务 ### 训练与服务
得到用户向量$\overrightarrow{\boldsymbol{v}}_{u}$和标签物品embedding$\vec{e}_{i}$后,计算用户$u$与标签物品$i$交互的概率: 得到用户向量$\overrightarrow{\boldsymbol{v}}_{u}$和标签物品embedding$\vec{e}_{i}$后,计算用户$u$与标签物品$i$交互的概率:
$$ $$
\operatorname{Pr}(i \mid u)=\operatorname{Pr}\left(\vec{e}_{i} \mid \vec{v}_{u}\right)=\frac{\exp \left(\vec{v}_{u}^{\mathrm{T} \rightarrow}\right)}{\sum_{j \in I} \exp \left(\vec{v}_{u}^{\mathrm{T}} \vec{e}_{j}\right)} \operatorname{Pr}(i \mid u)=\operatorname{Pr}\left(\vec{e}_{i} \mid \vec{v}_{u}\right)=\frac{\exp \left(\vec{v}_{u}^{\mathrm{T} \rightarrow}\right)}{\sum_{j \in I} \exp \left(\vec{v}_{u}^{\mathrm{T}} \vec{e}_{j}\right)}
@@ -202,10 +202,10 @@ $$
这就是整个MIND模型的细节了。 这就是整个MIND模型的细节了。
## 5. MIND模型之简易代码复现 ## MIND模型之简易代码复现
下面参考Deepctr,用简易的代码实现下MIND,并在新闻推荐的数据集上进行召回任务。 下面参考Deepctr,用简易的代码实现下MIND,并在新闻推荐的数据集上进行召回任务。
### 5.1 整个代码架构 ### 整个代码架构
整个MIND模型算是参考deepmatch修改的一个简易版本: 整个MIND模型算是参考deepmatch修改的一个简易版本:
@@ -400,7 +400,7 @@ item_embs = item_embedding_model.predict(all_item_model_input, batch_size=2 ** 1
``` ```
这样就能拿到用户和item的embedding, 接下来近邻检索完成召回过程。 注意,MIND的话,这里是拿到的多个兴趣向量的。 这样就能拿到用户和item的embedding, 接下来近邻检索完成召回过程。 注意,MIND的话,这里是拿到的多个兴趣向量的。
## 6. 小 ## 总
今天这篇文章整理的MIND,这是一个多兴趣的召回模型,核心是兴趣提取层,该层通过动态路由机制能够自动的对用户的历史行为序列进行聚类,得到多个兴趣向量,这样能在召回阶段捕获到用户的广泛兴趣,从而召回更好的候选商品。 今天这篇文章整理的MIND,这是一个多兴趣的召回模型,核心是兴趣提取层,该层通过动态路由机制能够自动的对用户的历史行为序列进行聚类,得到多个兴趣向量,这样能在召回阶段捕获到用户的广泛兴趣,从而召回更好的候选商品。
+12 -12
View File
@@ -1,4 +1,4 @@
## 1. 写在前面 ## 写在前面
SDM模型(Sequential Deep Matching Model),是阿里团队在2019年CIKM上的一篇paper。和MIND模型一样,是一种序列召回模型,研究的依然是如何通过用户的历史行为序列去学习到用户的丰富兴趣。 对于MIND,我们已经知道是基于胶囊网络的动态路由机制,设计了一个动态兴趣提取层,把用户的行为序列通过路由机制聚类,然后映射成了多个兴趣胶囊,以此来获取到用户的广泛兴趣。而SDM模型,是先把用户的历史序列根据交互的时间分成了短期和长期两类,然后从**短期会话**和**长期行为**中分别采取**相应的措施(短期的RNN+多头注意力, 长期的Att Net)** 去学习到用户的短期兴趣和长期行为偏好,并**巧妙的设计了一个门控网络==有选择==的将长短期兴趣进行融合**,以此得到用户的最终兴趣向量。 这篇paper中的一些亮点,比如长期偏好的行为表示,多头注意力机制学习多兴趣,长短期兴趣的融合机制等,又给了一些看待问题的新角度,同时,给出了我们一种利用历史行为序列去捕捉用户动态偏好的新思路。 SDM模型(Sequential Deep Matching Model),是阿里团队在2019年CIKM上的一篇paper。和MIND模型一样,是一种序列召回模型,研究的依然是如何通过用户的历史行为序列去学习到用户的丰富兴趣。 对于MIND,我们已经知道是基于胶囊网络的动态路由机制,设计了一个动态兴趣提取层,把用户的行为序列通过路由机制聚类,然后映射成了多个兴趣胶囊,以此来获取到用户的广泛兴趣。而SDM模型,是先把用户的历史序列根据交互的时间分成了短期和长期两类,然后从**短期会话**和**长期行为**中分别采取**相应的措施(短期的RNN+多头注意力, 长期的Att Net)** 去学习到用户的短期兴趣和长期行为偏好,并**巧妙的设计了一个门控网络==有选择==的将长短期兴趣进行融合**,以此得到用户的最终兴趣向量。 这篇paper中的一些亮点,比如长期偏好的行为表示,多头注意力机制学习多兴趣,长短期兴趣的融合机制等,又给了一些看待问题的新角度,同时,给出了我们一种利用历史行为序列去捕捉用户动态偏好的新思路。
这篇paper依然是从引言开始, 介绍SDM模型提出的动机以及目前方法存在的不足(why), 接下来就是SDM的网络模型架构(what), 这里面的关键是如何从短期会话和长期行为两个方面学习到用户的短期长期偏好(how),最后,依然是简易代码实现。 这篇paper依然是从引言开始, 介绍SDM模型提出的动机以及目前方法存在的不足(why), 接下来就是SDM的网络模型架构(what), 这里面的关键是如何从短期会话和长期行为两个方面学习到用户的短期长期偏好(how),最后,依然是简易代码实现。
@@ -8,7 +8,7 @@ SDM模型(Sequential Deep Matching Model),是阿里团队在2019年CIKM上的
* SDM的网络结构与细节 * SDM的网络结构与细节
* SDM模型代码复现 * SDM模型代码复现
## 2. 背景与动机 ## 背景与动机
这里要介绍该模型提出的动机,即why要有这样的一个模型? 这里要介绍该模型提出的动机,即why要有这样的一个模型?
一个好的推荐系统应该是能精确的捕捉用户兴趣偏好以及能对他们当前需求进行快速响应的,往往工业上的推荐系统,为了能快速响应, 一般会把整个推荐流程分成召回和排序两个阶段,先通过召回,从海量商品中得到一个小的候选集,然后再给到排序模型做精确的筛选操作。 这也是目前推荐系统的一个范式了。在这个过程中,召回模块所检索到的候选对象的质量在整个系统中起着至关重要的作用。 一个好的推荐系统应该是能精确的捕捉用户兴趣偏好以及能对他们当前需求进行快速响应的,往往工业上的推荐系统,为了能快速响应, 一般会把整个推荐流程分成召回和排序两个阶段,先通过召回,从海量商品中得到一个小的候选集,然后再给到排序模型做精确的筛选操作。 这也是目前推荐系统的一个范式了。在这个过程中,召回模块所检索到的候选对象的质量在整个系统中起着至关重要的作用。
@@ -44,8 +44,8 @@ SDM模型(Sequential Deep Matching Model),是阿里团队在2019年CIKM上的
这就是动机与背景总结啦。 那么接下来,SDM究竟是如何学习短期和长期表示,又是如何融合的? 为什么要这么玩? 这就是动机与背景总结啦。 那么接下来,SDM究竟是如何学习短期和长期表示,又是如何融合的? 为什么要这么玩?
## 3. SDM的网络结构与细节剖析 ## SDM的网络结构与细节剖析
### 3.1 问题定义 ### 问题定义
这里本来直接看模型结构,但感觉还是先过一下问题定义吧,毕竟这次涉及到了会话,还有几个小规则。 这里本来直接看模型结构,但感觉还是先过一下问题定义吧,毕竟这次涉及到了会话,还有几个小规则。
$\mathcal{U}$表示用户集合,$\mathcal{I}$表示item集合,模型考虑在时间$t$,是否用户$u$会对$i$产生交互。 对于$u$, 我们能够得到它的历史行为序列,那么先说一下如何进行会话的划分, 这里有三个规则: $\mathcal{U}$表示用户集合,$\mathcal{I}$表示item集合,模型考虑在时间$t$,是否用户$u$会对$i$产生交互。 对于$u$, 我们能够得到它的历史行为序列,那么先说一下如何进行会话的划分, 这里有三个规则:
@@ -59,7 +59,7 @@ $\mathcal{U}$表示用户集合,$\mathcal{I}$表示item集合,模型考虑
下面要开那三个盲盒操作,即短期行为学习,长期行为学习以及门控融合机制。但在这之前,得先说一个东西,就是输入层这里, 要带物品的side infomation,比如物品的item ID, 物品的品牌ID,商铺ID, 类别ID等等, 那你说,为啥要单独说呢? 之前的模型不也有, 但是这里在利用方式上有些不一样需要注意。 下面要开那三个盲盒操作,即短期行为学习,长期行为学习以及门控融合机制。但在这之前,得先说一个东西,就是输入层这里, 要带物品的side infomation,比如物品的item ID, 物品的品牌ID,商铺ID, 类别ID等等, 那你说,为啥要单独说呢? 之前的模型不也有, 但是这里在利用方式上有些不一样需要注意。
### 3.2 Input Embedding with side Information ### Input Embedding with side Information
在淘宝的推荐场景中,作者发现, 顾客与物品产生交互行为的时候,不仅考虑特定的商品本身,还考虑产品, 商铺,价格等,这个显然。所以,这里对于一个商品来说,不仅要用到Item ID,还用了更多的side info信息,包括`leat category, fist level category, brand,shop` 在淘宝的推荐场景中,作者发现, 顾客与物品产生交互行为的时候,不仅考虑特定的商品本身,还考虑产品, 商铺,价格等,这个显然。所以,这里对于一个商品来说,不仅要用到Item ID,还用了更多的side info信息,包括`leat category, fist level category, brand,shop`
所以,假设用户的短期行为是$\mathcal{S}^{u}=\left[i_{1}^{u}, \ldots, i_{t}^{u}, \ldots, i_{m}^{u}\right]$ 这里面的每个商品$i_t^u$其实有5个属性表示了,每个属性本质是ID,但转成embedding之后,就得到了5个embedding, 所以这里就涉及到了融合问题。 这里用$\boldsymbol{e}_{{i}^u_t} \in \mathbb{R}^{d \times 1}$来表示每个$i_t^u$,但这里不是embedding的pooling操作,而是Concat 所以,假设用户的短期行为是$\mathcal{S}^{u}=\left[i_{1}^{u}, \ldots, i_{t}^{u}, \ldots, i_{m}^{u}\right]$ 这里面的每个商品$i_t^u$其实有5个属性表示了,每个属性本质是ID,但转成embedding之后,就得到了5个embedding, 所以这里就涉及到了融合问题。 这里用$\boldsymbol{e}_{{i}^u_t} \in \mathbb{R}^{d \times 1}$来表示每个$i_t^u$,但这里不是embedding的pooling操作,而是Concat
@@ -78,7 +78,7 @@ Ok,输入这里说完了之后,就直接开盲盒, 不按照论文里面
![在这里插入图片描述](https://img-blog.csdnimg.cn/d297bf36d8c54b349dc666259b891927.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_2,color_FFFFFF,t_70,g_se,x_16#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/d297bf36d8c54b349dc666259b891927.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA57-75rua55qE5bCPQOW8ug==,size_2,color_FFFFFF,t_70,g_se,x_16#pic_center)
这里正好三个框把盒子框住了,下面剖析出每个来就行啦。 这里正好三个框把盒子框住了,下面剖析出每个来就行啦。
### 3.3 短期用户行为建模 ### 短期用户行为建模
这里短期用户行为是下面的那个框, 接收的输入,首先是用户最近的那次会话,里面各个商品加入了side info信息之后,有了最终的embedding表示$\left[\boldsymbol{e}_{i_{1}^{u}}, \ldots, \boldsymbol{e}_{i_{t}^{u}}\right]$。 这里短期用户行为是下面的那个框, 接收的输入,首先是用户最近的那次会话,里面各个商品加入了side info信息之后,有了最终的embedding表示$\left[\boldsymbol{e}_{i_{1}^{u}}, \ldots, \boldsymbol{e}_{i_{t}^{u}}\right]$。
这个东西,首先要过LSTM,学习序列信息,这个感觉不用多说,直接上公式: 这个东西,首先要过LSTM,学习序列信息,这个感觉不用多说,直接上公式:
@@ -124,7 +124,7 @@ $$
$$ $$
其中$s_{t}^{u} \in \mathbb{R}^{d \times 1}$,这样短期行为兴趣就修成了正果。 其中$s_{t}^{u} \in \mathbb{R}^{d \times 1}$,这样短期行为兴趣就修成了正果。
### 3.4 用户长期行为建模 ### 用户长期行为建模
从长期的视角来看,用户在不同的维度上可能积累了广泛的兴趣,用户可能经常访问一组类似的商店,并反复购买属于同一类别的商品。 所以长期行为$\mathcal{L}^{u}$来自于不同的特征尺度。 从长期的视角来看,用户在不同的维度上可能积累了广泛的兴趣,用户可能经常访问一组类似的商店,并反复购买属于同一类别的商品。 所以长期行为$\mathcal{L}^{u}$来自于不同的特征尺度。
$$ $$
\mathcal{L}^{u}=\left\{\mathcal{L}_{f}^{u} \mid f \in \mathcal{F}\right\} \mathcal{L}^{u}=\left\{\mathcal{L}_{f}^{u} \mid f \in \mathcal{F}\right\}
@@ -144,7 +144,7 @@ $$
\end{aligned} \end{aligned}
$$ $$
这里的$\boldsymbol{p}^{u} \in \mathbb{R}^{d \times 1}$ 这样就得到了用户的长期兴趣表示。 这里的$\boldsymbol{p}^{u} \in \mathbb{R}^{d \times 1}$ 这样就得到了用户的长期兴趣表示。
### 3.5 短长期兴趣融合 ### 短长期兴趣融合
长短期兴趣融合这里,作者发现之前模型往往喜欢直接拼接起来,或者加和,注意力加权等,但作者认为这样不能很好的将两类兴趣融合起来,因为长期序列里面,其实只有很少的一部分行为和当前有关。那么这样的话,直接无脑融合是有问题的。所以这里作者用了一种较为巧妙的方式,即门控机制: 长短期兴趣融合这里,作者发现之前模型往往喜欢直接拼接起来,或者加和,注意力加权等,但作者认为这样不能很好的将两类兴趣融合起来,因为长期序列里面,其实只有很少的一部分行为和当前有关。那么这样的话,直接无脑融合是有问题的。所以这里作者用了一种较为巧妙的方式,即门控机制:
$$ $$
G_{t}^{u}=\operatorname{sigmoid}\left(\boldsymbol{W}^{1} \boldsymbol{e}_{u}+\boldsymbol{W}^{2} s_{t}^{u}+\boldsymbol{W}^{3} \boldsymbol{p}^{u}+b\right) \\ G_{t}^{u}=\operatorname{sigmoid}\left(\boldsymbol{W}^{1} \boldsymbol{e}_{u}+\boldsymbol{W}^{2} s_{t}^{u}+\boldsymbol{W}^{3} \boldsymbol{p}^{u}+b\right) \\
@@ -161,12 +161,12 @@ $$
==这其实又给我们提供了一种两个向量融合的一种新思路,并不一定非得加权或者拼接或者相加了,还可以通过门控机制让网络自己学== ==这其实又给我们提供了一种两个向量融合的一种新思路,并不一定非得加权或者拼接或者相加了,还可以通过门控机制让网络自己学==
## 4. SDM模型的简易复现 ## SDM模型的简易复现
下面参考DeepMatch,用简易的代码实现下SDM,并在新闻推荐的数据集上进行召回任务。 下面参考DeepMatch,用简易的代码实现下SDM,并在新闻推荐的数据集上进行召回任务。
首先,下面分析SDM的整体架构,从代码层面看运行流程, 然后就这里面几个关键的细节进行说明。 首先,下面分析SDM的整体架构,从代码层面看运行流程, 然后就这里面几个关键的细节进行说明。
### 4.1 模型的输入 ### 模型的输入
对于SDM模型,由于它是将用户的行为序列分成了会话的形式,所以在构造SDM模型输入方面和前面的MIND以及YouTubeDNN有很大的不同了,所以这里需要先重点强调下输入。 对于SDM模型,由于它是将用户的行为序列分成了会话的形式,所以在构造SDM模型输入方面和前面的MIND以及YouTubeDNN有很大的不同了,所以这里需要先重点强调下输入。
在为SDM产生数据集的时候, 需要传入短期会话的长度以及长期会话的长度, 这样, 对于一个行为序列,构造数据集的时候要按照两个长度分成短期行为和长期行为两种,并且每一种都需要指明真实的序列长度。另外,由于这里用到了文章的side info信息,所以我这里在之前列的基础上加入了文章的两个类别特征分别是cat_1和cat_2,作为文章的side info。 这个产生数据集的代码如下: 在为SDM产生数据集的时候, 需要传入短期会话的长度以及长期会话的长度, 这样, 对于一个行为序列,构造数据集的时候要按照两个长度分成短期行为和长期行为两种,并且每一种都需要指明真实的序列长度。另外,由于这里用到了文章的side info信息,所以我这里在之前列的基础上加入了文章的两个类别特征分别是cat_1和cat_2,作为文章的side info。 这个产生数据集的代码如下:
@@ -238,7 +238,7 @@ def get_data_set(click_data, seq_short_len=5, seq_prefer_len=50):
``` ```
思路和之前的是一样的,无非就是根据会话的长短,把之前的一个长行为序列划分成了短期和长期两个,然后加入两个新的side info特征。 思路和之前的是一样的,无非就是根据会话的长短,把之前的一个长行为序列划分成了短期和长期两个,然后加入两个新的side info特征。
### 4.2 模型的代码架构 ### 模型的代码架构
整个SDM模型算是参考deepmatch修改的一个简易版本: 整个SDM模型算是参考deepmatch修改的一个简易版本:
```python ```python
@@ -384,7 +384,7 @@ item_feature_columns = [SparseFeat('doc_id', feature_max_idx['article_id'], embe
而后面的那块是为了模型训练完之后,拿用户embedding和item embedding用的, 这个在MIND那篇文章里作了解释。 而后面的那块是为了模型训练完之后,拿用户embedding和item embedding用的, 这个在MIND那篇文章里作了解释。
## 5. 小 ## 总
今天整理的是SDM,这也是一个标准的序列推荐召回模型,主要还是研究用户的序列,不过这篇paper里面一个有意思的点就是把用户的行为训练以会话的形式进行切分,然后再根据时间,分成了短期会话和长期会话,然后分别采用不同的策略去学习用户的短期兴趣和长期兴趣。 今天整理的是SDM,这也是一个标准的序列推荐召回模型,主要还是研究用户的序列,不过这篇paper里面一个有意思的点就是把用户的行为训练以会话的形式进行切分,然后再根据时间,分成了短期会话和长期会话,然后分别采用不同的策略去学习用户的短期兴趣和长期兴趣。
* 对于短期会话,可能和当前预测相关性较大,所以首先用RNN来学习序列信息,然后采用多头注意力机制得到用户的多兴趣, 隐隐约约感觉多头注意力机制还真有种能聚类的功效,接下来就是和用户的base向量进行注意力融合得到短期兴趣 * 对于短期会话,可能和当前预测相关性较大,所以首先用RNN来学习序列信息,然后采用多头注意力机制得到用户的多兴趣, 隐隐约约感觉多头注意力机制还真有种能聚类的功效,接下来就是和用户的base向量进行注意力融合得到短期兴趣
* 长期会话序列中,每个side info信息进行分开,然后分别进行注意力编码融合得到 * 长期会话序列中,每个side info信息进行分开,然后分别进行注意力编码融合得到
+45 -45
View File
@@ -11,11 +11,11 @@
# 一、 Ubuntu下安装MySQL # Ubuntu下安装MySQL
安装教程是在`Ubuntu20.04`下进行的,安装的MySQL版本为`8.0.27` 安装教程是在`Ubuntu20.04`下进行的,安装的MySQL版本为`8.0.27`
## 1.1 安装 ## 安装
```bash ```bash
sudo apt install mysql-server mysql-client sudo apt install mysql-server mysql-client
@@ -55,7 +55,7 @@ sudo service mysql status
## 1.2 配置MySQL的安全性 ## 配置MySQL的安全性
1. 首先,运行命令`mysql_secure_installation` 1. 首先,运行命令`mysql_secure_installation`
@@ -170,7 +170,7 @@ sudo service mysql status
## 1.3 以root用户登录 ## 以root用户登录
在MySQL 8.0上,root 用户默认通过`auth_socket`插件授权。`auth_socket`插件通过 Unix socket 文件来验证所有连接到`localhost`的用户。 在MySQL 8.0上,root 用户默认通过`auth_socket`插件授权。`auth_socket`插件通过 Unix socket 文件来验证所有连接到`localhost`的用户。
@@ -337,7 +337,7 @@ mysql>
## 1.4 修改密码 ## 修改密码
将用户`admin`的登录密码修改为`mysql321` 将用户`admin`的登录密码修改为`mysql321`
@@ -347,7 +347,7 @@ ALTER USER 'admin'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mysql32
## 1.5 撤销用户授权 ## 撤销用户授权
```mysql ```mysql
# 查看用户的权限 # 查看用户的权限
@@ -360,7 +360,7 @@ revoke all privileges on *.* from 'admin'@'localhost';
## 1.6 删除用户 ## 删除用户
```MYSQL ```MYSQL
drop user 'admin'@'localhost'; drop user 'admin'@'localhost';
@@ -372,11 +372,11 @@ drop user 'admin'@'localhost';
# 二、MySQL预备知识 # MySQL预备知识
在正式学习MySQL之前,我们先来了解一下SQL语句的书写规范以及命名规则等。 在正式学习MySQL之前,我们先来了解一下SQL语句的书写规范以及命名规则等。
## 2.1 SQL书写规范 ## SQL书写规范
在写SQL语句时,要求按照如下规范进行: 在写SQL语句时,要求按照如下规范进行:
@@ -398,7 +398,7 @@ drop user 'admin'@'localhost';
## 2.2 命名规则 ## 命名规则
+ 在数据库中,只能使用半角英文字母、数字、下划线(_)作为数据库、表和列的名称 。 + 在数据库中,只能使用半角英文字母、数字、下划线(_)作为数据库、表和列的名称 。
+ 名称必须以半角英文字母作为开头。 + 名称必须以半角英文字母作为开头。
@@ -406,11 +406,11 @@ drop user 'admin'@'localhost';
## 2.3. 数据类型 ## 数据类型
MySQL 支持所有标准 SQL 数值数据类型,包括: MySQL 支持所有标准 SQL 数值数据类型,包括:
### 1数值类型 ### 数值类型
数值包含的类型如下: 数值包含的类型如下:
@@ -433,7 +433,7 @@ MySQL 支持所有标准 SQL 数值数据类型,包括:
| DOUBLE | 8 Bytes | (-1.797 693 134 862 315 7 E+308-2.225 073 858 507 201 4 E-308)0(2.225 073 858 507 201 4 E-3081.797 693 134 862 315 7 E+308) | 0(2.225 073 858 507 201 4 E-3081.797 693 134 862 315 7 E+308) | 双精度 浮点数值 | | DOUBLE | 8 Bytes | (-1.797 693 134 862 315 7 E+308-2.225 073 858 507 201 4 E-308)0(2.225 073 858 507 201 4 E-3081.797 693 134 862 315 7 E+308) | 0(2.225 073 858 507 201 4 E-3081.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
| DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 | | DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
### 2日期和时间类型 ### 日期和时间类型
表示时间值的日期和时间类型为`DATETIME``DATE``TIMESTAMP``TIME``YEAR`。具体如下表: 表示时间值的日期和时间类型为`DATETIME``DATE``TIMESTAMP``TIME``YEAR`。具体如下表:
@@ -445,7 +445,7 @@ MySQL 支持所有标准 SQL 数值数据类型,包括:
| DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 | | DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
| TIMESTAMP | 4 | 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 | | TIMESTAMP | 4 | 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
### 3字符串类型 ### 字符串类型
字符串类型指`CHAR``VARCHAR``BINARY``VARBINARY``BLOB``TEXT``ENUM``SET`。具体如下表: 字符串类型指`CHAR``VARCHAR``BINARY``VARBINARY``BLOB``TEXT``ENUM``SET`。具体如下表:
@@ -468,11 +468,11 @@ MySQL 支持所有标准 SQL 数值数据类型,包括:
# 三、数据库的基本操作 # 数据库的基本操作
首先,我们来学习在MySQL下如何操作数据库。 首先,我们来学习在MySQL下如何操作数据库。
## 3.1 数据库的创建 ## 数据库的创建
通过`CREATE`命令,可以创建指定名称的数据库,语法结构如下: 通过`CREATE`命令,可以创建指定名称的数据库,语法结构如下:
@@ -493,7 +493,7 @@ CREATE DATABASE shop;
## 3.2 数据库的查看 ## 数据库的查看
1. 查看所有存在的数据库 1. 查看所有存在的数据库
@@ -560,7 +560,7 @@ Create Database: CREATE DATABASE `shop` /*!40100 DEFAULT CHARACTER SET utf8mb4 C
## 3.3 选择数据库 ## 选择数据库
在操作数据库前,必须指定所要操作的数据库。通过`USE`命令,可以切换到对应的数据库下。 在操作数据库前,必须指定所要操作的数据库。通过`USE`命令,可以切换到对应的数据库下。
@@ -580,7 +580,7 @@ Database changed
## 3.4 删除数据库 ## 删除数据库
通过`DROP`命令,可以将相应数据库进行删除。 通过`DROP`命令,可以将相应数据库进行删除。
@@ -602,11 +602,11 @@ SHOW DATABASES;
# 四、表的基本操作 # 表的基本操作
表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段。 表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段。
## 4.1 表的创建 ## 表的创建
创建表的语法结构如下: 创建表的语法结构如下:
@@ -684,7 +684,7 @@ DESC Product;
## 4.2 表的删除 ## 表的删除
删除表的语法结构如下: 删除表的语法结构如下:
@@ -698,7 +698,7 @@ DROP TABLE <表名>;
## 4.3 表的更新 ## 表的更新
通过`ALTER TABLE`语句,我们可以对表字段进行不同的操作,下面通过示例来具体学习用法。 通过`ALTER TABLE`语句,我们可以对表字段进行不同的操作,下面通过示例来具体学习用法。
@@ -818,7 +818,7 @@ DESC Students;
## 4.4 表的查询 ## 表的查询
通过`SELECT`语句,可以从表中取出所要查看的字段的内容: 通过`SELECT`语句,可以从表中取出所要查看的字段的内容:
@@ -1044,7 +1044,7 @@ SELECT product_name
## 4.5 表的复制 ## 表的复制
表的复制可以将表结构与表中的数据全部复制,或者只复制表的结构。 表的复制可以将表结构与表中的数据全部复制,或者只复制表的结构。
@@ -1100,9 +1100,9 @@ DESC Product_COPY2;
# 五、运算符 # 运算符
## 5.1 算术运算符 ## 算术运算符
我们可以在`SELECT`语句中使用计算表达式: 我们可以在`SELECT`语句中使用计算表达式:
@@ -1138,7 +1138,7 @@ SELECT
## 5.2 比较运算符 ## 比较运算符
`WHERE` 子句中通过使用比较运算符可以组合出各种各样的条件表达式。 `WHERE` 子句中通过使用比较运算符可以组合出各种各样的条件表达式。
@@ -1181,7 +1181,7 @@ SELECT
## 5.3 逻辑运算符 ## 逻辑运算符
1. 使用`NOT`否认某一条件: 1. 使用`NOT`否认某一条件:
@@ -1241,9 +1241,9 @@ SELECT product_type, sale_price
# 六、分组查询 # 分组查询
## 6.1 聚合函数 ## 聚合函数
通过 SQL 对数据进行某种操作或计算时需要使用函数。 通过 SQL 对数据进行某种操作或计算时需要使用函数。
@@ -1364,7 +1364,7 @@ SELECT COUNT(DISTINCT product_type)
## 6.2 对表分组 ## 对表分组
如果对Python的Pandas熟悉,那么大家应该很了解`groupby`函数,可以根据指定的列名,对表进行分组。在MySQL中,也存在同样作用的函数,即`GROUP BY` 如果对Python的Pandas熟悉,那么大家应该很了解`groupby`函数,可以根据指定的列名,对表进行分组。在MySQL中,也存在同样作用的函数,即`GROUP BY`
@@ -1413,7 +1413,7 @@ SELECT product_type, COUNT(*)
当被聚合的键中,包含`NULL`时,在结果中会以“不确定”行(空行)的形式表现出来,也就是字段中为`NULL`的数据会被聚合为一组。 当被聚合的键中,包含`NULL`时,在结果中会以“不确定”行(空行)的形式表现出来,也就是字段中为`NULL`的数据会被聚合为一组。
## 6.3 使用WHERE语句 ## 使用WHERE语句
在对表进行分组之前,也可以是先使用`WHERE`对表进行条件过滤,然后再进行分组处理。语法结构如下: 在对表进行分组之前,也可以是先使用`WHERE`对表进行条件过滤,然后再进行分组处理。语法结构如下:
@@ -1455,7 +1455,7 @@ FROM → WHERE → GROUP BY → SELECT
## 6.4 为聚合结果指定条件 ## 为聚合结果指定条件
前面提到了`WHERE`语句中不能使用聚合函数,但是实际操作时需要通过聚合函数来进行过滤怎么办呢?这就要用到`HAVING`语句了。语法结构如下: 前面提到了`WHERE`语句中不能使用聚合函数,但是实际操作时需要通过聚合函数来进行过滤怎么办呢?这就要用到`HAVING`语句了。语法结构如下:
@@ -1547,7 +1547,7 @@ SELECT product_type, COUNT(*)
## 6.5 对表的查询结果进行排序 ## 对表的查询结果进行排序
如果希望对表的查询结果根据某指定的字段进行排序,可以使用`ORDER BY`语句。语法结构如下: 如果希望对表的查询结果根据某指定的字段进行排序,可以使用`ORDER BY`语句。语法结构如下:
@@ -1684,9 +1684,9 @@ ORDER BY ID;
# 七、数据的插入及更新 # 数据的插入及更新
## 7.1 数据的插入 ## 数据的插入
通过命令`INSERT`,可以向表中插入数据: 通过命令`INSERT`,可以向表中插入数据:
@@ -1778,7 +1778,7 @@ INSERT INTO
## 7.2 数据的删除 ## 数据的删除
通过`DROP TABLE`或者`DELETE`语句,可以对表进行删除,但二者存在一定的区别。 通过`DROP TABLE`或者`DELETE`语句,可以对表进行删除,但二者存在一定的区别。
@@ -1879,7 +1879,7 @@ mysql> DESC Product;
## 7.3 数据的更新 ## 数据的更新
当我们使用`INSERT`语句插入错误的数据后,若我们不想删除后从新插入,那就要使用到`UPDATE`语句。 当我们使用`INSERT`语句插入错误的数据后,若我们不想删除后从新插入,那就要使用到`UPDATE`语句。
@@ -1961,7 +1961,7 @@ UPDATE Product
# 八、Pymysql的使用 # Pymysql的使用
在正式介绍`pymysql`的用法之前,我们先思考一件事,我们希望借助`pymysql`完成什么事情? 在正式介绍`pymysql`的用法之前,我们先思考一件事,我们希望借助`pymysql`完成什么事情?
@@ -1975,7 +1975,7 @@ UPDATE Product
## 8.1 安装pymysql ## 安装pymysql
通过`pip`,我们可以完成对`pymysql`的安装: 通过`pip`,我们可以完成对`pymysql`的安装:
@@ -1985,7 +1985,7 @@ python3 -m pip install PyMySQL
## 8.2 连接数据库 ## 连接数据库
如果希望在Python中操作MySQL数据库,那么首先就要登陆到MySQL下的用户。 如果希望在Python中操作MySQL数据库,那么首先就要登陆到MySQL下的用户。
@@ -2018,7 +2018,7 @@ db = pymysql.connect(
## 8.3 创建游标 ## 创建游标
关于游标,可以理解为在命令行中的光标。在命令行中,我们是在光标处键入语句的。这里游标的起到类似作用。 关于游标,可以理解为在命令行中的光标。在命令行中,我们是在光标处键入语句的。这里游标的起到类似作用。
@@ -2045,7 +2045,7 @@ cursor = db.cursor(cursor=pymysql.cursors.DictCursor)
## 8.4 类方法 ## 类方法
初始化完类`connect``cursor`的实例后,我们先来了解一下这两个类下包含的方法。了解这些方法有利于我们后面在python下操作mysql 初始化完类`connect``cursor`的实例后,我们先来了解一下这两个类下包含的方法。了解这些方法有利于我们后面在python下操作mysql
@@ -2074,7 +2074,7 @@ cursor = db.cursor(cursor=pymysql.cursors.DictCursor)
## 8.5 实战 ## 实战
+ 示例1 + 示例1
+48 -48
View File
@@ -1,14 +1,14 @@
## 1.Web 前端 ## Web 前端
Web 前端网页主要由文字、图像和超链接等元素构成。当然,除了这些元素,网页中还可以包含音频、视频以及 Flash 等。 Web 前端网页主要由文字、图像和超链接等元素构成。当然,除了这些元素,网页中还可以包含音频、视频以及 Flash 等。
### 1.1 什么是 Web ### 什么是 Web
WebWorld Wide Web)即全球广域网,也称为万维网,它是一种基于超文本和 HTTP 的、全球性的、动态交互的、跨平台的分布式图形信息系统。是建立在 Internet 上的一种网络服务,为浏览者在 Internet 上查找和浏览信息提供了图形化的、易于访问的直观界面,其中的文档及超级链接将 Internet 上的信息节点组织成一个互为关联的网状结构。 WebWorld Wide Web)即全球广域网,也称为万维网,它是一种基于超文本和 HTTP 的、全球性的、动态交互的、跨平台的分布式图形信息系统。是建立在 Internet 上的一种网络服务,为浏览者在 Internet 上查找和浏览信息提供了图形化的、易于访问的直观界面,其中的文档及超级链接将 Internet 上的信息节点组织成一个互为关联的网状结构。
Web 前端主要是通 `HTML`,`CSS`,`JS`,`ajax`,`DOM` 等前端技术,实现网站在客服端的正确显示及交互功能。 Web 前端主要是通 `HTML`,`CSS`,`JS`,`ajax`,`DOM` 等前端技术,实现网站在客服端的正确显示及交互功能。
### 1.2 Web 标准构成 ### Web 标准构成
主要包括结构(Structure)、表现(Presentation)和行为(Behavior)三个方面。 主要包括结构(Structure)、表现(Presentation)和行为(Behavior)三个方面。
@@ -24,18 +24,18 @@
- 理想状态下,他们三层都是独立的, 放到不同的文件里面 - 理想状态下,他们三层都是独立的, 放到不同的文件里面
### 1.2.1 HTML ### HTML
- `HTML` 指的是超文本标记语言 (**H**yper **T**ext **M**arkup **L**anguage)是用来描述网页的一种语言。 - `HTML` 指的是超文本标记语言 (**H**yper **T**ext **M**arkup **L**anguage)是用来描述网页的一种语言。
- `HTML` 不是一种编程语言,而是一种标记语言 (markup language) - `HTML` 不是一种编程语言,而是一种标记语言 (markup language)
- 标记语言是一套标记标签 (markup tag) - 标记语言是一套标记标签 (markup tag)
##### 1.2.1.1 超文本的含义 ##### 超文本的含义
- **超越文本限制**:可以加入图片、声音、动画、多媒体等内容 - **超越文本限制**:可以加入图片、声音、动画、多媒体等内容
- **超级链接文本**:可以从一个文件跳转到另一个文件,与世界各地主机的文件连接 - **超级链接文本**:可以从一个文件跳转到另一个文件,与世界各地主机的文件连接
##### 1.2.1.2 语法骨架格式 ##### 语法骨架格式
```html ```html
<!DOCTYPE html> <!DOCTYPE html>
@@ -63,13 +63,13 @@
![html](https://files.mdnice.com/user/28784/2c141964-f366-494d-a7cc-c2abcd21161b.png) ![html](https://files.mdnice.com/user/28784/2c141964-f366-494d-a7cc-c2abcd21161b.png)
#### 1.2.2 CSS #### CSS
- `CSS`(**C**ascading **S**tyle **S**heets) ,通常称为 `CSS` 样式表或层叠样式表(级联样式表) - `CSS`(**C**ascading **S**tyle **S**heets) ,通常称为 `CSS` 样式表或层叠样式表(级联样式表)
- `CSS` 主要用于设置 `HTML` 页面中的文本内容(字体、大小、对齐方式等)、图片的外形(宽高、边框样式、边距等)以及版面的布局和外观显示样式。 - `CSS` 主要用于设置 `HTML` 页面中的文本内容(字体、大小、对齐方式等)、图片的外形(宽高、边框样式、边距等)以及版面的布局和外观显示样式。
- `CSS``HTML` 为基础,提供了丰富的功能,如字体、颜色、背景的控制及整体排版等,而且还可以针对不同的浏览器设置不同的样式。 - `CSS``HTML` 为基础,提供了丰富的功能,如字体、颜色、背景的控制及整体排版等,而且还可以针对不同的浏览器设置不同的样式。
##### 1.2.2.1 CSS 规则 ##### CSS 规则
![CSS](https://files.mdnice.com/user/28784/87d28c2f-e9f9-47bd-a3e5-2659f2008b2c.png) ![CSS](https://files.mdnice.com/user/28784/87d28c2f-e9f9-47bd-a3e5-2659f2008b2c.png)
@@ -79,7 +79,7 @@
- 属性:希望设置的样式属性。每个属性有一个值。属性和值用冒号分开 - 属性:希望设置的样式属性。每个属性有一个值。属性和值用冒号分开
##### 1.2.2.2 语法格式 ##### 语法格式
```html ```html
<标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;"> 内容 </标签名> <标签名 style="属性1:属性值1; 属性2:属性值2; 属性3:属性值3;"> 内容 </标签名>
@@ -108,12 +108,12 @@
</style> </style>
``` ```
#### 1.2.3 JS #### JS
- `JS` (**J**ava**S**cript)是 Web 的编程语言,是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端 Web 开发的脚本语言,常常用来给 `HTML` 网页添加动态效果,从而实现人机交互的网页 - `JS` (**J**ava**S**cript)是 Web 的编程语言,是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端 Web 开发的脚本语言,常常用来给 `HTML` 网页添加动态效果,从而实现人机交互的网页
- 脚本语言不需要编译,在运行过程中由 `js` 解释器逐行来进行解释并执行 - 脚本语言不需要编译,在运行过程中由 `js` 解释器逐行来进行解释并执行
##### 1.2.3.1 JS 的组成 ##### JS 的组成
![JS](https://files.mdnice.com/user/28784/259c84c2-7570-4ab0-b192-eefe14463a47.png) ![JS](https://files.mdnice.com/user/28784/259c84c2-7570-4ab0-b192-eefe14463a47.png)
@@ -121,7 +121,7 @@
- **DOM**:文档对象模型(DocumentObject Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等) - **DOM**:文档对象模型(DocumentObject Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)
- **BOM**:浏览器对象模型(Browser Object Model,简称 BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过 BOM 可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等 - **BOM**:浏览器对象模型(Browser Object Model,简称 BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过 BOM 可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等
##### 1.2.3.2 书写位置 ##### 书写位置
**1.行内式** **1.行内式**
@@ -163,13 +163,13 @@ function myFunction()
--- ---
## 2. Vue 简介 ## Vue 简介
`Vue` 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,`Vue` 被设计为可以自底向上逐层应用。`Vue` 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,`Vue` 也完全能够为复杂的单页应用提供驱动。 `Vue` 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,`Vue` 被设计为可以自底向上逐层应用。`Vue` 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,`Vue` 也完全能够为复杂的单页应用提供驱动。
### 2.1 安装 ### 安装
#### 2.1.1 通过< script>标签引入 #### 通过< script>标签引入
直接下载并用 `<script>` 标签引入,`Vue` 会被注册为一个全局变量。 直接下载并用 `<script>` 标签引入,`Vue` 会被注册为一个全局变量。
@@ -177,7 +177,7 @@ function myFunction()
- **生产版本**https://cn.vuejs.org/js/vue.min.js - **生产版本**https://cn.vuejs.org/js/vue.min.js
#### 2.1.2 通过 CDN 安装 #### 通过 CDN 安装
- **制作原型或学习** - **制作原型或学习**
@@ -199,7 +199,7 @@ function myFunction()
</script> </script>
``` ```
#### 2.1.3 通过 npm 安装 #### 通过 npm 安装
在用 `Vue` 构建大型应用时推荐使用 `npm` 安装。`npm` 能很好地和诸如 `webpack`模块打包器配合使用。同时 `Vue` 也提供配套工具来开发单文件组件。 在用 `Vue` 构建大型应用时推荐使用 `npm` 安装。`npm` 能很好地和诸如 `webpack`模块打包器配合使用。同时 `Vue` 也提供配套工具来开发单文件组件。
@@ -220,11 +220,11 @@ npm install npm -g
npm install vue npm install vue
``` ```
### 2.2 创建一个 Vue 实例 ### 创建一个 Vue 实例
每个 `Vue` 应用都需要通过实例化 `Vue` 来实现。 每个 `Vue` 应用都需要通过实例化 `Vue` 来实现。
#### 2.2.1 语法格式 #### 语法格式
```javascript ```javascript
var vm = new Vue({ var vm = new Vue({
@@ -257,7 +257,7 @@ var vm = new Vue({
`Vue` 构造器中有一个`el` 参数,它是 `DOM` 元素中的 `id`。在上面实例中 `id``example`,这表示接下来的改动全部在以上指定的 `div` 内,`div` 外部不受影响。 `Vue` 构造器中有一个`el` 参数,它是 `DOM` 元素中的 `id`。在上面实例中 `id``example`,这表示接下来的改动全部在以上指定的 `div` 内,`div` 外部不受影响。
#### 2.2.2 定义数据对象 #### 定义数据对象
在上述`Vue`实例中: 在上述`Vue`实例中:
@@ -269,20 +269,20 @@ var vm = new Vue({
当一个 `Vue` 实例被创建时,它向 `Vue` 的响应式系统中加入了其 `data` 对象中能找到的所有的属性。当这些属性的值发生改变时,`html` 视图将也会产生相应的变化。 当一个 `Vue` 实例被创建时,它向 `Vue` 的响应式系统中加入了其 `data` 对象中能找到的所有的属性。当这些属性的值发生改变时,`html` 视图将也会产生相应的变化。
### 2.3 Vue 的生命周期 ### Vue 的生命周期
每个 `Vue` 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 `DOM` 并在数据变化时更新 `DOM` 等。同时在这个过程中也会运行一些叫做**生命周期钩子**的函数,这给了用户在不同阶段添加自己的代码的机会。 每个 `Vue` 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 `DOM` 并在数据变化时更新 `DOM` 等。同时在这个过程中也会运行一些叫做**生命周期钩子**的函数,这给了用户在不同阶段添加自己的代码的机会。
下图是一个 `Vue` 实例的生命周期: 下图是一个 `Vue` 实例的生命周期:
![Vue生命周期](https://files.mdnice.com/user/28784/96265b5a-a5f0-4b13-83ad-742d9167f4cd.png) ![Vue生命周期](https://files.mdnice.com/user/28784/96265b5a-a5f0-4b13-83ad-742d9167f4cd.png)
#### 2.3.1 beforeCreate #### beforeCreate
在实例初始化之后,进行数据侦听和事件/侦听器的配置之前同步调用。 在实例初始化之后,进行数据侦听和事件/侦听器的配置之前同步调用。
此时组件的选项对象还未创建,`el``data` 并未初始化,因此无法访问`methods` `data` `computed`等上的方法和数据。 此时组件的选项对象还未创建,`el``data` 并未初始化,因此无法访问`methods` `data` `computed`等上的方法和数据。
#### 2.3.2 created #### created
在实例创建完成后被立即调用。 在实例创建完成后被立即调用。
@@ -290,13 +290,13 @@ var vm = new Vue({
在这一步中可以调用`methods`中的方法,改变`data`中的数据,并且修改可以通过 `Vue` 的响应式绑定体现在页面上,获取`computed`中的计算属性等等,通常我们可以在这里对实例进行预处理。但需要注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子`beforeRouteEnter`中完成。 在这一步中可以调用`methods`中的方法,改变`data`中的数据,并且修改可以通过 `Vue` 的响应式绑定体现在页面上,获取`computed`中的计算属性等等,通常我们可以在这里对实例进行预处理。但需要注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不适合在这个方法发请求,建议在组件路由钩子`beforeRouteEnter`中完成。
#### 2.3.3 beforeMount #### beforeMount
在挂载开始之前被调用:相关的 `render` 函数首次被调用(虚拟 `DOM`)。 在挂载开始之前被调用:相关的 `render` 函数首次被调用(虚拟 `DOM`)。
实例已完成以下的配置: 编译模板,把`data`里面的数据和模板生成`HTML`,完成了`el``data` 初始化,但此时还没有挂在`HTML`到页面上。 实例已完成以下的配置: 编译模板,把`data`里面的数据和模板生成`HTML`,完成了`el``data` 初始化,但此时还没有挂在`HTML`到页面上。
#### 2.3.4 mounted #### mounted
实例被挂载后调用,这时 `el` 被新创建的 `vm.$el` 替换了。 实例被挂载后调用,这时 `el` 被新创建的 `vm.$el` 替换了。
@@ -313,13 +313,13 @@ mounted: function () {
//生命周期钩子的 this 上下文指向调用它的 Vue 实例。 //生命周期钩子的 this 上下文指向调用它的 Vue 实例。
``` ```
#### 2.3.5 beforeUpdate #### beforeUpdate
在数据发生改变后,`DOM` 被更新之前被调用。 在数据发生改变后,`DOM` 被更新之前被调用。
适合在现有 `DOM` 将要被更新之前访问它,比如移除手动添加的事件监听器。可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程. 适合在现有 `DOM` 将要被更新之前访问它,比如移除手动添加的事件监听器。可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程.
#### 2.3.6 updated #### updated
在数据更改导致的虚拟 `DOM` 重新渲染和更新完毕之后被调用。 在数据更改导致的虚拟 `DOM` 重新渲染和更新完毕之后被调用。
@@ -335,17 +335,17 @@ updated: function () {
} }
``` ```
#### 2.3.7 beforeDestroy #### beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。 实例销毁之前调用。在这一步,实例仍然完全可用。
这一步还可以用`this`来获取实例,一般用来做一些重置的操作,比如清除掉组件中的定时器和监听的`DOM`事件。 这一步还可以用`this`来获取实例,一般用来做一些重置的操作,比如清除掉组件中的定时器和监听的`DOM`事件。
#### 2.3.8 destroyed #### destroyed
实例销毁后调用。该钩子被调用后,对应 `Vue` 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 实例销毁后调用。该钩子被调用后,对应 `Vue` 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
## 3 创建 Vue 项目 ## 创建 Vue 项目
`Vue CLI` 是一个基于 `Vue.js` 进行快速开发的完整系统,提供: `Vue CLI` 是一个基于 `Vue.js` 进行快速开发的完整系统,提供:
@@ -361,7 +361,7 @@ updated: function () {
`Vue CLI` 致力于将 `Vue` 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接。与此同时,它也为每个工具提供了调整配置的灵活性 `Vue CLI` 致力于将 `Vue` 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接。与此同时,它也为每个工具提供了调整配置的灵活性
### 3.1 安装 vue CLI ### 安装 vue CLI
Vue CLI 的包名称由 `vue-cli` 改成了 `@vue/cli`。 如果已经全局安装了旧版本的 `vue-cli` (1.x 或 2.x),需要先通过 `npm uninstall vue-cli -g`卸载它。 Vue CLI 的包名称由 `vue-cli` 改成了 `@vue/cli`。 如果已经全局安装了旧版本的 `vue-cli` (1.x 或 2.x),需要先通过 `npm uninstall vue-cli -g`卸载它。
@@ -383,9 +383,9 @@ vue --version
npm update -g @vue/cli npm update -g @vue/cli
``` ```
### 3.2 创建 Vue 项目 ### 创建 Vue 项目
#### 3.2.1 通过 vue create 创建 #### 通过 vue create 创建
```shell ```shell
vue create hello-world vue create hello-world
@@ -413,7 +413,7 @@ npm run serve
npm run build npm run build
``` ```
#### 3.2.2 使用图形化界面创建 #### 使用图形化界面创建
```shell ```shell
vue ui vue ui
@@ -422,7 +422,7 @@ vue ui
打开一个浏览器窗口,并以图形化界面将你引导至项目创建的流程。 打开一个浏览器窗口,并以图形化界面将你引导至项目创建的流程。
![ui-new-project](https://files.mdnice.com/user/28784/d6ad9e95-fb2a-4999-ba07-bb2d04ce17e9.png) ![ui-new-project](https://files.mdnice.com/user/28784/d6ad9e95-fb2a-4999-ba07-bb2d04ce17e9.png)
#### 3.2.3 使用 2.x 模板 (旧版本)创建 #### 使用 2.x 模板 (旧版本)创建
```shell ```shell
# 全局安装一个桥接工具 # 全局安装一个桥接工具
@@ -448,7 +448,7 @@ npm run dev
npm run build npm run build
``` ```
### 3.3 Vue 项目目录 ### Vue 项目目录
``` ```
├── v-proj ├── v-proj
@@ -466,7 +466,7 @@ npm run build
└ └── package.json //配置文件,使用npm install安装 └ └── package.json //配置文件,使用npm install安装
``` ```
#### 3.3.1 public #### public
可以理解为入口目录。 可以理解为入口目录。
@@ -495,7 +495,7 @@ npm run build
</html> </html>
``` ```
#### 3.3.2 src #### src
是整个项目的主文件夹 ,代码大部分都在这里完成。 是整个项目的主文件夹 ,代码大部分都在这里完成。
@@ -605,7 +605,7 @@ let routerObj = new VueRouter({
export default routerObj export default routerObj
``` ```
#### 3.3.3 README.md #### README.md
项目的说明文档,markdown 格式 项目的说明文档,markdown 格式
@@ -623,7 +623,7 @@ npm run serve
npm run build npm run build
``` ```
#### 3.3.4 package.json #### package.json
是整个项目用的到的所有的插件的 json 的格式,比如插件的名称、版本号。 当在项目里使用 npm install 时 node 会自动安装文件里的所有插件。 是整个项目用的到的所有的插件的 json 的格式,比如插件的名称、版本号。 当在项目里使用 npm install 时 node 会自动安装文件里的所有插件。
@@ -674,9 +674,9 @@ npm run build
--- ---
## 4.基于 Vue 的移动端 H5 项目 ## 基于 Vue 的移动端 H5 项目
### 4.1 什么是 H5 ### 什么是 H5
`HTML5` 是第五代 `HTML` 的标准,可以说,`H5` 是基于 `HTML5` 实现的,是当前互联网前端开发的主流语言。`H5` 页面与普通 `web` 页面相比,最大的区别在于 `HTML5` 页面可以与不同大小的移动设备相匹配,支持市场上不同浏览器的兼容。移动网络和移动设备的快速发展,使得 `H5` 在移动设备上能够被更好的应用。 `HTML5` 是第五代 `HTML` 的标准,可以说,`H5` 是基于 `HTML5` 实现的,是当前互联网前端开发的主流语言。`H5` 页面与普通 `web` 页面相比,最大的区别在于 `HTML5` 页面可以与不同大小的移动设备相匹配,支持市场上不同浏览器的兼容。移动网络和移动设备的快速发展,使得 `H5` 在移动设备上能够被更好的应用。
@@ -689,9 +689,9 @@ npm run build
- **使用滚动侦测特效,**即滑动页面的同时,大量文字或图片会自动加载出来,造成一种动态美感 - **使用滚动侦测特效,**即滑动页面的同时,大量文字或图片会自动加载出来,造成一种动态美感
### 4.2 使用 Vue 开发 H5 页面 ### 使用 Vue 开发 H5 页面
#### 4.2.1 创建 Vue 项目 #### 创建 Vue 项目
```shell ```shell
# vue create创建项目 # vue create创建项目
@@ -709,7 +709,7 @@ npm run serve
![vue-h5](https://files.mdnice.com/user/28784/d707e635-31da-4dec-ae68-2aab7f44f84d.png) ![vue-h5](https://files.mdnice.com/user/28784/d707e635-31da-4dec-ae68-2aab7f44f84d.png)
#### 4.2.2 自适应布局 #### 自适应布局
移动端的布局相对 PC 较为简单,关键在于对不同设备的适配。 移动端的布局相对 PC 较为简单,关键在于对不同设备的适配。
@@ -724,7 +724,7 @@ npm run serve
- **rem**: 相对于根元素 html 的字体大小的单位,比如 2rem=2 倍的根字体大小 - **rem**: 相对于根元素 html 的字体大小的单位,比如 2rem=2 倍的根字体大小
。rem 的基本原理是根据屏幕不同的分辨率,动态修改根字体的大小,让所有的用 rem 单位的元素跟着屏幕尺寸一起缩放,从而达到自适应的效果。 。rem 的基本原理是根据屏幕不同的分辨率,动态修改根字体的大小,让所有的用 rem 单位的元素跟着屏幕尺寸一起缩放,从而达到自适应的效果。
#### 4.2.3 路由配置 #### 路由配置
##### 下载 vue-router ##### 下载 vue-router
@@ -766,7 +766,7 @@ new Vue({
}).$mount('#app') }).$mount('#app')
``` ```
#### 4.2.4 数据请求 #### 数据请求
##### 安装 axios ##### 安装 axios
@@ -812,7 +812,7 @@ Vue.use(VueAxios, axios);
</script> </script>
``` ```
#### 4.2.5 UI 组件库 #### UI 组件库
UI 设计组件(UI KIT),直译过来就是用户界面成套元件,是界面设计常用控件或元件,「组」是设计元素的组合方式,「件」由不同的元件组成。 UI 设计组件(UI KIT),直译过来就是用户界面成套元件,是界面设计常用控件或元件,「组」是设计元素的组合方式,「件」由不同的元件组成。
+21 -21
View File
@@ -12,11 +12,11 @@
# 一、 准备工作 # 准备工作
在学习Flask之前,已经假设你对python已经有了一定的基础,并且对于计算机知识有了一定的掌握。 在学习Flask之前,已经假设你对python已经有了一定的基础,并且对于计算机知识有了一定的掌握。
## 1.1 环境配置 ## 环境配置
为了保持全局环境的干净,指定不同的依赖版本,我们可以利用virtualenv来构建虚拟的环境,类似于anaconda。 为了保持全局环境的干净,指定不同的依赖版本,我们可以利用virtualenv来构建虚拟的环境,类似于anaconda。
@@ -44,7 +44,7 @@ venv/bin/activate
pip install Flask pip install Flask
``` ```
## 1.2 测试安装 ## 测试安装
为了测试装的Flask是否能正常使用,可以在编译器中输入一下代码: 为了测试装的Flask是否能正常使用,可以在编译器中输入一下代码:
@@ -83,9 +83,9 @@ app.run(host, port, debug, options)
| 3 | **debug** 默认为false。 如果设置为true,则提供调试信息 | | 3 | **debug** 默认为false。 如果设置为true,则提供调试信息 |
| 4 | **options** 要转发到底层的Werkzeug服务器。 | | 4 | **options** 要转发到底层的Werkzeug服务器。 |
# 二、主要内容 # 主要内容
## 2.1 路由 ## 路由
在Flask中,路由是指用户请求的*URL*与*视图函数*之间的映射。Flask通过利用路由表将URL映射到对应的视图函数,根据视图函数的执行结果返回给WSGI服务器。路由表的内容是由开发者进行填充,主要有一下两个方式。 在Flask中,路由是指用户请求的*URL*与*视图函数*之间的映射。Flask通过利用路由表将URL映射到对应的视图函数,根据视图函数的执行结果返回给WSGI服务器。路由表的内容是由开发者进行填充,主要有一下两个方式。
@@ -107,7 +107,7 @@ app.run(host, port, debug, options)
app.add_url_rule('/test',view_func=test) app.add_url_rule('/test',view_func=test)
``` ```
### 2.1.1 指定HTTP方法 ### 指定HTTP方法
默认情况下,Flask的路由支持HTTP的*GET*请求,如果需要视图函数支持HTTP的其他方法,可以通过*methods*关键字参数进行设置。关键字参数*methods*的类型为*list*,可以同时指定多种HTTP方法。 默认情况下,Flask的路由支持HTTP的*GET*请求,如果需要视图函数支持HTTP的其他方法,可以通过*methods*关键字参数进行设置。关键字参数*methods*的类型为*list*,可以同时指定多种HTTP方法。
@@ -122,7 +122,7 @@ def get_users():
### 2.1.2 匹配动态URL ### 匹配动态URL
动态URL用于当需要将*同一类URL*映射到同一个视图函数处理,比如,使用同一个视图函数 来显示不同用户的个人信息。那么可以将URL中的可变部分*使用一对小括号*<>声明为变量, 并为视图函数声明同名的参数: 动态URL用于当需要将*同一类URL*映射到同一个视图函数处理,比如,使用同一个视图函数 来显示不同用户的个人信息。那么可以将URL中的可变部分*使用一对小括号*<>声明为变量, 并为视图函数声明同名的参数:
@@ -151,7 +151,7 @@ def get_userInfo(uname):
### 2.1.3 匹配动态URL ### 匹配动态URL
为了满足一个视图函数可以解决多个问题,因此每个视图函数可以配置多个路由规则。 为了满足一个视图函数可以解决多个问题,因此每个视图函数可以配置多个路由规则。
@@ -168,7 +168,7 @@ def get_userInfo(uname=None):
### 2.1.4 URL构建方法 ### URL构建方法
在很多时候,在一个实用的视图中需要指向其他视图的连接,为了防止路径出现问题,我们可以让Flask框架帮我们计算链接URL。简单地给url_for()函数传入一个访问点,它返回将是一个可靠的URL地址: 在很多时候,在一个实用的视图中需要指向其他视图的连接,为了防止路径出现问题,我们可以让Flask框架帮我们计算链接URL。简单地给url_for()函数传入一个访问点,它返回将是一个可靠的URL地址:
@@ -208,11 +208,11 @@ def test_url_for():
## 2.2 请求,响应及会话 ## 请求,响应及会话
对于一个完整的HTTP请求,包括了来自客户端的请求对象(Request),服务器端的响应对象(Respose)和会话对象(Session)等。在Flask框架中,当然也具有这些对象,这些对象不仅可以在请求函数中使用,同时也可以在模板中使用。那我们来简单看看这些对象具体怎么使用。 对于一个完整的HTTP请求,包括了来自客户端的请求对象(Request),服务器端的响应对象(Respose)和会话对象(Session)等。在Flask框架中,当然也具有这些对象,这些对象不仅可以在请求函数中使用,同时也可以在模板中使用。那我们来简单看看这些对象具体怎么使用。
### 2.2.1 请求对象 request ### 请求对象 request
在Flask包中,可以直接引入request对象,其中包含**Form****args** **Cookies** **files** 等属性。**Form** 是一个字典对象,包含表单当中所有参数及其值的键和值对;**args** 是解析查询字符串的内容,它是问号(?)之后的URL的一部分,当使用get请求时,通过URL传递参数时可以通过**args**属性获取;**Cookies** 是用来保存Cookie名称和值的字典对象;**files** 属性和上传文件有关的数据。我们以一个登陆的例子看看如何搭配使用这些属性 在Flask包中,可以直接引入request对象,其中包含**Form****args** **Cookies** **files** 等属性。**Form** 是一个字典对象,包含表单当中所有参数及其值的键和值对;**args** 是解析查询字符串的内容,它是问号(?)之后的URL的一部分,当使用get请求时,通过URL传递参数时可以通过**args**属性获取;**Cookies** 是用来保存Cookie名称和值的字典对象;**files** 属性和上传文件有关的数据。我们以一个登陆的例子看看如何搭配使用这些属性
@@ -257,7 +257,7 @@ def login():
### 2.2.2 响应对象 response ### 响应对象 response
如果视图函数想向前端返回数据,必须是`Response`的对象, 主要讲返回数据的几种方式: 如果视图函数想向前端返回数据,必须是`Response`的对象, 主要讲返回数据的几种方式:
@@ -312,9 +312,9 @@ def hot_list():
## 2.3 重定向与错误处理 ## 重定向与错误处理
### 2.3.1重定向 ### 重定向
当一个请求过来后可能还需要再请求另一个视图函数才能达到目的,那么就可以调用`redirect(location, code=302, Response=None)`函数指定重定向页面。 当一个请求过来后可能还需要再请求另一个视图函数才能达到目的,那么就可以调用`redirect(location, code=302, Response=None)`函数指定重定向页面。
@@ -351,7 +351,7 @@ def index():
### 2.3.2错误处理 ### 错误处理
当请求或服务器出现错误的时候,我们希望遇到特定错误代码时重写错误页面,可以使用 **errorhandler()** 装饰器: 当请求或服务器出现错误的时候,我们希望遇到特定错误代码时重写错误页面,可以使用 **errorhandler()** 装饰器:
@@ -365,11 +365,11 @@ def page_not_found(error):
当遇到404错误时,会调用page_not_found()函数,返回元组数据,第一个元素是”page_not_found.html”的模板页,第二个元素代表错误代码,返回值会自动转成 response 对象。 当遇到404错误时,会调用page_not_found()函数,返回元组数据,第一个元素是”page_not_found.html”的模板页,第二个元素代表错误代码,返回值会自动转成 response 对象。
## 2.4 SQLAlchemy ## SQLAlchemy
SQLAlchemy 是一个功能强大的Python ORM 工具包,为应用程序开发人员提供了SQL的全部功能和ORM操作。其中ORM (Object Relation Mapping)指的是将对象参数映射到底层RDBMS表结构的技术,ORM API提供了执行CRUD操作的方法,不需要程序员编写原始SQL语句。 SQLAlchemy 是一个功能强大的Python ORM 工具包,为应用程序开发人员提供了SQL的全部功能和ORM操作。其中ORM (Object Relation Mapping)指的是将对象参数映射到底层RDBMS表结构的技术,ORM API提供了执行CRUD操作的方法,不需要程序员编写原始SQL语句。
### 2.4.1安装 ### 安装
通过下面指令可以进行安装: 通过下面指令可以进行安装:
@@ -385,7 +385,7 @@ pip install pymysql
### 2.4.2 创建连接 ### 创建连接
```python ```python
from sqlalchemy import create_engine from sqlalchemy import create_engine
@@ -408,7 +408,7 @@ create_engine("mysql://user:password@hostname/dbname?charset=utf8",
第一个参数是和框架表明连接数据库所需的信息,"数据库+数据库连接框架://用户名:密码@IP地址:端口号/数据库名称?连接参数";echo是设置当前ORM语句是否转化为SQL打印;pool_size是用来设置连接池大小,默认值为5;pool_recycle设置连接失效的时间,超过时间连接池会自动断开。 第一个参数是和框架表明连接数据库所需的信息,"数据库+数据库连接框架://用户名:密码@IP地址:端口号/数据库名称?连接参数";echo是设置当前ORM语句是否转化为SQL打印;pool_size是用来设置连接池大小,默认值为5;pool_recycle设置连接失效的时间,超过时间连接池会自动断开。
### 2.4.3 **创建数据库表类** ### **创建数据库表类**
由于SQLAlchemy 是对象关系映射,在操作数据库表时需要通过操作对象实现,因此就需要创建一个数据库表类。 由于SQLAlchemy 是对象关系映射,在操作数据库表时需要通过操作对象实现,因此就需要创建一个数据库表类。
@@ -434,7 +434,7 @@ class User(Base):
通过declarative_base()函数,可以将python类和数据库表进行关联映射,并通过 \__tablename\__ 属性将数据库模型类和表进行管理。其中Column() 表示数据表中的列,Integer()和String()表示数据库的数据类型。 通过declarative_base()函数,可以将python类和数据库表进行关联映射,并通过 \__tablename\__ 属性将数据库模型类和表进行管理。其中Column() 表示数据表中的列,Integer()和String()表示数据库的数据类型。
### 2.4.4 **操作数据库** ### **操作数据库**
创建完连接之后,我们需要借助sqlalchemy中的session来创建程序与数据库之间的会话。换句话来说,需要通过session才能利用程序对数据库进行CURD。这里我们可以通过 sessionmaker() 函数来创建会话。 创建完连接之后,我们需要借助sqlalchemy中的session来创建程序与数据库之间的会话。换句话来说,需要通过session才能利用程序对数据库进行CURD。这里我们可以通过 sessionmaker() 函数来创建会话。
@@ -540,7 +540,7 @@ if users:
### 参考资料 **参考资料**
1. [Flask教程](https://www.w3cschool.cn/flask/flask_sqlalchemy.html) 1. [Flask教程](https://www.w3cschool.cn/flask/flask_sqlalchemy.html)
+2 -2
View File
@@ -1,6 +1,6 @@
## Task01问答整理 ## Task01问答整理
## 1. Task01整体流程(外加录屏整理) ## Task01整体流程(外加录屏整理)
- 本次组队学习的内容以github上第二章第二节为主,具体每次的学习内容和重点已经在对应章节下的README.md中,大家忘记的可以随时取查看。 - 本次组队学习的内容以github上第二章第二节为主,具体每次的学习内容和重点已经在对应章节下的README.md中,大家忘记的可以随时取查看。
https://github.com/datawhalechina/fun-rec https://github.com/datawhalechina/fun-rec
@@ -39,7 +39,7 @@
- 总结:https://share.weiyun.com/u3ZIjZfg - 总结:https://share.weiyun.com/u3ZIjZfg
## 2. 问题解答 ## 问题解答
- 问:在执行`Scrapy`进行新闻爬取实战的时候,写不进去`mongdb`数据库 - 问:在执行`Scrapy`进行新闻爬取实战的时候,写不进去`mongdb`数据库
+2 -2
View File
@@ -1,6 +1,6 @@
## Task02问答整理 ## Task02问答整理
## 1. Task02整体流程(外加录屏整理) ## Task02整体流程(外加录屏整理)
- 需要掌握: - 需要掌握:
@@ -17,7 +17,7 @@
- 作业分享:https://relph1119.github.io/my-team-learning/#/recommender_system32/task02 - 作业分享:https://relph1119.github.io/my-team-learning/#/recommender_system32/task02
## 2. 问题解答 ## 问题解答
- 问:如果出现年龄显示的问题怎么办? - 问:如果出现年龄显示的问题怎么办?
+2 -2
View File
@@ -1,6 +1,6 @@
## Task03问答整理 ## Task03问答整理
## 1. Task03整体流程(外加录屏整理) ## Task03整体流程(外加录屏整理)
- 学习2.2.1.5 自动化构建用户及物料画像,学习具体的代码的时候建议先把项目中所有文件中的README.md先看看,了解每个包大概是在干什么,然后再根据教程一点一点去理解流程,建议先梳理代码流程,等到最后自己觉得整个流程自己比较熟悉了,就可以慢慢的去看代码的实现细节。 - 学习2.2.1.5 自动化构建用户及物料画像,学习具体的代码的时候建议先把项目中所有文件中的README.md先看看,了解每个包大概是在干什么,然后再根据教程一点一点去理解流程,建议先梳理代码流程,等到最后自己觉得整个流程自己比较熟悉了,就可以慢慢的去看代码的实现细节。
@@ -13,7 +13,7 @@
- 作业分享:https://relph1119.github.io/my-team-learning/#/recommender_system32/task03 - 作业分享:https://relph1119.github.io/my-team-learning/#/recommender_system32/task03
## 2. 问题解答 ## 问题解答
- 问:请问这样处理会不会时间复杂度较大? - 问:请问这样处理会不会时间复杂度较大?