├── .gitignore ├── .nojekyll ├── README.md ├── _navbar.md ├── _sidebar.md ├── codes └── rec │ ├── datasets │ └── README.md │ └── model │ ├── __init__.py │ ├── activate.py │ ├── inputs.py │ ├── layers.py │ ├── models.py │ └── utils.py ├── docs ├── dialogue │ ├── 1.概述.md │ ├── 2.技术架构.md │ ├── 3.query理解.md │ ├── 4.内容输出.md │ ├── 5.多轮对话.md │ ├── README.md │ └── image │ │ ├── image_H-KuJoI867.png │ │ ├── image_kW3I3wYCtU.png │ │ ├── image_kjDyaPkpUM.png │ │ ├── image_oVEDRXtSom.png │ │ └── image_s5_p_VOBPM.png ├── dl │ ├── 1.激活函数.md │ ├── 2.KL散度.md │ ├── 3.正则化.md │ ├── 4.损失函数.md │ ├── 5.优化器.md │ ├── 6.评估指标.md │ ├── README.md │ └── image │ │ ├── 1c6290931f35b50f794a8acca445e829_cCz574Huf6.gif │ │ ├── 9cf7ce63ee9047df36576f6b5f2ca290__m9AiUI0Ya.gif │ │ ├── image_-5-KhHc6vb.png │ │ ├── image_2AtuZrFran.png │ │ ├── image_2KV3LOKN2S.png │ │ ├── image_9ED50ulsDw.png │ │ ├── image_9PYcDpzk-_.png │ │ ├── image_AHzmMqgKgV.png │ │ ├── image_EkdkFEhzz3.png │ │ ├── image_GlE3RW4neL.png │ │ ├── image_OQIO6bJNUM.png │ │ ├── image_TO2iAcgR7r.png │ │ ├── image_VQ92WkZEST.png │ │ ├── image_mObw4TwnQV.png │ │ ├── image_vZZ0x7ThiD.png │ │ └── image_zrvZp-9GRb.png ├── ml │ ├── 1.ML概念.md │ ├── 2.LR模型.md │ ├── 3.SVM.md │ ├── 4.EM & 聚类.md │ ├── README.md │ └── image │ │ ├── 68747470733a2f2f6a756c796564752d696d672e6f73732d63.gif │ │ ├── image_-wlN4CmaWB.png │ │ ├── image_1EAlNZ-b_m.png │ │ ├── image_8GgBb12BYf.png │ │ ├── image_Cm_Ww_BWzc.png │ │ ├── image_ELXaGaECoB.png │ │ ├── image_NDV1nnrl2G.png │ │ ├── image_PEghHrm7Ih.png │ │ ├── image_Uyzi-bBIpS.png │ │ ├── image_VjyUAdnDna.png │ │ ├── image_ZLJyowbArj.png │ │ ├── image_mlePzMQoOV.png │ │ ├── image_q6_H8kClGx.png │ │ └── image_sSoyfDDeXh.png ├── nlp │ └── README.md ├── rag │ ├── image │ │ └── image_F-9kskhOyU.png │ └── 综述-面向大模型的检索增强生成(RAG).md ├── rec │ ├── 1.概要.md │ ├── 2.召回.md │ ├── 3.排序.md │ ├── 4.特征交叉.md │ ├── 5.行为序列.md │ ├── 6.重排.md │ ├── 7.物品冷启动.md │ ├── README.md │ └── image │ │ ├── image_-c9_lwqj_l.png │ │ ├── image_0-Ga1DCKwo.png │ │ ├── image_0pwcMiTsOT.png │ │ ├── image_0qFhFDLE6M.png │ │ ├── image_1SZ8p7JSfX.png │ │ ├── image_1lMyM1lqV3.png │ │ ├── image_1seADePZzK.png │ │ ├── image_1vzxIJWpJw.png │ │ ├── image_28ITuuUy2p.png │ │ ├── image_2C0Y35qWpv.png │ │ ├── image_2WzVKJf3zS.png │ │ ├── image_2bYQeQ7M2d.png │ │ ├── image_3WvbHFd6Ms.png │ │ ├── image_3X4y4vTuYc.png │ │ ├── image_3jSmbGIWjO.png │ │ ├── image_3oBGLNyBjf.png │ │ ├── image_3sNKnDe5oQ.png │ │ ├── image_4KUrLTZSlt.png │ │ ├── image_4Nhihh1RvM.png │ │ ├── image_4VRIt58qT6.png │ │ ├── image_4xpAKAJs9R.png │ │ ├── image_57embG0Blf.png │ │ ├── image_5DVcAZyldb.png │ │ ├── image_5HvjKCac84.png │ │ ├── image_5uFd4P-Qlb.png │ │ ├── image_5xAIj-eIAs.png │ │ ├── image_6J3FAs8p3v.png │ │ ├── image_6YPUOGgnL2.png │ │ ├── image_7AB46ql7Jk.png │ │ ├── image_7GvVjtBfqJ.png │ │ ├── image_7l9xATVYys.png │ │ ├── image_8-GAXyLYFr.png │ │ ├── image_81a-t6r1pX.png │ │ ├── image_89Drp77iFr.png │ │ ├── image_8RNkmrt2_C.png │ │ ├── image_8o8agbx8T7.png │ │ ├── image_8vVheB5mBI.png │ │ ├── image_9vlSe0CY4G.png │ │ ├── image_AIHkQL_AM5.png │ │ ├── image_BIyTFzMSZv.png │ │ ├── image_BO2LKkXOvD.png │ │ ├── image_BgVc5Y6cBf.png │ │ ├── image_BsJapeD-_o.png │ │ ├── image_C6e2dZFM8N.png │ │ ├── image_CJoCP17GvW.png │ │ ├── image_CK230euPN4.png │ │ ├── image_CLjNrkQxa6.png │ │ ├── image_CcZ86wfDTw.png │ │ ├── image_CoGLwk6LIu.png │ │ ├── image_CzBo1a7MrT.png │ │ ├── image_D4R-02kTP0.png │ │ ├── image_DW3Rd2Wk_n.png │ │ ├── image_E6nGivyquc.png │ │ ├── image_EI4kbN2TX4.png │ │ ├── image_F6dhnh2qbQ.png │ │ ├── image_FeBXn0GhzL.png │ │ ├── image_FvepkhhpYx.png │ │ ├── image_G6g9NEgw8Z.png │ │ ├── image_GPt66RfR6z.png │ │ ├── image_Gip-URcw9d.png │ │ ├── image_H_CwyEvwCx.png │ │ ├── image_Hn-lrisNa-.png │ │ ├── image_I50dj7yBEb.png │ │ ├── image_IOwpCjNMD3.png │ │ ├── image_Jq6f3XhyS3.png │ │ ├── image_K4QBc0qZQZ.png │ │ ├── image_L0ZpX5japc.png │ │ ├── image_LUdBQB0S5u.png │ │ ├── image_M608Z9jh12.png │ │ ├── image_MCxufwxlSs.png │ │ ├── image_MDz6ke3VVL.png │ │ ├── image_MHzIkwJFsw.png │ │ ├── image_Ma6fm_wZ_l.png │ │ ├── image_MkPh7xZCFm.png │ │ ├── image_MwXGfVnOEE.png │ │ ├── image_NRRP3WU9pM.png │ │ ├── image_NYHCr0fS8C.png │ │ ├── image_NiHZ3gX3ey.png │ │ ├── image_Oj3BlHhaR_.png │ │ ├── image_PGMrIELLsg.png │ │ ├── image_PVBLfuCWTt.png │ │ ├── image_RGiOdnd8pP.png │ │ ├── image_Rs-fIUSKmD.png │ │ ├── image_SLQxKYsSS0.png │ │ ├── image_SYwggjx4oY.png │ │ ├── image_SxItlIaLWB.png │ │ ├── image_Tfwv_42EQu.png │ │ ├── image_TvdXfJcTCB.png │ │ ├── image_U8wh9Vfs3m.png │ │ ├── image_UkPqQlcso-.png │ │ ├── image_W0b7sV_AW2.png │ │ ├── image_W2MrRVHDza.png │ │ ├── image_W4DHHkFRmJ.png │ │ ├── image_WfjfGcwBVQ.png │ │ ├── image_X-3xjswNi2.png │ │ ├── image_YWTvk7V0Zr.png │ │ ├── image_Zp8t8F0p5q.png │ │ ├── image_ZwDC-fQYRn.png │ │ ├── image_ZxvgHV0_0_.png │ │ ├── image_Zy3HHldsZb.png │ │ ├── image__KwcoqndE_.png │ │ ├── image__Z0HsNo2I3.png │ │ ├── image__cO_SLTofi.png │ │ ├── image_axmVLY6Ik4.png │ │ ├── image_bpbVb26Fqo.png │ │ ├── image_cjzM4ecvu3.png │ │ ├── image_clKaQ1OT8W.png │ │ ├── image_dNmmm3qJi6.png │ │ ├── image_d_Tj6Uk4_n.png │ │ ├── image_e-jdeFLaaZ.png │ │ ├── image_e19PdpsF8e.png │ │ ├── image_egcqBvd27d.png │ │ ├── image_fiDdgrgvCO.png │ │ ├── image_h-JdOb6bHA.png │ │ ├── image_hHDhp6PO7s.png │ │ ├── image_hWhDQ9HB9z.png │ │ ├── image_h_l_P1zRni.png │ │ ├── image_hiQmSo-x_0.png │ │ ├── image_i3Bqkzf_GU.png │ │ ├── image_iSIctmYYbR.png │ │ ├── image_iShVEnF6Yg.png │ │ ├── image_iTVMfwwJNh.png │ │ ├── image_imPcZGdrGv.png │ │ ├── image_iva8FLR943.png │ │ ├── image_j1h3X4VerA.png │ │ ├── image_jCcdGPTvVH.png │ │ ├── image_k7S54sQC6j.png │ │ ├── image_k8dNw9k5Ba.png │ │ ├── image_kTbzOBottp.png │ │ ├── image_kdGWIqhRTx.png │ │ ├── image_kosHodwpAP.png │ │ ├── image_l_iktEIkRV.png │ │ ├── image_lgfvyRfSTt.png │ │ ├── image_m-qWuNiq5w.png │ │ ├── image_m6_c31EjLw.png │ │ ├── image_mODwPpJRwO.png │ │ ├── image_ncWaODgw2m.png │ │ ├── image_o2EuYCVmLx.png │ │ ├── image_o5Ak6yyHCX.png │ │ ├── image_oXaUPepJGU.png │ │ ├── image_ovVgYq5YSc.png │ │ ├── image_pE00eutJ6U.png │ │ ├── image_pJSzVC1ma9.png │ │ ├── image_pgtuA8uQtF.png │ │ ├── image_rnzkChV_td.png │ │ ├── image_smA5iQsBsD.png │ │ ├── image_tRbq2lEbUV.png │ │ ├── image_tRxTN6ETAF.png │ │ ├── image_tSl9WOnZwF.png │ │ ├── image_tdYg8_xWwp.png │ │ ├── image_tncVQjZAgp.png │ │ ├── image_uGSDWU-Odn.png │ │ ├── image_uQOeuJ5hAI.png │ │ ├── image_vE5i49fP7D.png │ │ ├── image_vP8Uoyc8tH.png │ │ ├── image_wS1eMxRZfw.png │ │ ├── image_wUlx8lS-ox.png │ │ ├── image_x3TlzA1Dvz.png │ │ ├── image_xIuiO1kw7v.png │ │ ├── image_xcucF0MAb5.png │ │ ├── image_y5UxXFuNLf.png │ │ ├── image_zMk4F7kDuj.png │ │ ├── image_zaTzsYcK86.png │ │ └── image_zigdAf36nk.png └── search │ ├── 1.开篇语.md │ ├── 2.常见架构.md │ ├── 3.文档内容处理.md │ ├── 4.query理解.md │ ├── 5.召回:检索、粗排、多路召回.md │ ├── 6.精排.md │ ├── 7.补充模块.md │ ├── README.md │ └── image │ ├── image_2NnOFonb0B.png │ ├── image_6HwW7szTAZ.png │ ├── image_6YYlfq3Qj6.png │ ├── image_83LuygiASf.png │ ├── image_AWm29bJAD1.png │ ├── image_BrSNasOa0G.png │ ├── image_EPp4qqExAg.png │ ├── image_LpWtTTda_N.png │ ├── image_TmG08B6YFp.png │ ├── image_WGZTznvdV9.png │ ├── image_XVxR0bMHFn.png │ ├── image_faaG_kkI8R.png │ ├── image_hG8wpp_-sk.png │ ├── image_iYqSeUzGYk.png │ ├── image_mpuobqHvS-.png │ ├── image_n9zXOmxs4T.png │ ├── image_rkvExLW81V.png │ ├── image_uJ0fQLzMd7.png │ └── image_waQQM4WyMr.png └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | codes/rec/datasets/ml-32m/* 3 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/.nojekyll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AI 工程师相关知识及面试题 2 | 3 | ## 1.简介 4 | 5 | 本仓库为学习深度学习(DL)、机器学习(ML)、自然语言处理(NLP)、推荐系统(REC)、搜索系统(Search)相关知识整理,欢迎阅读,如果对你有用,麻烦点一下 🌟 star,谢谢! 6 | 7 | 8 | ## 2.在线阅读 9 | 10 | 在线阅读链接:[AI Interview Note](https://dongnian.icu/ai_interview_note) 11 | 12 | ## 3.目录 13 | 14 | 15 | - [深度学习](docs/dl/README.md) 16 | - [1.激活函数](docs/dl/1.激活函数.md) 17 | - [2.KL散度](docs/dl/2.KL散度.md) 18 | - [3.正则化](docs/dl/3.正则化.md) 19 | - [4.损失函数](docs/dl/4.损失函数.md) 20 | - [5.优化器](docs/dl/5.优化器.md) 21 | - [6.评估指标](docs/dl/6.评估指标.md) 22 | - [机器学习](docs/ml/README.md) 23 | - [1.ML概念](docs/ml/1.ML概念.md) 24 | - [2.LR模型](docs/ml/2.LR模型.md) 25 | - [3.SVM](docs/ml/3.SVM.md) 26 | - [4.EM & 聚类](docs/ml/4.EM%20&%20聚类.md) 27 | - [推荐系统](docs/rec/README.md) 28 | - [1.概要](/docs/rec/1.概要.md) 29 | - [2.召回](/docs/rec/2.召回.md) 30 | - [3.排序](/docs/rec/3.排序.md) 31 | - [4.特征交叉](/docs/rec/4.特征交叉.md) 32 | - [5.行为序列](/docs/rec/5.行为序列.md) 33 | - [6.重排](/docs/rec/6.重排.md) 34 | - [7.物品冷启动](/docs/rec/7.物品冷启动.md) 35 | - [搜索系统](docs/search/README.md) 36 | - [1.开篇语](docs/search/1.开篇语.md) 37 | - [2.常见架构](docs/search/2.常见架构.md) 38 | - [3.文档内容处理](docs/search/3.文档内容处理.md) 39 | - [4.query理解](docs/search/4.query理解.md) 40 | - [5.召回:检索、粗排、多路召回](docs/search/5.召回:检索、粗排、多路召回.md) 41 | - [6.精排](docs/search/6.精排.md) 42 | - [7.补充模块](docs/search/7.补充模块.md) 43 | - [RAG](docs/rag/README.md) 44 | - [RAG 综述](docs/rag/综述-面向大模型的检索增强生成(RAG).md) 45 | 46 | -------------------------------------------------------------------------------- /_navbar.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | * 快捷链接 4 | - [Tiny LLM zh](https://github.com/wdndev/tiny-llm-zh) 5 | - [体验Tiny LLM](https://www.modelscope.cn/studios/wdndev/tiny_llm_92m_demo/summary) -------------------------------------------------------------------------------- /_sidebar.md: -------------------------------------------------------------------------------- 1 | - [首页](/) 2 | - [深度学习](docs/dl/README.md) 3 | - [1.激活函数](docs/dl/1.激活函数.md) 4 | - [2.KL散度](docs/dl/2.KL散度.md) 5 | - [3.正则化](docs/dl/3.正则化.md) 6 | - [4.损失函数](docs/dl/4.损失函数.md) 7 | - [5.优化器](docs/dl/5.优化器.md) 8 | - [6.评估指标](docs/dl/6.评估指标.md) 9 | - [机器学习](docs/ml/README.md) 10 | - [1.ML概念](docs/ml/1.ML概念.md) 11 | - [2.LR模型](docs/ml/2.LR模型.md) 12 | - [3.SVM](docs/ml/3.SVM.md) 13 | - [4.EM & 聚类](docs/ml/4.EM%20&%20聚类.md) 14 | - [推荐系统](docs/rec/README.md) 15 | - [1.概要](/docs/rec/1.概要.md) 16 | - [2.召回](/docs/rec/2.召回.md) 17 | - [3.排序](/docs/rec/3.排序.md) 18 | - [4.特征交叉](/docs/rec/4.特征交叉.md) 19 | - [5.行为序列](/docs/rec/5.行为序列.md) 20 | - [6.重排](/docs/rec/6.重排.md) 21 | - [7.物品冷启动](/docs/rec/7.物品冷启动.md) 22 | - [搜索系统](docs/search/README.md) 23 | - [1.开篇语](docs/search/1.开篇语.md) 24 | - [2.常见架构](docs/search/2.常见架构.md) 25 | - [3.文档内容处理](docs/search/3.文档内容处理.md) 26 | - [4.query理解](docs/search/4.query理解.md) 27 | - [5.召回:检索、粗排、多路召回](docs/search/5.召回:检索、粗排、多路召回.md) 28 | - [6.精排](docs/search/6.精排.md) 29 | - [7.补充模块](docs/search/7.补充模块.md) 30 | - [对话系统](docs/dialogue/README.md) 31 | - [1.概述](docs/dialogue/1.概述.md) 32 | - [2.技术架构](docs/dialogue/2.技术架构.md) 33 | - [3.query理解](docs/dialogue/3.query理解.md) 34 | - [4.内容输出](docs/dialogue/4.内容输出.md) 35 | - [5.多轮对话](docs/dialogue/5.多轮对话.md) 36 | - [RAG](docs/rag/README.md) 37 | - [综述-面向大模型的检索增强生成](docs/rag/综述-面向大模型的检索增强生成(RAG).md) 38 | 39 | -------------------------------------------------------------------------------- /codes/rec/datasets/README.md: -------------------------------------------------------------------------------- 1 | ### Movielens 数据集 2 | 3 | 下载链接:[movielens](https://grouplens.org/datasets/movielens) 4 | 5 | 6 | -------------------------------------------------------------------------------- /codes/rec/model/__init__.py: -------------------------------------------------------------------------------- 1 | from .activate import * 2 | from .inputs import * 3 | from .layers import * 4 | from .models import * 5 | -------------------------------------------------------------------------------- /codes/rec/model/activate.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torch 3 | 4 | class Dice(nn.Module): 5 | """ DIN中的数组自适应激活函数,可以看作是PReLU的一种泛化,并且可以根据输入数据的分布自适应的调整修正点 6 | 7 | Input shape: 8 | - 2 dims: [batch_size, embedding_size(features)] 9 | - 3 dims: [batch_size, num_features, embedding_size(features)] 10 | 11 | Output shape: 12 | - 与输入维度相同. 13 | 14 | 参考文献 15 | - [Zhou G, Zhu X, Song C, et al. Deep interest network for click-through rate prediction[C]//Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. ACM, 2018: 1059-1068.](https://arxiv.org/pdf/1706.06978.pdf) 16 | - https://github.com/zhougr1993/DeepInterestNetwork, https://github.com/fanoping/DIN-pytorch 17 | """ 18 | 19 | def __init__(self, emb_size, dim=2, epsilon=1e-8, device='cpu'): 20 | super(Dice, self).__init__() 21 | assert dim == 2 or dim == 3 22 | 23 | self.bn = nn.BatchNorm1d(emb_size, eps=epsilon) 24 | self.sigmoid = nn.Sigmoid() 25 | self.dim = dim 26 | 27 | # 将alpha包装成nn.Parameter以便训练 28 | if self.dim == 2: 29 | self.alpha = nn.Parameter(torch.zeros((emb_size,)).to(device)) 30 | else: 31 | self.alpha = nn.Parameter(torch.zeros((emb_size, 1)).to(device)) 32 | 33 | def forward(self, x): 34 | assert x.dim() == self.dim 35 | if self.dim == 2: 36 | x_p = self.sigmoid(self.bn(x)) 37 | out = self.alpha * (1 - x_p) * x + x_p * x 38 | else: 39 | x = torch.transpose(x, 1, 2) 40 | x_p = self.sigmoid(self.bn(x)) 41 | out = self.alpha * (1 - x_p) * x + x_p * x 42 | out = torch.transpose(out, 1, 2) 43 | return out 44 | 45 | 46 | class Identity(nn.Module): 47 | 48 | def __init__(self, **kwargs): 49 | super(Identity, self).__init__() 50 | 51 | def forward(self, inputs): 52 | return inputs 53 | 54 | 55 | def activation_layer(act_name, hidden_size=None, dice_dim=2): 56 | """激活函数 57 | """ 58 | if isinstance(act_name, str): 59 | if act_name.lower() == 'sigmoid': 60 | act_layer = nn.Sigmoid() 61 | elif act_name.lower() == 'linear': 62 | act_layer = Identity() 63 | elif act_name.lower() == 'relu': 64 | act_layer = nn.ReLU(inplace=True) 65 | elif act_name.lower() == 'dice': 66 | assert dice_dim 67 | act_layer = Dice(hidden_size, dice_dim) 68 | elif act_name.lower() == 'prelu': 69 | act_layer = nn.PReLU() 70 | elif issubclass(act_name, nn.Module): 71 | act_layer = act_name() 72 | else: 73 | raise NotImplementedError 74 | 75 | return act_layer -------------------------------------------------------------------------------- /codes/rec/model/utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | from torch.nn.utils.rnn import pad_sequence 4 | import inspect 5 | # from torch4keras.snippets import * 6 | 7 | 8 | def sequence_padding(inputs, length=None, value=0, seq_dims=1, mode='post'): 9 | """将序列padding到同一长度 10 | """ 11 | if isinstance(inputs[0], (np.ndarray, list)): 12 | if length is None: 13 | length = np.max([np.shape(x)[:seq_dims] for x in inputs], axis=0) 14 | elif not hasattr(length, '__getitem__'): 15 | length = [length] 16 | 17 | slices = [np.s_[:length[i]] for i in range(seq_dims)] 18 | slices = tuple(slices) if len(slices) > 1 else slices[0] 19 | pad_width = [(0, 0) for _ in np.shape(inputs[0])] 20 | 21 | outputs = [] 22 | for x in inputs: 23 | x = x[slices] 24 | for i in range(seq_dims): 25 | if mode == 'post': 26 | pad_width[i] = (0, length[i] - np.shape(x)[i]) 27 | elif mode == 'pre': 28 | pad_width[i] = (length[i] - np.shape(x)[i], 0) 29 | else: 30 | raise ValueError('"mode" argument must be "post" or "pre".') 31 | x = np.pad(x, pad_width, 'constant', constant_values=value) 32 | outputs.append(x) 33 | 34 | return np.array(outputs) 35 | 36 | elif isinstance(inputs[0], torch.Tensor): 37 | assert mode == 'post', '"mode" argument must be "post" when element is torch.Tensor' 38 | if length is not None: 39 | inputs = [i[:length] for i in inputs] 40 | return pad_sequence(inputs, padding_value=value, batch_first=True) 41 | else: 42 | raise ValueError('"input" argument must be tensor/list/ndarray.') 43 | 44 | 45 | def get_kw(cls, kwargs, start_idx=3): 46 | '''保留类下的kwargs 47 | ''' 48 | return {i:kwargs[i] for i in inspect.getargspec(cls)[0][start_idx:]} -------------------------------------------------------------------------------- /docs/dialogue/1.概述.md: -------------------------------------------------------------------------------- 1 | # 1.概述 2 | 3 | ## 1.什么是对话系统 4 | 5 | 其实对话系统很好理解,对话系统就是人机对话的一个接口,人和他对话,他能给出一定的反馈,甚至完成一定的任务。举个例子,比较常见的就是淘宝的客服,问一些问题,某些有机器人后台的就会给出一些初步的回复,虽然有些沙雕,但是总能够完成部分简单常见的问题,能一定程度满足用户需求,从而降低了人工的成本。举个例子: 6 | 7 | > Q:你们商品一般什么时候发货。 8 | > A:当天发货亲。 9 | 10 | 这种很常见的简单问题,是可以通过客服系统直接回复的,简单方便。答案很多,回复也很多样,如何给出合适回复,这就是对话系统需要解决的核心问题。 11 | 12 | 而使用场景上,其实远没有大家想的那么冷门,可能大家身处互联网行业,或者是每天看的东西都是互联网而被这些信息给局限了,其实对话系统是非常常见的,除了上面说的客服,还有类似智能家居、智能助手等场景,其实非常依赖好的对话系统完成各种各种复杂的任务,我自己觉得最有幸福感的就是冬天天气很冷,在被窝里玩手机,只需要一句“帮我把卧室灯关掉”就能关了,这背后都有对话系统的身影,另外最近收到一些流调的电话,电话里的很多都是机器人在提问和记录。 13 | 14 | 所以,我其实感觉,对话系统没有想象中那么不堪,很多人觉得对话系统不赚钱没前途,我自己并不觉得悲观的,当然,对话系统的核心技术点——NLP,也因为同样的原因,其实不见得就“没前途”。 15 | 16 | ## 2.对话系统的类型划分 17 | 18 | 根据类型进行拆解,大家能够更好理解对话系统内部的本质,很多人可能都会听说类似“闲聊型”、“任务型”之类的,很多样,这里我按照我的理解做一些分类,让大家更好地理解对话系统以及其内部的一些技术思路。 19 | 20 | 说到分类,肯定是要提分类标准的,不同的分类标注肯定会得到不同的分类结果。 21 | 22 | ### 2.1根据结果输出的方式分类 23 | 24 | 分为检索式、生成式和混合式。 25 | 26 | - **检索式**顾名思义,通过查询来得到最终的答案。检索式的答案大都是有人提前进行了整理存到特定的库里面,在对用户query进行理解后即可根据结果查询到适合给用户的标准答案。这里的查询,可以是文本层面的查询,例如比较基础的ES,也可以是潮了一段时间现在被看做是baseline的向量召回,甚至是现在还比较潮的知识图谱,都可以算作是检索式。这种方式可能在对话系统中已经非常老了,但是仍旧是对话系统落地场景中最重要的方式,它具有很强的可干预性、稳定性等,结果是啥样就给的啥样,不会有什么风险,结果的正确性能够保证,而且NLP只需要关注理解和匹配问题,对答案内容可以不太关心,相比之下会简单很多。 27 | - **生成式**应该是现在大家看到的和分享的最多的,正因为他是比较前沿的,生成式就是通过模型或者规则的手段生成回复,可以说是非常智能的方案了。一般地,闲聊场景是非常常见的,最近看过的一次分享就是小布助手的生成式闲聊([小布助手闲聊生成式算法](http://mp.weixin.qq.com/s?__biz=MzU1NTMyOTI4Mw==\&mid=2247562192\&idx=1\&sn=0344248652f2c319c4860da300aebdb7\&chksm=fbd641bccca1c8aa19bdd76bed10daa4324d54bf47d8b6bfb556e3e3cd36338d3f0891103ebe\&scene=21#wechat_redirect "小布助手闲聊生成式算法")),就是直接能够根据用户query生成结果。这个方式的优点就是泛化能力强,对于没有提前准备答案的,知识点没覆盖的内容,他也能回复但是缺点也比较明显,就是可控性低,而且缺乏知识的生成式很可能会一本正经的胡说八道(从北京到深圳只需要2公里,这句话从通顺性上没毛病,但是逻辑上是有问题的,哪怕是GPT之类的模型也很容易出这个问题)。 28 | - **混合式**就是两者的混合吧,这里指的混合是指结果上的混合,检索式可以查到一些零散的信息,结合生成式可以将整个结果拼接成更为完整、更像“人话”的回复。 29 | 30 | ### 2.2 根据交互次数 31 | 32 | 这个划分很简单,如果只是回复一次就结束对话,上下文之间不考虑相关性,那就是单轮对话,与之相反就是多轮,毫无疑问多轮对话的难度要大于单轮,单轮对话遇到的问题多轮基本都会有,而多轮因为要考虑上下文,难度可就大很多了。 33 | 34 | 目前多轮对话的结构和思路是已经形成了一定的共识,即**需要DM模块(dialog management)来对对话内容管理起来**,无论是对方的还是机器的,都需要维护起来,确保一致,即DST(dialog state tracking),然后根据对话的进展以及对话管理下的内容进行综合评定给出最终回复,即DP(dialog policy),或者说是对话策略(dialog strategy)。 35 | 36 | 来几个多轮对话的例子,我就直接举翻车的例子了。 37 | 38 | > Q:今天天气怎么样。 39 | > A:今天晴,20度到25度。 40 | > Q:明天呢。 41 | > A:你希望问明天的什么呢。 42 | > 43 | > Q:你今年多少岁了。 44 | > A:我今年才3岁呢。 45 | > Q:你在哪个幼儿园? 46 | > A:我已经上班了。 47 | 48 | 前者是没有把用户说的内容给记录下,后者是没有和自己的结果维持统一,而为了保证这些东西,是需要把对话内容给完善维护起来的。 49 | 50 | ### 2.3 领域范围 51 | 52 | 根据领域范围的不同,把它分为**开放域**和**封闭域**,后者也有叫做垂直域的,都行。先不聊机器和技术,就聊人的对话,本身其实是有一个背景或者一个先验知识的,这会导致不同的人在不同场景下理解会不同。同样一个说法,“上号!”,在游戏圈背景下,那就是要上对应游戏了,在技术群里说一句,说不定就是去leetcode了,这是封闭域,这个封闭域下大家有了很多的先验信息,大家对这种简单的话判断就会比较明确,但是如果在大庭广众下吼一句,估计很多人会觉得你不太正常,这就是开放域,大家认为你这个话是模糊的。说完了人,在来说说对话系统,这个和搜索系统类似,在封闭域下一些很明确的话,可能在开放域就很模糊了,“手机卡怎么办”对电信客服来说理解就是办理手机卡业务了,对手机客服来说很可能首先理解是手机卡顿,当然手机卡办理估计也会怀疑可能是,但是如果开放域这个句话就是妥妥的歧义句了。 53 | 54 | 所以,针对开放域和封闭域,都有特定的一些技术手段来保证结果的准确性,例如**开放域会花费很多精力来做意图识别,而封闭域可能更倾向于根据一些信息的补充来直接给出答案**。 55 | 56 | ### 2.4 特别的类型 57 | 58 | 这里讲一些比较特殊的场景类型吧。 59 | 60 | 首先是闲聊。闲聊应该是很多人首先接触到的场景了,顾名思义,就是人随心所欲地聊天的那种场景,这种场景小则是一些闲话,但绝对不局限于此,闲聊其实一直是一个非常复杂的问题。首先,这个对话肯定要是正常的对话,但是人正不正常不好说,很多引导性的、涉黄涉政涉暴的,要从容应对可不简单,机器人被要求友好,被骂了骂回去可不见的合适,很多时候,是需要检索式来支持的,甚至是避不开的需要;第二,有的人喜欢娱乐明星,有的人喜欢政治军事,有的人喜欢二次元,有的人喜欢打游戏,有的人喜欢机器学习,背后的知识可能会很多,知识依赖可就很高了;第三,多轮问题,懂的都懂,甚至还有人设问题(对应的身份、年龄的人做对应的事,这就是人设)。 61 | 62 | 然后是客服。客服应该是很常见的场景了,淘宝一堆,然后还有了一些类似医疗问诊、银行证券之类的,也都很需要客服,检索式应该非常常见而且关键的技术方案了,因为要保证答案准确可控,但是客服可能不局限此,一些多轮和对话策略其实在很多客服系统都是支持的,从而增强用户体验,但是这个其实是很高级的功能了。 63 | 64 | **任务型**。应该是一个很典型的一种类型的对话系统了,通过不停地追问和对答案的记录,最终完成特定的任务,先来个例子吧。 65 | 66 | > Q:我要订机票。 67 | > A:要定从哪里出发的机票呢? 68 | > Q:从深圳,到北京的。 69 | > A:好的。希望什么时候出发? 70 | > Q:明天上午10点左右吧。 71 | > A:好的,系统给你找到XXX航班,明天10点05分起飞,预计13点到达,请问是否合适? 72 | > Q:可以的。 73 | > A:已经为您预定XXX航班,请点击付款完成最终操作。记得提前办理值机手续哟。 74 | 75 | 这里,通过一连串的追问获取信息,引导用户完成一个完整的订机票流程,这就是任务型,这也是多轮最典型的案例,需要记录信息并且最终完成一个任务,NER和意图识别要把对话中的要素提取,对话管理内需要维护好用户这一系列的信息,追问是一个答案生成的过程,最终还要完成这个任务。 76 | 77 | **对话推荐**。这里的推荐不是指疑似问和相关问题(当然这也是一个研究的领域了),而是至一种带有一定推荐性质的对话。来一个电商场景的吧: 78 | 79 | > Q:我想买一台电脑,大概6000元,有什么推荐的吗? 80 | > A:为你找到6000左右的电脑,你看这些合适吗? 81 | > Q:有没有游戏本? 82 | > A:为你找到6000左右的游戏本,你看有合适的吗? 83 | > Q:这台XXX有没有别的配置,只有i5吗,有没有i7的。 84 | > A:有的,这是XXX-i7版的。 85 | 86 | 这段对话内,是一个给用户推荐商品的过程,用户会有一些商品需求,需要根据用户的需求找到符合用户需求的产品,这里其实更像是带条件的搜索了,而如果是能考虑到用户画像和习惯,甚至可以做一些个性化,形成一个推荐系统,这里的问题就更热闹了,而其特点就在于,是带有用户条件的,这里其实更像是个性化搜索,不过是对话系统场景了,从产品上,我们不仅要考虑推荐的内容,还需要考虑生成的回复话术,简单的可以考虑是固定的,但都是复杂的可能还会有一些结合产品特定的生成或者拼接。 87 | -------------------------------------------------------------------------------- /docs/dialogue/2.技术架构.md: -------------------------------------------------------------------------------- 1 | # 2.技术架构 2 | 3 | ## 1.先来几个案例 4 | 5 | 架构是一个抽象的概念,而实际的落地应用则是架构的现实体现,所以相比直接把结论喂出来,更想先和大家讨论下现在业界的一些架构和设计思路。 6 | 7 | ### 1.1 平安智能问答 8 | 9 | 之前有写过文章讨论过:[平安智能问答系统](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247486102\&idx=1\&sn=00119d07f8b3b8e2ca6fc394cd3fb65a\&chksm=e8825208dff5db1e192942192a0010de25fe182c7e2d0ad5559be79e4bc225498ee186498c09\&scene=21#wechat_redirect "平安智能问答系统")。这里再抽出关键点讲一下。平安的技术架构可以用这个图来解释: 10 | 11 | ![](image/image_oVEDRXtSom.png) 12 | 13 | 这个架构图是按照处理流程来画的,即预处理、检索、知识图谱和信息处理、排序、结果输出等。整个对话系统就覆盖了这些内容。 14 | 15 | - **预处理**:包括分词、词性、实体推荐、纠错、多意图、句子匹配等等,在别的领域可能更多叫query理解了,就是对句子进行一些预处理,并且提取一些关键信息。 16 | - **检索**。这里的检索包括ES的检索和孪生网络,说白了就是文本检索和语义检索。 17 | - **知识图谱和信息处理**。说白了也是一种检索的过程,只是这里涉及到语料和图谱的管理罢了。 18 | - **排序**。针对多路召回的答案,根据语义、关键词、编辑距离等因素进行综合排序,最后甚至还有一些利用用户画像的操作。 19 | 20 | ### 1.2 微软小冰 21 | 22 | 这篇文章其实也讲过:[微软小冰-多轮和情感机器人的先行者](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247485954\&idx=1\&sn=53c49a5af387cd86ea51a6407818e414\&chksm=e882529cdff5db8a6d04891e9e939475409d547798c51f00d9fad6a695fd1d96a080160d0148\&scene=21#wechat_redirect "微软小冰-多轮和情感机器人的先行者"),文章中对小冰的评价非常高。主要是因为小冰起步的真的挺早的,而且现有很多技术和思想也很前沿,撑得起“先行者”之名吧,可以参考一下小冰的技术架构: 23 | 24 | ![](image/image_H-KuJoI867.png) 25 | 26 | 这个是按照模块划分的,告诉了我们他们是怎么切分的。 27 | 28 | 首先是有客户端,接受各个入口来的用户信息,主要是query,但这里看其实还有很多多模态的输入,声音、文本、图片、视频等,这个入口无疑也是多元化的。 29 | 30 | 中间是我们非常关心的对话系统层,里面包括了闲聊、技能、情感计算、和对话管理模块。 31 | 32 | - 即使是闲聊,也按照通用闲聊和领域闲聊,拆解比较细致,领域闲聊里无疑还有很多知识维护的工作,有知识支撑的闲聊应该也是现在比较潮的技术话题了。 33 | - 技能是为了让小冰具有完成特定任务和需求的能力,这里包括任务完成等很实用的技能,能帮助人完成一些基础工作。 34 | - 情感计算应该是小冰比较特色的能力,一方面能理解用户的情感,另一块能有一定的社交能力,形成小冰自己的“人设”,从而产生一定的情感“反馈”,这个到现在也还是比较牛的场景落地。 35 | - DM是多轮对话标志性的模块,要对整个对话管理起来,细分下,就是对话状态跟踪和对话策略,说白了就是一个处理输入和生成输出。 36 | 37 | 最底层,就是对话层,数据的重要性毋庸置疑,对算法来说这点我们更有感触,而小冰的底层数据,除了我们熟知的基础物料(知识),还有比较有特色的小冰画像(人设知识)、用户画像(用于个性化)。 38 | 39 | ### 1.3 美团智能问答技术 40 | 41 | 美团智能问答技术这块没写文章讲解,原文在这里:[https://mp.weixin.qq.com/s/IN-xzbrjjV2XgrGLPS5wRw](https://mp.weixin.qq.com/s/IN-xzbrjjV2XgrGLPS5wRw "https://mp.weixin.qq.com/s/IN-xzbrjjV2XgrGLPS5wRw") 42 | 43 | ![](https://mmbiz.qpic.cn/mmbiz_png/zHbzQPKIBPhGiaj4X9pXzH6yA8sNPTg3zVZYopQhfkenp14BYagRoibZGDk3eA5HEsqfAMVs9uaiaKFRTjElLBaXA/640?wx_fmt=png) 44 | 45 | 这个图也比较简单,对于对话系统本身,对话系统主要就是对应问题理解和问题解决,问题推荐属于另一个业务问题,这里先不聊。 46 | 47 | 在问题理解模块,主要覆盖了意图识别、实体识别等基础的NLU理解为,也有一些澄清这种对话系统比较特色的技术(模糊意图下形成向用户澄清的话术,例如“你说的啥?”),也有一些类似时效识别之类的场景特色的技术点。 48 | 49 | 至于问题解决,就是根据问题理解的结果,去生成回复,这个生成的方式很多,可以走图谱,可以走阅读理解,可以走任务型多轮,可以从社区问答里面找,甚至还有非常直观能够想到的文本生成,最终就是从多个回复中进行筛选和排序甚至是融合,最终解决问题。 50 | 51 | ### 1.4 案例小结 52 | 53 | 看完这几个工业界大厂的技术设计,其实大家都能从中找到一些共性,无论是计算流程,还是模块拆解划分,都有一个初步的了解,也能发现一些共性,对话系统在工业界的使用,思路就明确了。 54 | 55 | ## 2.对话系统的架构 56 | 57 | 流程架构针对的是整个对话系统的处理流程,即用户从提交query到最终获取回复的流程,基本流程就是这些: 58 | 59 | - **Query理解**。覆盖意图识别、实体识别/提槽、语义表征等共性的NLP处理技术,也有一些涉及拒识、澄清、盘全等技术。 60 | - **对话管理**。针对多轮对话,需要将历史的对话内容甚至是用户画像构造并维护起来,并根据现在的现状,总结出当前最优的对话策略。 61 | - **结果生成**。根据Query理解和对话管理的结果,获取特定的答案,这里有检索、排序等和推荐系统还比较相似的操作。 62 | 63 | 对话管理,虽说学术界在这块研究的还算前沿,但是在工业界的发展并没有想象中顺利,无论是技术实现上,还是用户需求的复杂性上,都为多轮的落地实施带来巨大挑战,一方面多轮的信息的存储和处理,另一方面是根据先有信息和状态进行对话策略的生成,从而为下游答案筛选和排序提供依据,当然了,一些复杂的功能,例如主动对话、对话是推荐这种比较新潮也比较智能的技术,都需要依赖对话策略的设计来实现,如果策略做的不好,用户很可能会认为这是“答非所问”。 64 | 65 | 结果生成,这个过程其实和搜索非常类似,即是根据上游得到的结果,进行结果的召回,这里的召回思路打开,可以有很多: 66 | 67 | - 文本召回。检索式对话那套最简单的模式,进行q-q,q-a匹配做结果召回。 68 | - 语义向量召回。对query进行语义向量表征,进行向量召回。 69 | - 知识图谱的识别和推理。 70 | - 文本生成。很多多种信息进行受控的结果生成,生成特定的回复。 71 | 72 | 多路召回后,结合多种信息进行排序,这里的排序的学问也不少,相比搜索,会多很多对话相关的信息,相比推荐,也有很多的query处理的信息。 73 | 74 | ## 3.架构背后的考量 75 | 76 | 技术架构的设计背后其实就是一个系统工程,一个合理的架构和模块拆解能让系统在运行、维护、迭代过程更加流畅。在理解了对话系统整体架构的设计之后,可以进一步探索一下。 77 | 78 | 首先,**Query理解成为比较稳定的独立模块**。对句子本身的理解,虽说部分内容可能会涉及人的认知会有些偏差,但是总体其实是比较固定的,把用户的内容充分理解后,也可以做很多事,特别的其实很多不同类型的文本都需要做理解,很多细节其实是业务无关的,那么Query理解就有必要独立化,另外在迭代上,他的迭代更多不来源于产品需求,而是一些意图召回、实体召回的效果提升,独立出来有利于降低对其他模块的影响。这点其实和搜索也非常类似,意图识别、NER任务独立化以后,能独立确定迭代的节奏。 79 | 80 | 第二个关键点,**对话管理模块的设计**,在现实落地的场景下,对话管理需要单独维护起来,主要原因是在计算机网络架构下,多轮对话背后其实对应用户的多次请求,多次请求但是对应多一批对话需要依赖类似sessionid的方法是实时维护,这不仅是算法的活,还需要大幅度依赖工程和数据方面的技术,形成一个综合的,交叉最多的技术点。诚然多轮的技术非常复杂,很多步骤其实都可以需要多轮信息,但是把各种多轮的操作都集中在这,显然是有大量的工程操作考虑的,举个例子,用户意图大都是上下相关的,如果把多轮信息的处理放在Query理解了,那工作量会骤然增大(想想打断、转移之类的凑在哦),加上多意图,这里的处理逻辑会很多,所以适当拆解,Query理解只负责把多种可能算出来,在对话管理模块再来筛选,会更合适。 81 | 82 | 第三,**召回和排序的处理**。对话系统的答案生成技术逐步多元化,让我们有了很多答案生成的模式,然而我们知道,不同的结果产生方案会对应很多场景,他们不是完全意义的平替关系,例如客服系统其实更倾向于检索式,毕竟答案可维护而且可控,生成的使用会比较谨慎,所以会把答案获取得到这个模块做成和搜索推荐相似的多路召回思路,所有可能得到答案的路径都会尝试去查查。这里,一方面是算法需要构造合理的表征进行计算,另一方面是工程需要在这里去搭建多种不同的数据中间件以满足不同的搜索需求,因此有了这种召回层的设计,而紧接着,就需要一个综合排序来找出最合适的方案。 83 | 84 | ## 3.架构和项目阶段的关系 85 | 86 | 当然了,抛开需求谈架构绝对是不合适的,这3个案例其实都建立在流程比较完善,业务也比较稳定的情况下了,但是初期,其实我们并没有太大必要切分那么细。来举个例子吧。 87 | 88 | - 例如,做检索式问答系统,那召回的链路就会比较简单,甚至只有一个,此时完全没必要把召回和排序拆开,只需要在查回结果后,直接根据相似度等因素进行排序即可。 89 | - 再例如,在系统比较简单的情况下,甚至是不需要很重的query理解的,例如意图识别,甚至可以不做,直接去进行检索排序都行。这里要明确意图识别存在的意义,主要是在用户需求非常分散的情况下,通过意图识别识别用户意图,从而方便进行一些不一样的设计,例如百科知识和音乐播放,最终给的结果形式都不同,此时有一个意图识别,能为下游做不同的操作提供一定的空间。 90 | 91 | 所以,上面的架构只是提供技术上的一些拆解思考,做出一些设计建议,也让大家了解到对话系统中涉及的算法技术有哪些,从而对对话系统在技术层面有一个宏观的认识。 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/dialogue/3.query理解.md: -------------------------------------------------------------------------------- 1 | # 3.query理解 2 | 3 | ## 1.query理解是干什么的 4 | 5 | 上一期在给出的美团智能问答技术的架构中说到了问题理解,这里所谓的问题理解就是我说的query理解,在这一步中,**需要做的就是把用户提出的内容充分理解,从而让我们后续的回复能更精准**,这点和我们日常的对话是符合的,只有理解对方说的话,回复才有意义。 6 | 7 | 这里聊清了他的意义,但是具体做的事情其实并不清晰,而具体要做什么,首先要考虑的是,说query理解是为了最终的回复结果,是指就是为了下游的结果生成服务的,这也意味着,query理解的任务很大程度上和下游的需求有关,下游需要什么,我们提取什么。 8 | 9 | ## 2.query理解的具体任务 10 | 11 | ### 2.1 美团智能问答技术 12 | 13 | 先来看看上次提到的美团,看看他们在做什么 14 | 15 | ![](image/image_kjDyaPkpUM.png) 16 | 17 | 可以看到,主要是6个部分,这里先解释下,当然了有些是联合在一起起作用的就合在一起了: 18 | 19 | - **领域意图识别**:主要用于识别query的话题意图,下游针对不同的意图是有不同的资源或者是处理方式,所以这个意图识别非常重要。 20 | - **领域路由和意图澄清**:和搜索不同的是,在多意图上的处理,对话系统在只能给一个结果的情况下只能转为澄清或者取一个概率明显高的,这个判断的工作则要由领域路由来判断然后做这个意图澄清。 21 | - **实体识别和链接**:实体的抽取和链接,下游如果是KBQA或者是文本检索,其实是非常需要实体信息的。 22 | - **时效识别**:应该是美团场景特有的一个点了,就是识别某个实体或者活动的时效性,例如有些活动结束了,那应该是需要给拒绝的回复了。 23 | - **实体澄清**:这个和多意图其实类似,举个例子大家就明白了——“苹果”。 24 | - **句式识别**:顾名思义,就是识别整个句式,这个具体的用法很多,例如有的时候有了句式,能快速识别意图或者是实体。 25 | - **槽位填充**:槽位填充和实体识别很类似,很多地方的说法会不太一直,就槽位而言,主要是看指的是向用户追问还是用户提出的槽位问题需要对话系统来填。 26 | 27 | 这些任务,都是旨在从query中抽取甚至是推理出一些信息,这些信息是有利于给出回复的,例如意图识别是探索用户的需求是什么,ner则是给出用户更加细粒度的要求或者是用户的一些先决条件,当用户给出的内容我们感到模糊的时候,也可以适时返回一些澄清意图,引导用户更好地描述他的问题,从而让我们进一步回答。 28 | 29 | ### 2.2 平安对话系统 30 | 31 | 看完美团的,回头看看平安的,其实相比之下,平安的对话系统会稍微简单一些: 32 | 33 | ![](image/image_kW3I3wYCtU.png) 34 | 35 | 这里的细节里可以看到,整个理解被看做是整个预处理模块,这个可能和下游的处理复杂度有关,他这里下游主要是ES检索和向量检索,从而那张可以多少看到,对多轮的要求不多,而是个性化等方面会比较多,所以在query理解上就会相对简单了。 36 | 37 | ### 2.3 共性query理解任务 38 | 39 | 从上面的两个例子可以看到一些比较共性的任务: 40 | 41 | - 意图识别。 42 | - 实体识别。 43 | 44 | 而另一方面,也会有一些针对业务定制化的任务和根据下游数据需求去做的任务,前者有美团的时效识别,后者又有类似实体链接之类的任务。 45 | 46 | 其他的多少要么就是细节内容,我平时讲的语义匹配或者相似度问题,但是这个可能会不放在这里,而一般放在检索之类的里面,这个我放在下一篇讲吧。 47 | 48 | ## 3.query和下游任务之间的关系 49 | 50 | query理解要做的是理解query,但不能局限于此,而还应该考虑下游要怎么用,而不能我们擅自去划分,而这里进一步展开,可以考虑的因素有这些,分段展开描述。 51 | 52 | - **对于****检索式****,下游利用意图识别的方式是什么**。直接的,是字段检索构造语义向量的特征,如果是字段检索,那都有哪些字段,类目体系如何,类目之间的边界是什么,这些都是需要去明确和了解的,同样是大类小说,但是类目下有小说名。作者、发布时间等,甚至有些模糊的直接带了些标签,例如“最新”、“恐怖”、“爱情”等等,底层的数据结构是什么样的,只有充分了解,才能让下游更好的利用起来,如果自顾自的做了一版,效果还很好,但就是不好用,那肯定是不行的。 53 | - **对于****生成式****,也要考虑生成式里需要用到的信息有哪些**,毕竟肯定不想要言而无物的万能回复,带一些信息的回复总不至于把天聊死,所以提供的信息就非常重要,此时就要看下游用的信息是用到什么粒度,例如是只需要实体,还是要详细到实体类型的实体信息,下游要根据意图变化给出一些对话策略,那意图体系也要尽可能和下游的意图对话策略对齐。 54 | 55 | 所以,回到query理解任务下,**需要充分了解下游任务的需求,才来去做query理解,合理划分任务,才能做好这颗在整个系统中的螺丝钉**。 56 | 57 | ## 4.query任务解释 58 | 59 | 从日常实践的经验来看,我们更多关注的不应该用什么模型,而是具体设计的思路以及具体的数据,数据集的优化往往是大幅提升效果的快速方式,真心的,大部分情况,textcnn和bert没有太多效果的差异。 60 | 61 | ### 4.1 意图识别 62 | 63 | **意图识别可以看做是一个文本分类任务**,因为这个任务实质上就是把query识别到特定的类目上去,与常规nlp任务不同的主要是这几个特点: 64 | 65 | - 类目边界不明确,这块其实难度不小。 66 | - 数据质量大部分情况都不高,需要花大量时间操纵数据,这也是很多情况模型效果diff不明显的原因了。 67 | - 空间分布可能会比较零散,这个其实会一定程度影响我们的方案设计的,模型上也要考虑多空间的承载能力。 68 | - 数据会具有一些场景特色,如名词性场景、口语化问题等。 69 | 70 | 虽说意图识别可以被看做是一个文本分类的任务,但不局限于用文本分类的方法来解决这个文本分类的问题,与之对应的,更建议是把他当做一个完整的系统来进行处理: 71 | 72 | - [心法利器\[29\] | 把文本分类任务做成一个系统](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487101\&idx=1\&sn=f511c12331fb7c2b33bdd973efd4e2a7\&chksm=e88256e3dff5dff57393ea70a09544c5e949cefb6b2c25588ea4069008e52387a279e34fb815\&scene=21#wechat_redirect "心法利器\[29] | 把文本分类任务做成一个系统") 73 | - [前沿重器\[20\] | 文本分类和意图识别调研思考](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247488016\&idx=1\&sn=840dcd8585c294a5611e99888a27ae1b\&chksm=e8824a8edff5c39821117112b85636411d53b312440f070aeb5e31d4f79ef2a5d5fb443324fe\&scene=21#wechat_redirect "前沿重器\[20] | 文本分类和意图识别调研思考") 74 | - [心法利器\[26\] | 以搜代分:文本多分类新思路](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487022\&idx=1\&sn=8d4637014107c76c895cbed2e3d6f81b\&chksm=e88256b0dff5dfa61c3b8fe5b7041b7b2a172ca5df4aca02decec6abfcff2b61b48e7687d1df\&scene=21#wechat_redirect "心法利器\[26] | 以搜代分:文本多分类新思路") 75 | - [心法利器\[11\] | 任务方案思考:文本分类篇](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247486329\&idx=1\&sn=d83000fea702b6c7ec6ba3584b24a7fe\&chksm=e88253e7dff5daf1acdee035b0712fb0376e49a17211fb7dd716760542da81ca598f8d1681af\&scene=21#wechat_redirect "心法利器\[11] | 任务方案思考:文本分类篇") 76 | 77 | ### 4.2 实体识别 78 | 79 | 实体识别的本质就是一个NER问题,而且可以是一个比较传统的NER问题,在大部分情况不太需要考虑嵌套、连接之类的问题,在早起版本我们可以把一些复杂的问题放到相对不关键的位置,关键点还是抽取出实体,这一方面是让我们不需要考虑太过复杂的ner模型,另一方面也给了传统地词典匹配足够的生存空间。 80 | 81 | 这里再仔细聊聊对话场景相比一般场景的NER特点: 82 | 83 | - 大部分对话场景,有一定的时效性,这个时效性体现在一些新热词汇的抽取,基本上都要给这个问题留空间,所以词表肯定是要留着的,必须做。 84 | - 短句问题,同样可能需要词典来处理,尤其是光杆名词的时候,词典效果是最好的,毕竟没有上下文,模型很难生效。 85 | - 上面提的分类的口语化问题难做,但其实NER反而好做一点。 86 | 87 | 具体的方法可以看这些文章吧: 88 | 89 | - [心法利器\[12\] | 任务方案思考:序列标注(NER)篇](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247486348\&idx=1\&sn=a6010380e084ad8b27fd6168eccff079\&chksm=e8825312dff5da04dbe55c50233320d7a5059f4c229bd6bf7926ac63275d2f325d20cfd70229\&scene=21#wechat_redirect "心法利器\[12] | 任务方案思考:序列标注(NER)篇") 90 | - [NLP.TM\[29\] | 近期做NER的反思](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247485200\&idx=1\&sn=049a2a9bd2527a3f5b6c769386d0e9c0\&chksm=e8825f8edff5d698a6e6c7484bb41f1dd07d5c60a0ad6d04899d34b2abaea6520afb145e9472\&scene=21#wechat_redirect "NLP.TM\[29] | 近期做NER的反思") 91 | - [NLP.TM\[31\] | 2018年的一篇NER综述笔记](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247485222\&idx=1\&sn=6dd56d91bc33e70df0f64edbfadb9bd8\&chksm=e8825fb8dff5d6ae4ade676002eff8d3dee34568ec4e14d92aa191bb7fe98a47b21c5749d1a4\&scene=21#wechat_redirect "NLP.TM\[31] | 2018年的一篇NER综述笔记") 92 | - [NLP.TM\[18\] | 搜索中的命名实体识别](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247484954\&idx=1\&sn=69b4662284aec3f5eda3e64c55c49c6c\&chksm=e8825e84dff5d7921fd35b765d1a004f537466e018d4ba20e5966c57c30ccbb0cde72e07b315\&scene=21#wechat_redirect "NLP.TM\[18] | 搜索中的命名实体识别") 93 | 94 | ### 4.3 其他的工作 95 | 96 | query理解的工作主要是这些,而另外的,则是一些场景特点或者是下游任务需求去增加的了,例如纠错、实体连接、时效性之类的,甚至包括关键词抽取或者是词权重,这种要根据任务需求来进行设计和优化了,此时尤其要明确好需求。 97 | 98 | 举个例子,关键词抽取,在很多讲解中,大部分是根据任务需求来整的,有的时候关键词是那些名词的词汇,有的时候则是动词的词汇,而反推过来,其实所谓的关键词,是要看对谁关键,有的时候,是需要作为关键词给用户看的,有的时候则是给相似度模型看的,这直接导致了抽取方式需要有所取舍判断,此处对于对话系统,其实和搜索系统类似,都是抽取“对相似度模型有利”的词汇,这个就是所谓任务设计根据需求来设计了。 99 | 100 | ## 5.对话系统特别场景的应对 101 | 102 | 如果仅仅从NLP角度出发,可能对话系统中拆解得到的很多任务都非常成熟,但是一旦到了落地场景,其实问题绝对不是NLP任务那么简单,是需要考虑到这个场景下的用户习惯的,这些习惯直接导致的是用户的query具有特定的风格,而这些风格,不见得模型能够简单的解决,而需要更多辅助措施才能解决。在日常遇到了不少,这里我聊一些。 103 | 104 | ### 5.1 时效性问题 105 | 106 | 类似热点话题、新品迭代比较快的电商平台,这些场景下,都会有很多时效性很多的产品,举个例子,公司出了新品,先不论下游的检索,就是上游的ner和意图识别,都需要快速更新,一般的分类和实体识别模型去做的话,意味着要更新模型,更新模型这个事无论是在效果的稳定性上还是在更新及时性上都有很大风险,而相反,通过词典和模板的方式来处理则无论是在稳定性还是效果上都有稳定的保证。 107 | 108 | ### 5.2 口语化问题 109 | 110 | 对话系统本身给用户的感知就是一个聊天框或者一个完整的对话系统,所以相比搜索,用户给出的query会更加口语化,也会更加偏向于完整的句子,更严谨的说,就是完整句子的占比会比搜索高一些,这也就让我们不得不重视这个问题了。 111 | 112 | 有关这个问题,其实有文章专门聊过:[心法利器\[52\] | 口语化句子解析问题](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487997\&idx=1\&sn=945e9c54354b2a593b7eacf284a7f61b\&chksm=e8824963dff5c0756130372a1c2fa511e66400818e6fde66491b37d2a41a32b7c3c865c0bb3f\&scene=21#wechat_redirect "心法利器\[52] | 口语化句子解析问题")。这里简单说一下,就两个角度,模型角度和数据角度。 113 | 114 | - 数据层面是收益比较大的,这里通过定向的补充样本进行优化,就能有比较好的效果了。 115 | - 模型层面,则是使用对抗学习、r-dropout之类的方式对模型进行一定的扰动,毕竟口语化本质还是对句子的信息扰动,所以增强模型鲁棒性,能一定程度缓解这个问题。 116 | 117 | 当然了,这个口语化的问题,可以一定程度描述为长句问题,其实解决的思路和这个类似,所以长句问题不赘述了,但是短句,还是要拿出来的。 118 | 119 | ### 5.3 短句问题 120 | 121 | 长短句之前我同样聊过([心法利器\[51\] | 长短句语义相似问题探索](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487992\&idx=1\&sn=a07de64da1588ee3ede499413966409d\&chksm=e8824966dff5c070089da72c3e3bf15d2057386f71a92451ebb972998ec96443102cf9abebeb\&scene=21#wechat_redirect "心法利器\[51] | 长短句语义相似问题探索")),不过是在语义相似度上的,其实在综合的query理解也会有类似的问题,但是更多是在短句上,这点和搜索是类似的,这个和口语化可以说是两个极端了,对于短句的问题,主要是两个情况比较多吧: 122 | 123 | - 有意义的短句,例如“维修”,意义就很明确。 124 | - 无意义的断句,在一些场景下,用户可能给的短句含义不是很多或者表意不明,例如“请问”,也有一些在特定场景,可能类似"你好"也是无意义词,但是有些场景可能会认为是有意义的,就看你有没有设计“欢迎”意图了。 125 | 126 | 常规的,句子短信息少,信息少会导致两种情况,分别是无意义和模糊。一般这种问题的解决思路是这样的: 127 | 128 | - 意图识别在做的时候,需要考虑短句,常规情况,短句模型是可以覆盖的,尤其是高频的,没见过的理论上应该拒绝。 129 | - 对于新词,就该延续时效性问题那块的处理,用词典来解决,很方便。 130 | - 一般地,被意图识别统一识别为负类的,自然就是无意义的,这样无意义的能被摘出来,而对于困难的,黑名单自然可以安排,短句其实要挖掘覆盖起来难度不会很高的。 131 | 132 | 意图识别模块的把关其实还好,而对于多意图,此时则需要通过一定的规则和置信度,来调整排序,甚至是,可以在多意图情况下给用户一个澄清,这个在美团那个案例里就有聊到澄清的问题,例如“你是想要问下面的哪个问题”,这个需要和产品一起沟通最佳体验的回复,当然这个是短句引申出来的问题,但是这本质上应该是一个模糊澄清的处理问题,而非短句了。 133 | 134 | ## 6.小结 135 | 136 | 本文着重去聊的,主要是这几个点: 137 | 138 | - 整个query理解都有哪些关键的组件,不同的业界还往这里面塞了什么有特点的东西。 139 | - 重点的query理解任务,都是怎么做的。 140 | - 对话系统中的任务,和常规的NLP,在数据和场景上有什么特点,以及如何应对。 141 | 142 | -------------------------------------------------------------------------------- /docs/dialogue/4.内容输出.md: -------------------------------------------------------------------------------- 1 | # 4.内容输出 2 | 3 | ## 1.核心思路和架构情况 4 | 5 | 一般的,会把整体思路分为两种,检索式和生成式,当然现在也有很多方法其实算是两者结合的方法。 6 | 7 | - **检索式**重在检索,根据query理解的结果,在特定的库中进行查询,找到答案后输出,或者在找到之后通过组装完成输出。 8 | - **生成式**则是根据query理解的效果去生成特定的回复,基本使用的是文本生成的方案了。 9 | 10 | 而对于整体架构而言,这两者往往不是完全独立的,而是两者互相辅助互为补充,或者可以理解为多路召回,后续根据对话策略进行筛选排序,找到最优解。 11 | 12 | ## 2.检索式 13 | 14 | 检索式对话这种模型相信很多人都不陌生了,也专门写过文章聊过([NLP.TM\[38\] | 对话系统经典:检索式对话](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247485924\&idx=1\&sn=549116a02409d0b86cf6b3e1cd12c921\&chksm=e882517adff5d86c489c9551bf17ee8628f35d2e4370c01dbe8cca5399580282e5a3dc484a99\&scene=21#wechat_redirect "NLP.TM\[38] | 对话系统经典:检索式对话")),随着技术的逐步迭代,检索的方式其实也逐步丰富化。 15 | 16 | ### 2.1 检索式的基本方法 17 | 18 | 首先,大家可以看看检索能有什么比较流行的方式:文本/结构化检索,表征式向量检索,知识图谱推理。 19 | 20 | - **文本/结构化检索**。比较传统的检索方式了,基本的是类似ES之类的检索,当然有些非常明确的抽取,mysql也可。这种检索对query理解的要求不小,因为检索时的最优方案是,特定字段搜特定内容,有一些类似“你们有卖5000元左右的电脑吗”之类的疑问,我们甚至需要识别5000是一个价格,从而针对性的进行检索。当然了,有一些比较粗暴的方式是把所有内容拼接然后构造倒排索引,这个会对query理解要求降低,但是相比之下对相似度计算的要求会提升,这个需要权衡,例如如果特外特征很多很杂,这个时候对query理解的难度很大,拼接的方式更简单,例如购物场景的对话,而如果特征不多但是比较集中,此时query理解抽取出来可能更好,例如小说场景的对话,基本都围绕那几个关键槽位,如小说名、作者等。 21 | - **表征式向量检索**。这个好像是大家目前最容易想到的办法了,之前有专门聊过这个问题([心法利器\[16\] | 向量表征和向量召回](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247486586\&idx=1\&sn=ddd1716c5e5860361df3e45de0f14de9\&chksm=e88254e4dff5ddf289bdf02e5e6d18baf42bda78415b61e620c567a749fafb00d2dacd50232a\&scene=21#wechat_redirect "心法利器\[16] | 向量表征和向量召回")),把query等特征进行表征,然后用向量索引做召回,这个详细聊过这里就不赘述了。 22 | - **知识图谱推理**。对自己来说多少算一些超纲,但是确实是逐步成为一个比较重要的技术了,毕竟可解释性和可控性比模糊泛化要好很多,知识结构也更容易定义,而最突出的,其实是他能体现人类文明的逻辑型,这点是常规的生成模型所很难具备的,哪怕强如GPT模型,回答的流畅性应该没什么问题,但是逻辑型可能就很难保证,而知识图谱是能解决这个问题的。 23 | 24 | ### 2.2 检索式知识库的来源 25 | 26 | 所谓的检索式就是查,而查的一大前提就是有库的支持,然后才可能找到结果从而返回,这就如米之于炊,没有米就做不了饭了,所以,这里检索库的知识点就需要大量的资源来构建,这里提供集中比较常见的方式,也强调下这个的重要性。 27 | 28 | - 人工维护。在很多对话机器人的场景,例如客服,是要确保知识的正确性、官方性、稳定性、可控性,有一个可供维护的能力,其实对对话机器人很重要。 29 | - 在线开源资源。在允许的情况下从三方或者是网上获取。 30 | - 结合日常人工的对话,进行挖掘和抽取,这也是个很好的方法。 31 | 32 | 总之,检索式对内容的要求其实不低,我们往往是需要花费一些时间去整理和结构化,才能支撑到在线的使用。 33 | 34 | ### 2.3 检索的匹配度问题 35 | 36 | 库很大,**查询的本质是从中找到一些比较接近的,可能是结果的答案,这里依赖相似度来做排序和截断**,常规的字面和语义相似度都是比较好的方法,具体的就是我们熟知的那些相似度模型,字面的有jaccard、cqr/ctr、BM25,语义的就是DSSM系列、sentence-bert等的表征式和ESIM等的交互式还有一些更复杂的模型,但是在实践中,单一的相似度可能并不完善,有的时候会结合一些query理解、内容质量等信息会有更好的效果,此时可以组装出一些很实用的大型模型来统一处理。 37 | 38 | ## 3.生成式 39 | 40 | 首先,生成式在一段时间内而且在特定场景下是一个很实用的方案,尤其是闲聊,而且在一定情况下收益还是不小的——这个,应该是大部分人对生成式的直观理解,但是在现实应用真的是这样吗? 41 | 42 | 在近期看的一篇有关生成式闲聊的文章中([小布助手闲聊生成式算法](http://mp.weixin.qq.com/s?__biz=MzU1NTMyOTI4Mw==\&mid=2247562192\&idx=1\&sn=0344248652f2c319c4860da300aebdb7\&chksm=fbd641bccca1c8aa19bdd76bed10daa4324d54bf47d8b6bfb556e3e3cd36338d3f0891103ebe\&scene=21#wechat_redirect "小布助手闲聊生成式算法")),生成式和闲聊之间的关系没有想象的那么简单,主要还有下面这些问题: 43 | 44 | - **可控性不足**,对特定的问题或者回复,需要风控。(政治敏感、涉黄涉暴等) 45 | - **常规的闲聊**,回复内容比较直接,对于闲聊这种多轮倾向比较重的回复,很容易把天聊死,所以需要控制。 46 | - **万能回复**,例如“不知道”、“你说呢”这种,需要约束和控制。 47 | - **一致性问题**。换个问法,可能回复就不同,但是对于有些情况是需要一致的,例如“你多少岁了”和“你几岁”。 48 | - **知识缺失**。就是上面说的通顺但不符合逻辑的回复。 49 | 50 | 上面的问题基本都是现有生成式的一些主要问题,上面的部分问题可以通过检索式解决,也有一些可以通过上下游的信息输入来完成条件生成。 51 | 52 | ### 3.1 业界的方法 53 | 54 | ![](image/image_s5_p_VOBPM.png) 55 | 56 | 而重点在于,我们需要集中一些精力,来解决上面的问题。 57 | 58 | ### 3.2 生成式的使用方式 59 | 60 | 针对可控性不足的问题,解决思路如下: 61 | 62 | - 对于敏感问题和回复,一方面从上游的过滤来处理,有些可能有问题的query就不能进入到这一层来,在上游用规则等方式过滤;另一方面,在生成的过程,业务要对该类型的答案进行惩罚,这点在万能回复里也需要做这个工作。 63 | - 容易把天聊死的问题,可以结合主动对话的对话策略,来推动聊天更容易聊下去。 64 | - 一致性问题和知识缺失问题,本质上都是依赖一个统一地知识库,结合这个知识库,能让生成的结果更加受控,这也是我前面聊的结合检索的生成式。 65 | 66 | ## 4.方案的选择与决策 67 | 68 | 方法总有很多,在技术的迭代发展上,无论是生成还是检索,都还有很大的使用空间,肯定是建议大家都去学的,但是在实践过程,总要进行取舍,这个取舍,不仅是实践过程中的方案实施的抉择,还有在线预测阶段的结果筛选排序,都是需要进行决策的。 69 | 70 | ### 4.1 方案选择的思路 71 | 72 | 检索式因为物料本身的可控性,为结果的精准度带来很高的下限,只要query理解和匹配没问题,最终的结果就不会太差,就取决于物料质量了,所以一般情况,尤其是企业级的对话机器人,例如淘宝的客服,其实非常乐意去整检索式,甚至连一些客套话、闲聊场景也会用检索式来处理一些高频的问题,毕竟他是真的稳。但缺点也是在这个库上,低质量的库或者是覆盖率不足的库,体验会很差甚至形同虚设,无论是算法还是运营、数据、工程都要为这个数据库维护花费不少精力,但是一旦建立了起来,绝对起飞。 73 | 74 | 而生成式,其他点就在于泛化性强,库里面没有或者是有但是泛化能力不足的话,生成式是可以轻松解决的,另一方面,生成式本身的句子流畅性高,在用户感知上会更像人,这给用户体验上带来很大的提升,然而缺点在上面提到了,确实很多不稳定的问题,如果要上,很多辅助措施也是要跟着建立起来。 75 | 76 | 所以该怎么选?如果是给我操作,检索式会是更高优的选择,至少黑白名单之类的方案还是需要考虑有的,系统的可控性全靠这个,此时只需要花时间整理,检索式总能提供一个稳定可用的版本,尤其是知识型要求非常重的,例如客服型,咨询的问题大都是固定而且专业的,检索式的优势可以说是能充分发挥了。 77 | 78 | 而在后期,针对长尾的问题,包括闲聊,到了收官时刻,开始处理长尾问题的时候,生成式的需要会逐步明显起来,他的泛化能力能让系统能回复更多更长尾的问题,即使是缓兵之计,“我不太清楚哟,我们来聊聊别的吧,今天晚上打算吃什么”这种回复也会体验好不少,毕竟别说机器人了,每个个体人类都有一定的知识上限,所以真的不奇怪。 79 | 80 | ### 4.2 排序层的结果筛选 81 | 82 | 不把鸡蛋放在一个篮子里,随着系统逐步完善,系统内肯定会有多种结果召回,需要从中找到最优的方案返回,这点其实和搜索很相似,就是一个**多路召回+排序**的过程,然而在对话系统中,却有一些非常具有特色的难点: 83 | 84 | - 大部分对话系统没有点击之类的用户交互数据,顶多是类似客服场景的“满足/不满足”之类的,但这个占比很少。 85 | - 搜索系统多半结果是多条,而且要关注多样性,而对话系统一般只有一个回复,而且要求精准,对于多意图顶多是用“我猜你想问这些问题”这种疑似问的方式来引导,总之最终结合对话策略,只有一条回复。 86 | 87 | 针对第一个问题,其实对话场景,其实很难有类似推荐或者搜索的排序模型来进行筛选,毕竟是真的没数据,而针对第二个问题,则对结果的精准度有了更高的要求,上游的意图识别和下游的排序层压力都会很大,毕竟结果精准性要求很难。 88 | 89 | 针对这两个问题,在多意图多内容召回的这个问题下,对话系统很可能采用基于策略和规则来进行综合排序,一方面考虑多个意图或者之间的关系,例如优先信任检索式甚至是kv查询的结果,另一方面,考虑各个结果的置信度(或者结果内和query的相似度)做一个排序从而进行筛选会更为合理。 90 | 91 | 而如果规则逐渐复杂,系统的维护逐渐存在困难前,可以慢慢往机器学习转,结合各种结果和相似度、匹配度等做一些机器学习的计算,也会有一定效果,当然了,这里用机器学习也是为了避免太过复杂的特征输入,从而降低数据成本,这个方案可供参考。 92 | 93 | ## 5.小结 94 | 95 | 这篇给大家讲了对话系统的结果怎么来的,检索式应该算我比较擅长的东西了,但是后者生成式写的其实挺吃力的,年后才开始慢慢看然后现在只是有个认识,也找过一些做这块的朋友聊过一些经验,所以才总结出来,希望大家看不出来什么破绽吧。 96 | 97 | -------------------------------------------------------------------------------- /docs/dialogue/5.多轮对话.md: -------------------------------------------------------------------------------- 1 | # 5.多轮对话 2 | 3 | ## 1.多轮的核心——对话管理 4 | 5 | 人能够进行多轮对话,很大程度和我们能记住并且使用沟通过程产生的信息和共识,这里值得注意的是,**有两个关键的能力,一个是记住,另一个是使用**。而现有的大量技术也都是围绕着这两点来搭建的,甚至,比较统一的形成了一个“对话管理模块”,即Dialog Management,DM。 6 | 7 | 对话管理承担了多轮对话中信息的记录和使用,所谓的记录,就是对话过程的跟踪,一般被称为"Dialog State Tracking","DST"对话状态跟踪,而所谓的使用,有一个跟有意思的说法,叫做**对话策略**,"Dialog Policy",DP。这点和我们日常的聊天很像,在对话过程中,一方面是能接收双方交换的信息,另一方面也会根据自己的目标或者想法制定不同的对话策略,从而达到自己的目标。 8 | 9 | 当然了,这里的拆解的部分,在现实应用中并不一定是独立拆分开的,可能是组合而成的端到端形式,也可能是拆解分开的形式,这个是根据现实情况来进行选择的。 10 | 11 | - 端到端,从经验上,往往具有很强的泛化能力,在DSTC之类的比赛中,AB榜上端到端的情况似乎会更加稳定,但是缺点是模型内可控性比较差,而且对数据质量和数量的依赖性会比较高。 12 | - 拆分式在设计上会更简单,而且具有较强的可拓展性,拼装起来可控性也比较高,但是泛化能力会比较差。 13 | 14 | ## 2.拆分式的对话管理 15 | 16 | 因为把整个对话管理模块进行了拆解,因此整个对话从信息的梳理存储到对话策略的制定都会很明确,大家看起来也会非常好理解,这里先讲这个。 17 | 18 | 先用最常见的就是任务型对话作为例子,这个例子前面是提到过的: 19 | 20 | > Q:我要订机票。 21 | > A:要订从哪里出发的机票呢? 22 | > Q:从深圳,到北京的。 23 | > A:好的。希望什么时候出发? 24 | > Q:明天上午10点左右吧。 25 | > A:好的,系统给你找到XXX航班,明天10点05分起飞,预计13点到达,请问是否合适? 26 | > Q:可以的。 27 | > A:已经为您预定XXX航班,请点击付款完成最终操作。记得提前办理值机手续哟。 28 | 29 | 这是一段订机票的任务型对话,这段任务型对话其实并不复杂,目标很明确,就是要引导用户把所有信息都填充清楚后,进行订机票的操作,列举下来就这几件事: 30 | 31 | - 开头的意图识别,识别为订机票的意图,进入多轮。 32 | - 拉出需要填写的信息列表,并且引导用户填写这些信息: 33 | - Query理解持续提取用户回复的信息。 34 | - 对话状态记录用户的填表信息。 35 | - 对话策略确认仍然缺少的信息,选择追问策略和完成策略,当然还包括一些打断后的策略。 36 | 37 | 显然,这种方式是非常规则化简单化的,而随着逐渐复杂,对话策略也就会逐步复杂,逐步迭代为一些类似类似用树或者用有限状态自动机来对这些规则进行合理化管理。 38 | 39 | ### 2.1 对话流程中的DST 40 | 41 | DST主要用于对对话过程中的内容就进行管理维护,这是为了下一步对话策略进行分析做基础的,最简单的方式其实就是直接用缓存把对话内容记下来,形成可解释的部分,如下面一个格式,只列举部分字段: 42 | 43 | ```json 44 | { 45 | "destination": "北京", 46 | "originator": "深圳", 47 | "takeoff_time_date": "" 48 | } 49 | ``` 50 | 51 | 而后对话策略根据缺失的信息进行追问即可。 52 | 53 | 而后,随着内容逐渐丰富,场景逐渐复杂,甚至因为轮数增加部分信息也有了更新和变化,这种固定格式的并不一定能够满足我们的需求,于是有了更多的改进措施,也逐步向模型、泛化的方式进行。 54 | 55 | 首先是对话状态的表示,不难看出对话状态数跟意图和槽值对的数成指数关系,因此需要考虑构造合理的模式来实现,例如隐含信息状态、贝叶斯更新等。然后是状态的更新和转移,这种随着任务逐步复杂,是最快进行模型化的,从CRF到RNN,甚至用到迁移学习等,也从单一任务或者槽位的跟踪逐步升级为多任务多目标的跟踪,在DSTC大型赛事中被验证具有很好的效果。此处已经是一个非常完整的体系了,这里列举一些好文章吧: 56 | 57 | - 任务型对话系统中状态追踪(DST):[https://zhuanlan.zhihu.com/p/51476362](https://zhuanlan.zhihu.com/p/51476362 "https://zhuanlan.zhihu.com/p/51476362") 58 | - 一起来看看最新的对话状态追踪(DST)模型:[https://zhuanlan.zhihu.com/p/115019681](https://zhuanlan.zhihu.com/p/115019681 "https://zhuanlan.zhihu.com/p/115019681") 59 | - 多轮对话状态追踪(DST)--模型介绍篇:[https://zhuanlan.zhihu.com/p/40988001](https://zhuanlan.zhihu.com/p/40988001 "https://zhuanlan.zhihu.com/p/40988001") 60 | 61 | ### 2.2 对话流程中的DP 62 | 63 | DP就是对话策略,对话策略是根据现有的query理解和DST,制定对话返回策略的部分,这部分一旦敲定,其实最终的回复也就差不多了,所以重要性也可想而知。 64 | 65 | 常见的对话策略都还比较简单,例如上面的任务型,其实就是比较简单的用一些规则,根据缺失的信息制定回复策略进行追问即可,这里甚至不需要很多复杂的操作,规则即可,但这也就仅限在一些比较简单任务了,对于复杂的任务,进行复杂的策略分析和预测就显得非常必要,DPL(对话策略学习)应运而生。 66 | 67 | 考虑到很多对话策略的文章直接就本着强化学习去聊了,但是我个人其实并不太想直奔那块,而是想把对话策略先当成分类来去聊(虽然我也知道,强化学习某种意义上其实和分类问题很像),即在现有信息下,把策略的选择当成是一个分类问题来去看,有了消息,该采取哪种策略,这点来看他实打实就是一个分类问题,主要原因是,它涉及的信息很多,最重要把他们综合起来,在各种策略中找到一个比较好的,这无疑就是一个分类问题,再升级一下,可能就是一个召回+ TOP1排序的问题: 68 | 69 | - 选择的依据很多,DST信息,现有Query的信息,用户画像,甚至机器人的画像(人设信息),还有一些策略规则等。 70 | - 策略上,先默认现在的机器人没有自己生成新的回复风格的能力,那如无人工添加,就是从现有策略进行选择了。 71 | - 可用的策略并不唯一,例如用户说了个模糊的结果,可以是追问(特殊疑问句,如你说的是啥)、可以是疑似问(猜测你要问啥)、甚至是调侃(没想到你说的我居然没听懂,是不是我没学好)、转移话题(啊,你说的我不懂,要不我们聊聊XX吧)等等,哪个比较好,是需要通过排序之类的思路来进一步筛选出来的。 72 | 73 | 毫无疑问,想到这里,分类问题很合适,甚至适合在这里构造一个完整的分类系统,从模型分类到召回-排序的模式来做,都没有问题。 74 | 75 | 而后,由于本身DP就是一个决策问题,甚至是一个多次决策的问题,因此把问题交给强化学习可能更好,于是强化学习就开始成为DP的重要手段了。说到强化学习,必须提到的就是强化学习本身需要的元素,即状态、动作、奖励,在多轮对话里,状态就可以理解为DST中的信息,动作就是采取的对话策略,奖励就是采取行动会得到的奖励,所希望的就是全局,也就是整次对话下来,奖励最高,多轮对话无疑是符合这个模式的。 76 | 77 | 和DST一样,这里不展开说,有兴趣大家可以自己进行深入阅读,这里放一些我觉得比较好的文章吧: 78 | 79 | - 一文看懂任务型对话中的对话策略学习(DPL):[https://zhuanlan.zhihu.com/p/52692962](https://zhuanlan.zhihu.com/p/52692962 "https://zhuanlan.zhihu.com/p/52692962") 80 | - 深度学习对话系统理论篇--Deep Reinforcement Learning for Dialogue Generation:[https://zhuanlan.zhihu.com/p/31829823](https://zhuanlan.zhihu.com/p/31829823 "https://zhuanlan.zhihu.com/p/31829823") 81 | 82 | ## 3.端到端式的对话管理 83 | 84 | 端到端式的对话管理大部分出现在学术界中,用过特定的模型完成多轮信息的整合和对话策略的决策,甚至从输入开始进行串联,从输入直接到输出完成全局的端到端结果回复。 85 | 86 | ### 3.1 检索式多轮 87 | 88 | 没错,**检索式其实也有多轮,也能做多轮,而且其实研究还不少,其本质就是把历史的对话信息和当前的回复都放到模型的输入中,形成端到端的模式**,不过从社区目前的关注度来看,关注度其实并不太高,列出一些文章供大家参考下: 89 | 90 | - 多轮检索式对话系统小结:[https://zhuanlan.zhihu.com/p/84163773](https://zhuanlan.zhihu.com/p/84163773 "https://zhuanlan.zhihu.com/p/84163773") 91 | - 检索式多轮问答系统模型总结:[https://zhuanlan.zhihu.com/p/46366940](https://zhuanlan.zhihu.com/p/46366940 "https://zhuanlan.zhihu.com/p/46366940") 92 | 93 | ### 3.2 生成式多轮 94 | 95 | 与检索式对应的生成式多轮,生成式的灵活性可想而知。简单的方案其实很早就有了,seq2seq就是最经典的操作,直接将这些对话信息放入模型,这种操作方式和编码器类似,能直接生成一些基本的多轮回复,这种方式虽然简单,但终究算是一个可行的方法。 96 | 97 | 而后,考虑到对话信息的存储和处理,以及对知识的录入,其实慢慢的开始有用大模型、知识图谱的趋势,开始构造出更加顺滑,具有一定知识性的回复结果,GPT、BERT的始祖Transformer做的是机器翻译,而这本质其实还是文本生成,结合对抗生成模型的介入,这种模式为生成式多轮带来了新的发展。 98 | 99 | - SIGIR 2019 |基于BERT的历史答案编码实现多轮会话问答:[https://zhuanlan.zhihu.com/p/68481797](https://zhuanlan.zhihu.com/p/68481797 "https://zhuanlan.zhihu.com/p/68481797") 100 | 101 | ## 4.多轮对话的其他问题和难点 102 | 103 | 除了上面聊的东西,其实很多场景都面临很多复杂多样的问题,这些经常有听说过的,列举一下: 104 | 105 | - **多轮打断和话题转移问题**,在任务型等多轮对话下,打断或者话题转移的识别和后续策略的设计问题。 106 | - **主动对话问题**。从一问一答,回答为目标的对话变成一些带有主动性质,牵引性质的对话回复。 107 | - **对话内容的个性化回复和人设问题**。其实本质都是画像的维护和使用,一方面要说“用户想知道的信息”,并且“符合机器人的人设”,后者小冰应该是做的比较好的,很早就已经构造好人设画像并且体现在对话系统里。 108 | - **对话式推荐系统**。在对话过程挖掘用户兴趣,从而进行商品或者问题的推荐。 109 | - 这里还有一篇文章写的非常好:[https://zhuanlan.zhihu.com/p/439302820](https://zhuanlan.zhihu.com/p/439302820 "https://zhuanlan.zhihu.com/p/439302820") 110 | - **多轮的评测标准**。这点其实至今都在讨论,这个问题其实颇为复杂。 111 | 112 | ## 5.拓展阅读 113 | 114 | 文章写完了,但是总感觉意犹未尽,还有很多细节感觉无法写完,否则这就奔着一本书之类的去了,先到此为止吧。对话系统,和推荐系统、搜索系统一样,都是一些很复杂的系统,而且系统还会受到各种场景问题的外因(客服、智能助手、闲聊等)、系统内运转的内因(多轮信息的存储、知识库的挖掘存储、多意图处理)影响,从而产生了其实并不一致的各种解决方案,目前虽有大体统一的趋势,但是内部结构其实都有对自己面对的问题做了很多权衡,如果要变得更为深入,那就需要自己多实践+多阅读,多看看更多的方案和论文,才能有更好的提升。 115 | 116 | 这里,列举一些比较好的材料供大家参考学习吧: 117 | 118 | - A Survey on Dialogue Systems: Recent Advances and New Frontiers:[https://arxiv.org/abs/1711.01731](https://arxiv.org/abs/1711.01731 "https://arxiv.org/abs/1711.01731") 119 | - 对话系统-Dialogue System:[https://ailearning.ml/2020/04/29/dialogue-system](https://ailearning.ml/2020/04/29/dialogue-system "https://ailearning.ml/2020/04/29/dialogue-system") 120 | - RASA对话系统:[https://github.com/RasaHQ/rasa](https://github.com/RasaHQ/rasa "https://github.com/RasaHQ/rasa") 121 | - 百度的PLATO,自行上网查询。 122 | 123 | 另外大家也可以关注几个大厂的对话系统,技术都相对成熟了,部分会需求和应用的原因,会有些技术领域的限制,主要包括几个语音助手(小布助手、小爱同学、siri、天猫精灵、小度等),几个大厂(美团、平安、阿里小蜜、58等都有不少对话系统的分享)。 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /docs/dialogue/README.md: -------------------------------------------------------------------------------- 1 | # 对话系统 2 | 3 | > 文章摘自: 4 | > \- 作者:叉烧 5 | > \- 链接:[两万字聊对话系统](https://mp.weixin.qq.com/s/ESTVHeKqFk2qnznGSJkK6A "两万字聊对话系统") 6 | 7 | ### 简介 8 | 9 | - 概述:对整个对话系统有一个比较完整的综述 10 | - 技术架构:对话系统是怎么运转和处理 11 | - 内容理解:理解对方说什么,也就是NLU 12 | - 内容输出:回复对方的内容是怎么产生的 13 | 14 | ### 主要内容 15 | 16 | - [1.概述](docs/dialogue/1.概述.md) 17 | - [2.技术架构](docs/dialogue/2.技术架构.md) 18 | - [3.query理解](docs/dialogue/3.query理解.md) 19 | - [4.内容输出](docs/dialogue/4.内容输出.md) 20 | - [5.多轮对话](docs/dialogue/5.多轮对话.md) 21 | 22 | -------------------------------------------------------------------------------- /docs/dialogue/image/image_H-KuJoI867.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dialogue/image/image_H-KuJoI867.png -------------------------------------------------------------------------------- /docs/dialogue/image/image_kW3I3wYCtU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dialogue/image/image_kW3I3wYCtU.png -------------------------------------------------------------------------------- /docs/dialogue/image/image_kjDyaPkpUM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dialogue/image/image_kjDyaPkpUM.png -------------------------------------------------------------------------------- /docs/dialogue/image/image_oVEDRXtSom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dialogue/image/image_oVEDRXtSom.png -------------------------------------------------------------------------------- /docs/dialogue/image/image_s5_p_VOBPM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dialogue/image/image_s5_p_VOBPM.png -------------------------------------------------------------------------------- /docs/dl/1.激活函数.md: -------------------------------------------------------------------------------- 1 | # 1.激活函数 2 | 3 | ### 1.激活函数作用 4 | 5 | 神经网络是线性的,无法解决非线性的问题,加入激活函数就是给模型引入非线性能力; 6 | 7 | 不同的激活函数,特点和作用不同: 8 | 9 | - `Sigmoid`和`tanh`的特点是将输出限制在`(0,1)`和`(-1,1)`之间,说明`Sigmoid`和`tanh`适合做概率值的处理,例如LSTM中的各种门;而`ReLU`就不行,因为`ReLU`无最大值限制,可能会出现很大值。 10 | - `ReLU`适合用于深层网络的训练,而`Sigmoid`和`tanh`则不行,因为它们会出现梯度消失。 11 | 12 | ### 2.梯度爆炸和梯度消失 13 | 14 | 模型中的梯度爆炸和梯度消失问题: 15 | 16 | 1. 激活函数导致的梯度消失,像 `sigmoid `和 `tanh` 都会导致梯度消失; 17 | 2. 矩阵连乘也会导致梯度消失,这个原因导致的梯度消失无法通过更换激活函数来避免。直观的说就是在反向传播时,梯度会连乘,当梯度都小于1.0时,就会出现梯度消失;当梯度都大于1.0时,就会出现梯度爆炸。 18 | 19 | 如何解决梯度爆炸和梯度消失问题: 20 | 21 | 1. 上述第一个问题只需要使用像 ReLU 这种激活函数就可以解决; 22 | 2. 上述第二个问题没有能够完全解决的方法,目前有一些方法可以很大程度上进行缓解该问题,比如:对梯度做截断解决梯度爆炸问题、残差连接、normalize。由于使用了残差连接和 normalize 之后梯度消失和梯度爆炸已经极少出现了,所以目前可以认为该问题已经解决了。 23 | 24 | ### 3.Sigmoid 25 | 26 | Sigmoid函数公式: 27 | 28 | $$ 29 | \sigma(z)=\frac{1}{1+e^{-z}} 30 | $$ 31 | 32 | 导数公式: 33 | 34 | $$ 35 | \sigma^{\prime}(z)=\sigma(z)(1-\sigma(z)) 36 | $$ 37 | 38 | ![](image/image_9ED50ulsDw.png) 39 | 40 | 优点: 41 | 42 | - 平滑,易于求导; 43 | - 取值范围是`(0, 1)`,可直接用于求概率值的问题或者分类问题;比如 LSTM 中的门,二分类或者多标签分类问题; 44 | 45 | 缺点: 46 | 47 | - **计算量大**,包含幂运算,以及除法运算; 48 | - sigmoid 导数的取值范围是 `[0, 0.25]`,最大值都是小于 1 的,反向传播时又是"链式传导",**经过几次相乘之后很容易就会出现梯度消失的问题**; 49 | - **sigmoid 的输出的均值不是0**(即zero-centered),这会导致当前层接收到上一层的非0均值的信号作为输入,随着网络的加深,会改变数据的原始分布; 50 | 51 | ### 4.Tanh 52 | 53 | Tanh的函数公式为: 54 | 55 | $$ 56 | \begin{aligned} \tanh (z) & =\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} \\ & =\frac{2}{1+e^{-2 z}}-1\end{aligned} 57 | $$ 58 | 59 | > 从上述公式的第二行可以看出,tanh 函数可以由 sigmoid 函数经过平移和拉伸得到。tanh 函数的取值范围是`(-1, 1)`。 60 | 61 | 导数公式 62 | 63 | $$ 64 | \tanh (x)^{\prime}=\frac{\left(e^{x}+e^{-x}\right)^{2}-\left(e^{x}-e^{-x}\right)^{2}}{\left(e^{x}+e^{-x}\right)^{2}}=1-(\tanh (x))^{2} 65 | $$ 66 | 67 | ![](image/image_2AtuZrFran.png) 68 | 69 | tanh 函数可以理解为是**基于 sigmoid 函数的一种改进的激活函数**,所以对于 sigmoid 函数的缺点,它能够解决一部分。但是 tanh 函数依然有着不少的缺点。tanh 函数的特点如下: 70 | 71 | - 它的输出范围是`(-1, 1)`,解决了 sigmoid 函数输出的均值不是0(zero-centered)的问题; 72 | - tanh 的导数取值范围是`(0, 1)`,可以看出其在反向传播的"链式传导"过程中的梯度消失问题要比 sigmoid 函数要好一些,但是其依然存在着梯度消失问题; 73 | - **幂运算依然存在,计算量比较大**; 74 | 75 | ### 5.ReLU系列 76 | 77 | #### 5.1 ReLU 78 | 79 | `ReLU `全称为 Rectified Linear Unit,即修正线性单元函数。该函数的公式比较简单,相应的公式和图像如下表所示。 80 | 81 | ![](image/image_2KV3LOKN2S.png) 82 | 83 | 相比于 `sigmoid`、`tanh `这两个激活函数,`ReLU `激活函数的优缺点如下: 84 | 85 | - 当 `z>0` 时,ReLU 激活函数的导数恒为常数1,这就避免了 sigmoid 和 tanh 会在神经网络层数比较深的时候出现的梯度消失的问题; 86 | - 计算复杂度低,不再含有幂运算,只需要一个阈值就能够得到其导数; 87 | - 经过实际实验发现,**使用 ReLU 作为激活函数,模型收敛的速度比 sigmoid 和 tanh 快**; 88 | - 当 `z<0`时,ReLU 激活函数的导数恒为常数0,这既带来了一些有利的方面,也导致了一些坏的方面,分别进行描述。 89 | - 有利的方面:在深度学习中,目标是从大量数据中学习到关键特征,也就是把密集矩阵转化为稀疏矩阵,保留数据的关键信息,去除噪音,这样的模型就有了鲁棒性。ReLU 激活函数中将 `z<0`的部分置为0,就是产生稀疏矩阵的过程。 90 | - 坏的方面:将 `z<0`的部分梯度直接置为0会导致 Dead ReLU Problem(神经元坏死现象)。**可能会导致部分神经元不再对输入数据做响应,无论输入什么数据,该部分神经元的参数都不会被更新**。(这个问题是一个非常严重的问题,后续不少工作都是在解决这个问题) 91 | - ReLU 有可能会导致梯度爆炸问题,解决方法是梯度截断; 92 | - ReLU 的输出不是 0 均值的,这个和 sigmoid 类似。(后续的优化工作 ELU 在该问题上解决的比较好,ELU 的输出是近似为0的) 93 | 94 | #### 5.2 Leaky ReLU 95 | 96 | 为了解决 ReLU 的 Dead ReLU 问题,提出了 渗漏整流线性单元(Leaky ReLU),该方法是 ReLU 的一个变体。其在`z>0`的部分与ReLU一样保持不变;在`z<0`的部分,采用一个非常小的斜率0.01,其公式如下: 97 | 98 | $$ 99 | Leaky \operatorname{ReLU}(z)=\left\{\begin{array}{ll}0.01 z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. 100 | $$ 101 | 102 | 其图像如下所示: 103 | 104 | ![](image/image_zrvZp-9GRb.png) 105 | 106 | 该方法是 ReLU 的一个变体,能够在一定程度上解决 Dead ReLU 问题,但是该方法的缺点是**效果并不稳定**,所以实际实验中使用该方法的并不多。 107 | 108 | #### 5.3 PReLU, RReLU 109 | 110 | PReLU 的全称为 Parametric Relu;PReLU 的全称为 Random ReLU。 111 | 112 | 这两个方法和 Leaky ReLU 类似,都是 ReLU 的变体。也都是为了解决 Dead ReLU 问题而提出来的。 113 | 114 | Leaky ReLU 是在`z<0`时,设置了一个较小的常数0.01作为斜率。由于这种常数值的斜率并不好,所以 PReLU 提出了可学习的斜率,RReLU 提出了随机的斜率,两者具体的公式如下。 115 | 116 | PReLU的公式如下,这里的$\alpha$是可学习的: 117 | 118 | $$ 119 | \operatorname{PReLU}(z)=\left\{\begin{array}{ll}\alpha \cdot z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. 120 | $$ 121 | 122 | RReLU 的公式如下,这里的 $\alpha$是从一个高斯分布中随机产生的,在训练过程中每次这个 $\alpha$ 都是不相同的;在推理时会将这个$\alpha$都是不相同的;在推理时会将这个 123 | 124 | $$ 125 | \operatorname{RReLU}(z)=\left\{\begin{array}{ll}\alpha \cdot z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. 126 | $$ 127 | 128 | PReLU 和 RReLU 的图像如下所示: 129 | 130 | ![](image/image_GlE3RW4neL.png) 131 | 132 | #### 5.4 ELU(指数线性单元) 133 | 134 | ELU 的提出也解决了 ReLU 的问题。与 ReLU 相比,ELU 有负值,这会使激活的平均值接近零,让模型学习得更快。 135 | 136 | ![](image/image_mObw4TwnQV.png) 137 | 138 | $$ 139 | \mathrm{g}(x)=\operatorname{ELU}(x)=\left\{\begin{aligned} x, & x>0 \\ \alpha\left(\mathrm{e}^{x}-1\right), & x \leqslant 0\end{aligned}\right. 140 | $$ 141 | 142 | 其中 $\alpha$不是固定的,是通过反向传播学习出来的。ELU的一个小问题是需要exp计算,运算量会更大一些。 143 | 144 | - 融合了sigmoid和ReLU,左侧具有软饱和性,右侧无饱和性。 145 | - 右侧线性部分使得ELU能够缓解梯度消失,而左侧软饱能够让ELU对输入变化或噪声更鲁棒。 146 | - ELU的输出均值接近于零,所以收敛速度更快。 147 | 148 | ### 6.GeLU 149 | 150 | > 出自2016年的论文《Gaussian Error Linear Units (GELUs)》 151 | 152 | 先描述一下 GELU 这个激活函数直觉上是基于一个什么思路设计出来的。然后再具体看其如何近似求解、如何代码实现。 153 | 154 | #### 6.1 介绍 155 | 156 | 先看一下 ReLU 激活函数是怎样做的,该函数中包含两种映射:一个是恒等映射(identity mapping),当输入值大于零时就是恒等映射;一个是置零映射(zero mapping),当输入值小于等于零时就是置零映射。 157 | 158 | 参考 ReLU 激活函数,设计另外一个包含恒等映射和置零映射的激活函数,并且参考 ReLU 函数来看,新激活函数应该有如下性质: 159 | 160 | 1. 在输入 `x` 满足某些条件时,为恒等映射; 161 | 2. 在输入 `x` 满足另外一些条件时,为置零映射; 162 | 3. 在输入 `x` 是一个较大的正值时,更希望为恒等映射;在输入 `x` 为一个较小的负值时,更希望是一个置零映射; 163 | 164 | 以上就是想要新设计的激活函数的性质。 165 | 166 | 下面的图7和图8是标准正态分布的概率密度函数和累积分布函数的图像。接下来根据下图8中的累积分布函数设计一个新的函数。 167 | 168 | 符号定义:输入值用 $x$ 表示,$ϕ(⋅)$表示下图8中的正态分布的累积分布函数,$f(⋅)$表示新设计的函数。 169 | 170 | 设计的新函数:给定输入值 $x$,函数 $f(x)$的输出值以 $ϕ(x)$的概率采用恒等映射,以 $1−ϕ(x)$的概率采用置零映射。也就是下述公式: 171 | 172 | $$ 173 | \begin{aligned} f(x) & =x \cdot \phi(x)+0 \cdot(1-\phi(x)) \\ & =x \cdot \phi(x)\end{aligned} 174 | $$ 175 | 176 | 然后看一下,新设计的这个公式是否满足上述的激活函数性质。前两条是肯定满足的,主要看一下第3条性质: 177 | 178 | - 当输入 $x$ 是一个较大的正值时,从图8中可以看出 $ϕ(x)$的函数图像逐渐趋近于1,由于函数 $f(x)$的输出值以 $ϕ(x)$的概率采用恒等映射,所以有接近于1的概率采用恒等映射; 179 | - 当输入 $x$ 是一个较小的负值时,$ϕ(x)$趋近于0,由于函数 $f(x)$以 $1−ϕ(x)$的概率采用置零映射,所以有接近于1的概率采用置零映射; 180 | 181 | 可以看出新设计的这个函数是满足上述激活函数的性质的。 182 | 183 | 为了更直观描述设计该函数时的直觉,上述都是采用图8进行描述的,上述公式如果使用图7中的概率密度函数就是如下形式: 184 | 185 | $$ 186 | \begin{aligned} f(x) & =x \cdot p(X 这里描述的设计 GELU 函数的直觉思路是非常简化的版本,只是为了易于理解。实际在设计这个函数时还需要考虑更多的因素,比如该函数的那几条性质和 ReLU 很像,已经有了 ReLU 为什么还要设计这个函数,这个函数在理论上是否能够解决 ReLU 的存在的 Dead ReLU 等问题; 198 | 199 | #### 6.2 函数及导数 200 | 201 | GeLU 公式为: 202 | 203 | $$ 204 | G E L U=x \cdot \phi(x) 205 | $$ 206 | 207 | 使用该函数作为激活函数时,需要求解其导数。对其求导可得: 208 | 209 | $$ 210 | \begin{aligned} \frac{d}{d x} G E L U & =\phi(x)+x \frac{d}{d x} \phi(x) \\ & =\phi(x)+x \cdot p(X=x)\end{aligned} 211 | $$ 212 | 213 | 其中$X$是随机变量,$p(X=x)$是图7中的标准正态分布概率密度函数中,随机变量取值为$x$时的值。 214 | 215 | GELU 函数及其导数的图像如下所示。可以看出其函数图像和 ReLU 非常相似,其导数图像也和 ReLU 的导数图像非常相似,不过该图像是连续的。 216 | 217 | ![](image/image_AHzmMqgKgV.png) 218 | 219 | GELU 激活函数的优缺点: 220 | 221 | - 从其函数图像可以看出,在负值区域,不再全为0,这解决了 Dead ReLU 问题; 222 | - GELU 函数是处处连续、光滑可导的; 223 | 224 | #### 6.3 精确计算 225 | 226 | 对于 GeLU 的加速计算有两种方法。 227 | 228 | 第一种方法是精确求解。有一个函数为 Gauss Error function (gef),由于使用率非常高所以在常见的库(比如TensorFlow、PyTorch)中都有针对该函数的优化,该函数的公式如下。 229 | 230 | $$ 231 | \operatorname{erf}(y)=\frac{2}{\sqrt{\pi}} \int_{0}^{y} e^{-t^{2}} d t 232 | $$ 233 | 234 | 所以如果能够先求解出$erf(\cdot)$,再由该函数求解出 $\phi(x)$,那么可以加快计算。下面省略具体的推导过程,直接给出计算公式: 235 | 236 | $$ 237 | \phi(x)=\frac{1+\operatorname{erf}\left(\frac{x}{\sqrt{2}}\right)}{2} 238 | $$ 239 | 240 | 另一种方法是不精确求解,而是求解其近似值。为了加速计算,还可以使用近似计算的方式。GELU 的近似公式如下所示: 241 | 242 | $$ 243 | G E L U=0.5 * x\left(1+\tanh \left[\sqrt{\frac{2}{\pi}}\left(x+0.044715 x^{3}\right)\right]\right) 244 | $$ 245 | 246 | ### 7.Swish 247 | 248 | > 出自2017年的论文《Searching for Activation Functions》 249 | 250 | 该激活函数的公式为: 251 | 252 | $$ 253 | f(x)=x \cdot \sigma(x) 254 | $$ 255 | 256 | Swish导数: 257 | 258 | $$ 259 | \begin{array}{l}f^{\prime}(x) \\ =\sigma(x)+x \cdot \sigma(x) \cdot(1-\sigma(x)) \\ =x \cdot \sigma(x)+\sigma(x)(1-x \cdot \sigma(x)) \\ =f(x)+\sigma(x) \cdot(1-f(x))\end{array} 260 | $$ 261 | 262 | 该激活函数的图像为: 263 | 264 | ![](image/image_vZZ0x7ThiD.png) 265 | 266 | Swish特点: 267 | 268 | - 和ReLU一样,没有上边界,因此不会出现梯度饱和现象 269 | - 有下边界,可以产生更强的正则化效果(x左半轴慢慢趋近于0) 270 | - 非单调 271 | - 处处连续且可到,更容易训练 272 | 273 | 关于正则化效果:x轴越靠近左半轴,纵坐标的值越小,甚至接近于0,如果x值是-10,那么经过激活之后的值接近于0,那么就可以一定程度上过滤掉一部分信息,起到[正则化](https://so.csdn.net/so/search?q=正则化\&spm=1001.2101.3001.7020 "正则化")的效果。 274 | 275 | ### 8.GLU 276 | 277 | PaLM 和 LLaMA 中都使用 SwiGLU 替换了 FFN 278 | 279 | > 出自2017年的论文 [Language Modeling with Gated Convolutional Networks](https://arxiv.org/pdf/1612.08083.pdf "Language Modeling with Gated Convolutional Networks") 280 | 281 | GLU 全称为 Gated Linear Unit,即**门控线性单元函数**。 282 | 283 | 参考ReLU激活函数,激活函数GLU的公式为如下公式的形式 284 | 285 | $$ 286 | \operatorname{GLU}(x)=x \otimes \sigma(g(x)) 287 | $$ 288 | 289 | 这里有一个新符号 $g(x)$表示的是向量$x$经过一层MLP或者卷积,$⊗$表示两个向量逐元素相乘,$σ$ 表示sigmoid函数。 290 | 291 | 当$\sigma(g(x))$趋近于0时表示对$x$进行阻断,当$\sigma(g(x))$趋近于1时表示允许$x$通过,以此实现门控激活函数的效果。 292 | -------------------------------------------------------------------------------- /docs/dl/2.KL散度.md: -------------------------------------------------------------------------------- 1 | # 2.KL散度 2 | 3 | > 文章来源:[Index - 笔记 (mingchao.wang)](https://mingchao.wang/0ISjGzGG/ "Index - 笔记 (mingchao.wang)") 4 | 5 | ### 1.KL散度的定义 6 | 7 | KL散度是一种**衡量两个概率分布 P 和 Q 的差异**的方法; 8 | 9 | 对于连续随机变量的概率分布来说,KL散度公式为:$D_{K L}(p \| q)=\int_{x} p(x) \log \frac{p(x)}{q(x)} d x$ 10 | 11 | 对于离散随机变量的概率分布来说,KL散度公式为:$D_{K L}(p \| q)=\sum_{x} p(x) \log \frac{p(x)}{q(x)}$ 12 | 13 | 机器学习和深度学习中使用的都是离散随机变量的概率分布,下面将仅讨论离散情况下的KL散度。 14 | 15 | ### 2.在机器学习中KL散度的作用 16 | 17 | 机器学习的目标就是:希望模型学到的分布 $p_{model}$ 与该任务的真实分布 $P_{real}$ 一致。 18 | 19 | 问题在于该任务的真实分布 $P_{real}$是无法获取到的,能够获取到的是训练集的分布 $P_{train}$,我们一般认为训练数据是从总体中独立同分布采样出来的,基于该条件下,就可以认为训练集的分布 $P_{train}$ 与真实分布 $P_{real}$ 是一致的。这样机器学习的目标就是:希望模型学到的分布 $P_{model}$ 与训练集的分布$P_{train}$ 一致。 20 | 21 | 然后剩余的问题就是如何评估两个分布是否一致?答案是使用KL散度进行评估。因为KL散度的定义就是衡量两个概率分布 p 和 q 的差异。 22 | 23 | **两个分布越相近,KL散度越小;两个分布的差异越大,KL散度也越大**;当两个分布相同时,KL散度为0。 24 | 25 | ### 3.熵、KL散度、交叉熵 26 | 27 | 先对这三个概念给出一个通俗但不严谨的描述: 28 | 29 | - **熵**:可以表示一个事件 A 的自信息量,即 A 包含多少信息; 30 | - **KL散度**:可以表示从事件 A 的角度看,事件 B 有多大的不同; 31 | - **交叉熵**:可以表示从事件 A 的角度看,如何描述事件 B; 32 | 33 | 下面使用数据公示给出这三个概念的严谨的表示: 34 | 35 | **熵:** $H(p)=-\sum_{i} p_{i} \log p_{i}$ 36 | 37 | **KL散度:** $D_{K L}(p \| q)=\sum_{i} p_{i} \log \frac{p_{i}}{q_{i}}=\sum_{i} p_{i} \log p_{i}-\sum_{i} p_{i} \log q_{i}$ 38 | 39 | **交叉熵:** $H(p \| q)=-\sum_{i} p_{i} \log q_{i}$ 40 | 41 | > 注意熵和交叉熵公式中都带有一个负号,而KL散度的公式中并没有负号; 42 | 43 | 分析一下上面的KL散度的公式,左侧项 $\sum_{i} p_{i} \log p_{i}$ 很像是熵的公式,即 $−H(p)$;右侧项 $-\sum_{i} p_{i} \log q_{i}$ 就是交叉熵的公式,即 $H(p||q)$;所以会推导出如下公式: 44 | 45 | $$ 46 | D_{K L}(p \| q)=H(p \| q)-H(p) 47 | $$ 48 | 49 | 即从公式上来说:**KL散度等于交叉熵减熵。** 50 | 51 | ### 4.机器学习中为什么多用交叉熵而不是KL散度 52 | 53 | 在第二部分的描述中已经很清晰的提到:机器学习就是将模型分布 $P_{model}$ 学到与训练集分布 $P_{train}$ 一致的过程。而衡量两个分布是否一致最直接的评估方式就是KL散度,那么为什么机器学习中常用交叉熵而不是KL散度? 54 | 55 | 在第三部分的最后推导出了一个公式,再次记录如下: 56 | 57 | $$ 58 | \begin{aligned} D_{K L}(p \| q) & =\sum_{i} p_{i} \log \frac{p_{i}}{q_{i}} \\ & =\left[-\sum_{i} p_{i} \log q_{i}\right]-\left[-\sum_{i} p_{i} \log p_{i}\right] \\ & =H(p \| q)-H(p)\end{aligned} 59 | $$ 60 | 61 | 将上述公式放到机器学习这个具体应用场景中,公式中的概率分布 `q` 就是需要学习才能得到的模型分布 $P_{model}$,公式中的概率分布 `p` 就是训练集分布 $P_{train}$。 62 | 63 | 我们知道在机器学习中,**训练集是固定的,所以训练集的熵 **$H(p)$** 也是固定的,不随着模型的优化过程而变化**。即在机器学习这个应用场景下 $H(p)$ 是常数。此时使用 $D_{KL}(p||q)$ 对模型优化与使用 $H(p||q)$ 对模型优化是等价的。由于使用交叉熵 $H(p||q)$ 时还能少计算一项,节省计算资源,所以机器学习中一般较多情况使用交叉熵。 64 | 65 | ### 5.KL散度的性质 66 | 67 | 最后记录一下KL散度的两个数学性质: 68 | 69 | - **正定性**:$D_{K L}(p \| q) \geqslant 0$ 70 | - **不对称性**:$D_{K L}(p \| q)!=D_{K L}(q \| p)$ 71 | 72 | 由于KL散度不具有**对称性**,所以KL散度不是一种距离(度量)。 73 | 74 | > 一般来说距离(度量)要满足3个条件:正定性、对称性、三角不等式; 75 | 76 | ### 6.一个额外的知识点 77 | 78 | > 这个是李宏毅在讲RL的课程中提到的。 79 | 80 | 深度学习模型中,如果需要做正则化,常用的方法是 L1、L2,如果是衡量两个分布是否相似,常用的方法是 KL 散度。比如在半监督方法 [UDA](https://arxiv.org/abs/1904.12848 "UDA") 里面,使用 KL 散度来进行一致性训练。然后就有一个问题是说:能不能使用L1、L2来衡量两个模型的分布是否相同?将 L1、L2 放到loss中,与将 KL 散度放到loss中,在学习时的区别是什么? 81 | 82 | 解答:对于一个模型 $f_θ$,将 L1、L2 放到loss中,其起到的作用主要是衡量模型的参数本身。比如\*\* L1 会让模型中出现更多的0,L2 会让模型参数的方差尽量的小\*\*。 83 | 84 | 而**将 KL 散度放到loss中,其主要是衡量模型输出结果的分布,即模型的表现**。使用 KL 散度可以让两个模型的输出结果非常相似,但是 KL 散度不关心这两个模型内部参数是否相似,有可能这两个模型的内部参数差异是非常大的,但是它们的输出结果是非常相似的。使用 L1、L2 做约束,可以使得两个模型内部的参数有一定的相似性,但是 L1 和 L2 完全不关心两个模型的输出是否是相似的。 85 | -------------------------------------------------------------------------------- /docs/dl/3.正则化.md: -------------------------------------------------------------------------------- 1 | # 3.正则化 2 | 3 | > 文章来源:[Index - 笔记 (mingchao.wang)](https://mingchao.wang/Mt7oEh5j/ "Index - 笔记 (mingchao.wang)") 4 | 5 | 1. 正则化常用于缓解模型过拟合。过拟合发生的原因是模型的容量过大,而正则化可以对模型施加某些限制,从而降低模型的有效容量。 6 | 2. 目前有多种正则化策略。 7 | - 有些正则化策略是向模型添加额外的约束,如增加对参数的限制。这是对参数的硬约束。 8 | - 有些正则化策略是向目标函数增加额外项。这是对参数的软约束。 9 | 3. 正则化策略代表了某种先验知识,即:倾向于选择简单的模型。 10 | 4. 在深度学习中,大多数正则化策略都是基于对参数进行正则化。正则化以偏差的增加来换取方差的减少,而一个有效的正则化能显著降低方差,并且不会过度增加偏差。 11 | 5. 在深度学习的实际应用中,不要因为害怕过拟合而采用一个小模型,推荐采用一个大模型并使用正则化。 12 | 13 | ## 1.参数约束正则化:L1和L2正则化 14 | 15 | 参数约束正则化主要是指 L1 和 L2 正则化; 16 | 17 | - **L1正则化**:给每个权重减去一个与$sign(\theta_i)$ 同符号的常数因子; 18 | - **L2正则化**(权重衰减):给每个权重值乘上一个常数因子,线性的缩放每个权重值; 19 | 20 | ### 1.1 L2正则化 21 | 22 | 正则化项为 $\Omega(\theta)=\frac{1}{2}\|\theta\|_{2}^{2}$,系数 1/2 是为了求导时得到得系数为1;$L_2$\*\*正则化能够使参数 \*\*$\theta$**的方差更接近与0**; 23 | 24 | 目标函数:$J(\theta)=L(\theta)+\lambda \Omega(\theta)=L(\theta)+\frac{1}{2} \lambda\|\theta\|_{2}^{2}$ 25 | 26 | 梯度:$\nabla_{\theta} J(\theta)=\nabla_{\theta} L(\theta)+\lambda \theta$ 27 | 28 | 梯度下降过程,其中$\gamma$为学习率:$\theta \leftarrow \theta-\gamma\left(\nabla_{\theta} L(\theta)+\lambda \theta\right)$ 29 | 30 | 整理得:$\theta \leftarrow(1-\gamma \lambda) \theta-\gamma \nabla_{\theta} L(\theta)$ 31 | 32 | L2正则化对梯度更新的影响是:每一步执行更新前,会对权重向量乘以一个常数因子来收缩权重向量,使参数$\theta$的方差更接近0,因此L2也被称为权重衰减。 33 | 34 | ### 1.2 L1正则化 35 | 36 | 正则化项为 $\Omega(\theta)=\|\theta\|_{1}=\sum_{i=1}^{d}\left|\theta_{i}\right|$,即各个参数的绝对值之和; 37 | 38 | 目标函数:$J(\theta)=L(\theta)+\Omega(\theta)=L(\theta)+\lambda\|\theta\|_{1}$ 39 | 40 | 梯度:$\nabla_{\theta} J(\theta)=\nabla_{\theta} L(\theta)+\lambda \cdot \operatorname{sign}(\theta)$ 41 | 42 | 其中 $sign(\cdot)$ 表示取自变量的符号 43 | 44 | 梯度下降过程,其中$\gamma$为学习率:$\theta \leftarrow \theta-\gamma \cdot\left(\nabla_{\theta} L(\theta)+\lambda \cdot \operatorname{sign}(\theta)\right)$ 45 | 46 | 整理得:$\theta \leftarrow(\theta-\gamma \cdot \lambda \cdot \operatorname{sign}(\theta))-\gamma \cdot \nabla_{\theta} L(\theta)$ 47 | 48 | > 特别说明:对于带有$L_1$正则的目标函数,由于其不是处处可导,所以一般不使用梯度下降法进行求解,这里只是和$ L_2$正则做一个类似的讨论。在本文的最后一部分会介绍坐标轴下降法,是更常用的用于求解带有$L_1$正则的目标函数的方法; 49 | 50 | ## 2.Dropout 51 | 52 | 1. **dropout**:在前向传播过程中,对网络中的每个隐藏层,每个隐单元都以一定的概率 $p_{drop}$ 被删除,之后得到一个比原始网络要小的裁剪网络。**在反向传播过程中,仅仅对该裁剪网络进行梯度更新,被删除的隐单元不进行梯度更新**; 53 | 2. **对隐单元的删除指的是**:将该隐单元的输出置为0;当其输出为0时,该隐单元对后续神经元的影响均为0; 54 | 3. **输入层和输出层的神经元不会被删除**,这两层的神经元的个数是固定的; 55 | 4. 关于隐单元删除时的一些细节: 56 | - 不同的样本,其删除的隐单元的集合是不同的,因此得到的裁剪网络也是不同的; 57 | - 不同的样本,每个隐单元被删除的概率是相同的; 58 | - 同一条样本,分两次进入模型训练,那么这两次删除的隐单元也是不同的; 59 | - 在每个梯度更新周期中,被删除的隐单元的集合是不同的,因此得到的裁剪网络也是不同的; 60 | - 在每个梯度更新周期中,隐单元被删除的概率是相同的; 61 | 5. **dropout仅仅用于神经网络的训练阶段,在推理阶段不需要删除隐单元,而是使用所有的神经元**; 62 | 6. dropout的优点: 63 | - 其不限神经网络的网络结构,都可以使用该技术; 64 | - 其计算非常方便、高效;具体计算过程为:每次产生 n 个随机的二进制数(0和1),然后将这些产生的随机二进制数与 n 个隐单元的输出相乘(与0相乘的隐单元就相当于是被删除了);这个计算开销相比于神经网络的正常计算是非常小的; 65 | 7. dropout的缺点: 66 | - **损失函数 Loss 不再被明确的定义,每次迭代都会随机删除一部分隐单元**; 67 | 8. dropout使用时的策略:由于dropout的作用是防止过拟合,所以 68 | - 若某一隐层神经元比较少,过拟合不严重,可以调小概率 $p_{drop}$,甚至该层不使用 dropout; 69 | - 若某一隐层神经元比较多,过拟合严重,可以调大概率 $p_{drop}$; 70 | 9. dropout在使用时更多的可能性(也可称作推广): 71 | - 可以对某一层或某几层使用dropout,其他层不使用dropout; 72 | - 可以对不同的层,甚至不同的隐单元分别设置不同的概率 $p_{drop}$,但实际中一般不这么做; 73 | - 可以对每个梯度更新周期设置不同的概率 $p_{drop}$,但实际中一般不这么做; 74 | - 现在对每个隐单元的输出乘的是个二值函数(0或1),不一定必须是二值函数,也可以扩展为乘以其他值,比如:对 n 个隐单元,每个隐单元乘上的值是根据均值为0,方差为1的标准正态分布生成的值。此时单从形式上来看和 L1、L2 正则已经非常相似了;不过实际中一般也很少采用这种方式; 75 | 76 | ## 3.数据增强(EDA) 77 | 78 | ### 3.1 词汇增强: 79 | 80 | - **基于词典进行替换**:从文本中随机选取一个或多个词语,利用同义词词典将这一个或多个词语替换成其同义词; 81 | - **基于词向量进行替换**:从文本中随机选取一个或多个词语,使用预先训练好的词向量,找到在嵌入空间中与这一个或多个词距离最近的词语,进行替换; 82 | - **基于MLM进行替换**:BERT系列模型是通过MLM进行预训练的,所以可以随机将文本中的某一个或者多个词语mask,使用预训练好的BERT系列模型对mask掉的词语进行生成,以此做增强; 83 | - **基于tf-idf进行替换**:文本中tf-idf较小的词语,对该文本的贡献较小。可以优先对这些词语进行增强,以避免模型错误的将这些词语作为具体任务的主要判断依据; 84 | - **随机插入词语**:向文本的任意位置以一定的概率随机插入词语; 85 | - **随机删除词语**:对文本中任意词语以一定的概率随机进行删除; 86 | - **随机替换词语**:将文本中任意的某一个或多个词语,随机的替换为另外的随机词语; 87 | 88 | ### 3.2 回译增强: 89 | 90 | 利用机器翻译模型,或百度翻译、谷歌翻译等,将中文文本翻译为其他语种的文本,然后再翻译回中文文本,以此进行增强; 91 | 92 | ### 3.3 基于语法解析增强 93 | 94 | 首先使用语法解析工具解析并生成原始文本的依存关系树,之后按照依存关系对其调整,生成增强后的文本。比如:将文本从一个主动语态调整为被动语态; 95 | 96 | ### 3.4 直接在输入层注入随机噪声; 97 | 98 | ## 4.早停(early stopping) 99 | 100 | 在训练时,一般来说是训练集的损失一直下降,而验证集的损失是先下降后上升的。验证集的损失之所以上升就是因为模型已经在训练集上过拟合了。 101 | 102 | 选取验证集损失最小的模型,而不是最新的模型,这种策略就是早停。 103 | 104 | ## 5.对抗训练 105 | 106 | 详情见 [http://mingchao.wang/Kw0SoUUq/](http://mingchao.wang/Kw0SoUUq/ "http://mingchao.wang/Kw0SoUUq/") 107 | 108 | ## Reference[#](#reference "#") 109 | 110 | - [https://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/3\_regularization.html](https://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/3_regularization.html "https://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/3_regularization.html") 111 | -------------------------------------------------------------------------------- /docs/dl/4.损失函数.md: -------------------------------------------------------------------------------- 1 | # 4.损失函数 2 | 3 | 损失函数(Loss Function)用于评估模型**的预测值与实际值之间的差异程度**。在训练过程中,损失函数作为优化的目标,通过**最小化损失函数的值**来调整模型参数,从而提高模型的预测准确性。 4 | 5 | 具体来说,损失函数将模型的预测输出(例如,一个分类任务中的类别概率分布)与真实标签(或真实值)进行比较,并计算出一个表示差异的数值。这个数值越大,表示模型的预测越不准确;数值越小,表示模型的预测越接近真实情况。 6 | 7 | 接下来,介绍几个常用的损失函数。 8 | 9 | - **L1 Loss损失函数**:通常用于**回归任务**中。 10 | - **NLL Loss损失函数**:在**多分类问题**中广泛应用。 11 | - **MSE Loss损失函数**:在**多种回归任务**中表现出色。 12 | - **BCE Loss损失函数**:广泛应用于各类**二分类任务中**。 13 | - **CrossEntropyLoss交叉熵损失函数**:广泛应用于**多分类问题**中。 14 | 15 | ## 1.L1 Loss损失函数 16 | 17 | L1 Loss损失函数,也被称为**平均绝对误差(Mean Absolute Error, MAE)**,是深度学习和机器学习中常用的一种损失函数,特别是在**回归任务**中。 18 | 19 | ### 1.1 定义 20 | 21 | L1Loss计算的是模型预测值f(x)与真实值y之间差的绝对值的平均值。其数学表达式为: 22 | 23 | $$ 24 | text_L1Loss =\frac{1}{n} \sum_{i=1}^{n}\left|y_{i}-f\left(x_{i}\right)\right| 25 | $$ 26 | 27 | 其中,`n`是样本数量,$y_i$是第`i`个样本的真实值,$f(xi)$是模型对第`i`个样本的预测值。 28 | 29 | ### 1.2 优缺点 30 | 31 | **优点** 32 | 33 | 1. **稳定性**:L1Loss对于所有输入值都有稳定的梯度,不会导致梯度爆炸问题,因此具有较为稳健的解。 34 | 2. **鲁棒性**:L1Loss对于噪声和异常值(离群点)具有相对较强的鲁棒性,因为它不会因个别异常值而产生过大的误差。 35 | 3. **稀疏性**:L1Loss能够产生稀疏的特征权重,即很多无用或影响较小的特征的权重会被置为0,有助于特征选择和模型简化。 36 | 37 | **缺点** 38 | 39 | 1. **不可导性**:在0点处,L1Loss的梯度不存在(因为绝对值函数在0点不可导),这可能导致在优化过程中,当权重恰好接近0时,梯度下降法无法继续进行。 40 | 2. **收敛速度**:与L2Loss相比,L1Loss在误差较大时,其梯度是恒定的,这可能导致在接近最优解时收敛速度较慢。 41 | 42 | ### 1.3 应用 43 | 44 | 1. L1Loss通常用于**回归任务**中,特别是当模型需要处理的数据集存在较多噪声或异常值。 45 | 2. 或者希望模型**具有稀疏特征**时。 46 | 47 | 然而,由于神经网络通常解决的是复杂问题,且L1 Loss在0点不可导的缺点,它在神经网络中的应用相对较少,尤其是在需要精细调整权重的情况下。 48 | 49 | ## 2.NLL Loss损失函数 50 | 51 | NLLLoss损失函数,全称为Negative Log Likelihood Loss(**负对数似然损失**),是深度学习中常用的一种损失函数,尤其在处理**多分类问题**时表现出色。 52 | 53 | #### 2.1 定义与原理 54 | 55 | NLLLoss衡量的是模型**预测概率分布**与真实标签之间**差异的损失**。在PyTorch等深度学习框架中,它通常用于**多分类任务**。具体来说,NLL Loss计算的是对数概率的负值与真实标签之间的**交叉熵损失**。这样做的目的是通过最小化损失来优化模型参数,使得模型的预测结果更加接近真实标签。 56 | 57 | #### 2.2 优点与注意 58 | 59 | NLLLoss损失函数的优点在于它能够**直接反映模型预测的概率分布与真实标签之间的差异**,且计算过程相对简单高效。然而,在使用时需要**注意**以下几点: 60 | 61 | 1. **输入要求**:NLLLoss要求输入的对数概率必须是通过**log\_softmax函数计算**得到的,而不能直接使用softmax函数的输出。 62 | 2. **目标标签**:目标**标签需要是整数类型**,表示每个样本的真实类别索引。 63 | 3. **权重调整**:如果需要对不同类别的损失进行权重调整,可以在NLL Loss函数中设置相应的权重参数。 64 | 4. **数值稳定性**:由于NLLLoss涉及对数运算,因此需要注意数值稳定性问题。通过先**应用log\_softmax函数可以避免直接计算softmax时可能出现的上溢或下溢问题**。 65 | 66 | #### 2.3 应用 67 | 68 | NLLLoss损失函数在**多分类问题**中广泛应用,包括但不限于自然语言处理(NLP)中的语言模型、情感分类等任务。在这些任务中,模型需要将输入序列映射到输出标签,而NLLLoss能够评估模型预测的概率分布与真实标签之间的差异,从而指导模型的优化方向。 69 | 70 | ## 3.MSE Loss损失函数 71 | 72 | MSELoss损失函数,全称为Mean Squared Error Loss(**均方误差损失函数**),是深度学习中常用的一种**回归损失函数**。 73 | 74 | #### 3.1 定义与原理 75 | 76 | MSELoss通过计算预测值与真实值之间**差的平方的平均值**来衡量模型的性能。具体来说,对于每个样本,它**计算预测值与真实值之差的平方,然后对所有样本的平方误差求和并取平均,得到最终的损失值**。这种损失函数旨在通过最小化预测值与真实值之间的差异来优化模型参数,从而提高模型的预测准确性。 77 | 78 | 对于单个样本,假设预测值为 $\hat y$,真实值为 $y$,则该样本的均方误差为$(\hat y - y)^2$。对于包含 `n` 个样本的数据集,MSELoss的计算公式为: 79 | 80 | $$ 81 | textMSELoss =\frac{1}{n} \sum_{i=1}^{n}\left(\hat{y}_{i}-y_{i}\right)^{2} 82 | $$ 83 | 84 | #### 3.2 优点与注意 85 | 86 | **优点**: 87 | 88 | 1. **优化直观**:MSE结果是一个平滑且凸的优化直观,这有助于使用基于梯度的算法(如梯度下降)进行高效优化。 89 | 2. **唯一极小值**:MSE具有唯一的全局极小值,这简化了优化过程,并在某些情况下可以获得解析解。 90 | 3. **可微性**:MSE在任何地方都是可微的,这使得在训练过程中可以使用基于梯度的优化方法。 91 | 4. **广泛适用性**:MSE是回归问题的标准且广泛使用的损失函数,适用于预测连续的数值。 92 | 93 | **注意**: 94 | 95 | 1. **对异常值敏感**:由于MSE计算的是误差的平方,因此它**对异常值非常敏感**。当数据集中存在极端值时,这些异常值可能会对损失值产生不成比例的影响,从而导致模型性能下降。 96 | 2. **非直观的尺度**:MSE的尺度受到平方差的影响,这可能导致其解释性较差。特别是在与原始数据的尺度相比时,MSE可能难以直观地反映模型预测的准确性。 97 | 98 | #### 3.3 应用 99 | 100 | MSELoss在**多种回归任务**中表现出色,包括但不限于房价预测、股票价格预测、气温预测等。在这些任务中,模型需要输出一个**连续的数值预测结果**,而MSELoss能够有效地评估模型预测结果与实际值之间的差异,并指导模型的优化方向。 101 | 102 | ## 4.BCE Loss损失函数 103 | 104 | BCELoss损失函数,全称为Binary Cross Entropy Loss(二元交叉熵损失函数),是深度学习中常用于二分类问题的一种损失函数。 105 | 106 | #### 4.1 定义与原理 107 | 108 | BCELoss通过**计算模型预测的概率分布与实际标签之间的****交叉熵****损失来评估模型的性能**。在**二分类问题**中,每个样本的真实标签是0或1,而模型输出的是一个介于0和1之间的概率值,表示该样本属于正类的概率。BCELoss通过比较这两个值之间的差异,为模型提供一个损失值,该值越大表示模型预测越不准确。 109 | 110 | 对于单个样本,BCELoss的数学公式为: 111 | 112 | $$ 113 | textBCELoss =-(y \log (p)+(1-y) \log (1-p)) 114 | $$ 115 | 116 | 其中,`y `是实际标签(0 或 1),`p` 是模型输出的概率值(预测为正类的概率),log 是自然对数。 117 | 118 | - 当 `y=1` 时,损失函数简化为 $−log($$p$$)$,此时如果 *`p`* 越接近 1,则损失越小; 119 | - 当 `y=0` 时,损失函数简化为$ −log(1−p)$,此时如果 *`p`* 越接近 0,则损失越小。 120 | 121 | 对于一批样本,BCELoss通常是对所有样本的BCELoss求和后取平均值。 122 | 123 | #### 4.2 优点与注意 124 | 125 | **优点**: 126 | 127 | 1. **直观性**:BCELoss能够**直观地反映**模型预测的概率分布与实际标签之间的差异,从而指导模型的优化方向。 128 | 2. **鲁棒性**:在二分类问题中,BCELoss对正负样本的预测误差都进行了考虑,使得模型在训练过程中能够同时**关注到正负样本的分类**情况。 129 | 3. **易于实现**:在深度学习框架(如PyTorch、TensorFlow等)中,BCELoss通常作为内置函数提供,易于实现和使用。 130 | 131 | **注意**: 132 | 133 | 1. **输入要求**:在使用BCELoss时,需要注意模型输出的概率值应该经过Sigmoid函数或其他适当的**激活函数处理**,以确保其值在0和1之间。 134 | 2. **标签要求**:BCELoss要求真实标签**必须是二值化的**(0或1),而不是其他形式的标签(如类别索引、独热编码等)。 135 | 3. **数值稳定性**:在计算BCELoss时,需要注意数值稳定性问题。例如,当预测概率 *`p`* 非常接近0或1时,$log($$p$$)$ 或 $log(1−p) $的值可能会变得非常大或非常小,导致计算过程中出现数值问题。为了避免这种情况,可以对 *`p`* 进行一些**平滑处理**(如添加一个小的正数 *`ϵ`* 到 *`p`* 和 `1−p` 中)。 136 | 137 | #### 4.3 应用 138 | 139 | BCELoss广泛应用于各类**二分类任务中**,如文本情感分析(积极/消极)、垃圾邮件检测(垃圾邮件/非垃圾邮件)、病患诊断(患病/未患病)等。在这些任务中,模型需要输出一个二分类的概率预测结果,而BCELoss能够有效地评估模型预测的准确性,并指导模型的优化方向。 140 | 141 | ## 5.CrossEntropyLoss损失函数 142 | 143 | CrossEntropyLoss损失函数,也称为**交叉熵损失函数**,是深度学习中**用于分类问题**的一种常用损失函数。**它衡量的是模型预测的概率分布与真实标签的概率分布之间的差异**。尽管它通常与多分类问题相关联,但**也可以用于二分类问题**(在这种情况下,它等价于二元交叉熵损失,即BCELoss的特例)。 144 | 145 | #### 5.1 定义与原理 146 | 147 | 交叉熵损失函数通过比较模型对每个类别的**预测概率**和真实的标签(通常是独热编码形式)来计算损失。如果模型对某个样本的预测概率分布与真实标签**越接近**,则**交叉熵损失越小**;反之,损失越大。 148 | 149 | 对于多分类问题,假设有\_C\_个类别,对于每个样本,交叉熵损失的计算公式如下: 150 | 151 | $$ 152 | textCrossEntropyLoss =-\sum_{c-1}^{C} y_{c} \log \left(p_{c}\right) 153 | $$ 154 | 155 | 其中,$y_c $是样本的真实标签中第 `c` 类的值(在独热编码中,只有一个元素为1,其余为0),$p_c$ 是模型预测的第 `c` 类的概率。 156 | 157 | 注意,在实际计算中,由于$y_c $ 是独热编码的,所以上式中的求和实际上只涉及一个非零项,即真实标签对应类别的预测概率的对数的负值。 158 | 159 | #### 5.2 优点与注意 160 | 161 | **优点**: 162 | 163 | 1. **直观性**:交叉熵损失能够**直观地反映**模型预测的概率分布与真实标签之间的差异。 164 | 2. **易于优化**:由于交叉熵损失函数是凸函数(在模型输出为softmax概率的情况下),因此可以使用**梯度下降**等优化算法来有效地最小化损失。 165 | 3. **鲁棒性**:交叉熵损失对预测概率的**微小变化敏感**,这有助于模型在训练过程中更准确地逼近真实标签。 166 | 167 | **注意**: 168 | 169 | 1. **输入要求**:在使用交叉熵损失函数时,需要确保**模型输出的是概率值**(通常通过softmax函数进行转换),而真实标签是独热编码形式的。 170 | 2. **数值稳定性**:当预测概率接近0时,log(*p*) 的值会趋于负无穷,这可能导致数值问题。为了解决这个问题,可以在计算对数之前对预测概率进行**平滑处理**(例如,添加一个小的正数 *ϵ* 到预测概率中)。 171 | 3. **权重平衡**:在处理类别不平衡的数据集时,可以为不同类别的损失分配不同的权重,以改善模型的性能。 172 | 173 | #### 5.3 应用 174 | 175 | 交叉熵损失函数广泛应用于**多分类问题**中,如图像分类、文本分类等。在这些任务中,模型需要输出每个类别的概率预测,而交叉熵损失函数能够有效地评估模型预测的准确性,并指导模型的优化方向。 176 | 177 | ## 6.总结 178 | 179 | 本篇介绍了部分损失函数,损失函数有很多,这些是较为常用的,其余可以自行了解哦\~ 180 | 181 | 1. L1Loss损失函数:通常用于**回归任务**中。 182 | 2. NLLLoss损失函数:在**多分类问题**中广泛应用。 183 | 3. MSELoss损失函数:在**多种回归任务**中表现出色。 184 | 4. BCELoss损失函数:广泛应用于各类**二分类任务中**。 185 | 5. CrossEntropyLoss交叉熵损失函数:广泛应用于**多分类问题**中。 186 | -------------------------------------------------------------------------------- /docs/dl/5.优化器.md: -------------------------------------------------------------------------------- 1 | # 5.优化器 2 | 3 | ## 1.梯度下降变形形式 4 | 5 | ### 1.1批量梯度下降(batch gradient descent) 6 | 7 | 批量梯度下降,计算整个训练数据集的目标函数对参数 $θ$ 的梯度: 8 | 9 | $$ 10 | \theta=\theta-\eta \cdot \nabla_{\theta} J(\theta) 11 | $$ 12 | 13 | 使用批量梯度下降时代码一般如下所示: 14 | 15 | ```python 16 | for i in range(nb_epochs): 17 | params_grad = evaluate_gradient(loss_function, data_list, params) 18 | params = params - learning_rate * params_grad 19 | 20 | ``` 21 | 22 | 批量梯度下降的缺点是其需要计算整个数据集的梯度,然后仅用于执行一次更新。这导致批量梯度下降速度非常慢。另外如果数据量比较大时,内存一般也不足以加载这些数据。 23 | 24 | 批量梯度下降能够保证收敛到凸函数的最小值,或者非凸函数的极小值。 25 | 26 | ### 1.2 随机梯度下降(Stochastic gradient descent) 27 | 28 | 随机梯度下降 (SGD) 对每个训练示例 $x(i)$ 和标签 $y(i)$ 执行参数更新: 29 | 30 | $$ 31 | \theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i)} ; y^{(i)}\right) 32 | $$ 33 | 34 | 上一部分已经说过,批量梯度下降的计算量是非常大的,因为它每次更新都要计算所有数据的梯度。而SGD则是每次仅计算一条数据的梯度,所以SGD的速度更快。但是由于SGD每次只使用一条数据进行更新,所以**其目标函数的值也会出现较大幅度的波动**,如下图所示。 35 | 36 | ![](image/image_VQ92WkZEST.png) 37 | 38 | 除了速度以外,SGD还有另一方面的优势。对于非凸函数,批量梯度下降会优化到极小值点,但SGD的波动能够使其跳出极小值点,进入更好的局部最小值。 39 | 40 | 但是上述这种现象也使得SGD的收敛过程变得非常复杂,甚至其不能收敛到局部最小值。有一种方法是随着学习的进行慢慢降低学习率,在这种策略下SGD能够表现出与批量梯度下降较为相似的收敛行为,能够稳定收敛到凸函数的全局最小值,或者非凸函数的局部最小值。 41 | 42 | 下面是使用SGD的一般代码结构: 43 | 44 | ```python 45 | for i in range(nb_epochs): 46 | np.random.shuffle(data_list) 47 | for example in data_list: 48 | params_grad = evaluate_gradient(loss_function , example , params) 49 | params = params - learning_rate * params_grad 50 | 51 | ``` 52 | 53 | 在上述代码中可以看出,每个epoch都会对所有的数据进行一次shuffle,这是一个常规操作。而在批量梯度下降中却没有该操作,原因是批量梯度下降每次都是计算完全量数据的梯度再更新,是否shuffle对它计算出的梯度没有影响。 54 | 55 | ### 1.3 Mini-batch梯度下降(Mini-batch gradient descent) 56 | 57 | Mini-batch梯度下降结合批量梯度下降和SGD两者各自的优势,其每次对一个小批量的 n 个训练样本求梯度,并做一次更新。公式如下: 58 | 59 | $$ 60 | \theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i: i+n)} ; y^{(i: i+n)}\right) 61 | $$ 62 | 63 | Mini-batch梯度下降的优势有: 64 | 65 | - 相比于SGD,每次更新时减少了更新的方差,使得收敛比SGD更稳定; 66 | - 相比于批量梯度下降,计算速度大幅提升;同时也有一定的跳出局部最小值的能力; 67 | 68 | 目前的深度学习中基本都是使用Mini-batch梯度下降,但是使用术语时一般使用SGD。为了和大部分资料保持一致性,在本文的后面部分也是如此,提到SGD时指的是Mini-batch梯度下降。 69 | 70 | 下面是Mini-batch梯度下降的一般代码结构: 71 | 72 | ```python 73 | for i in range(nb_epochs): 74 | np.random.shuffle(data_list) 75 | for batch in get_batches(data_list, batch_size=50): 76 | params_grad = evaluate_gradient(loss_function, batch, params) 77 | params = params - learning_rate * params_grad 78 | 79 | ``` 80 | 81 | ## 2.梯度下降遇到的挑战 82 | 83 | 上面提到的三种梯度下降的方法都是比较原始的,并不能保证比较好的收敛性,它们存在的问题有: 84 | 85 | - **选择合适的学习率比较困难**。学习率选的太小了会导致收敛缓慢,学习率选的太大了会导致不收敛在最小值附近波动,甚至于发散。 86 | - 有些策略是在训练的过程中调整学习率,但是这些策略里什么时候需要调整、调整为多大都是在训练前预定义好的,对不同的数据集特征的适应性比较差,换一个数据集可能就不生效了。 87 | - **鞍点问题**。有些研究表明,很多时候问题并不是梯度下降收敛到了局部最小值点,而是收敛到了鞍点,收敛到鞍点之后可能模型的效果比收敛到局部最小值点还差。 88 | 89 | ## 3.梯度下降优化算法 90 | 91 | 接下来将列举一些被深度学习社区广泛用于解决上述困难的算法,这些算法有个共同之处,**一般是求一阶动量(m)和二阶动量(V),然后利用一阶、二阶动量本身或者他们组合来优化梯度下降**(其中一阶动量为与梯度相关函数,二阶动量为与梯度平方相关的函数) 92 | 93 | 首先还是给出梯度下降的公式: 94 | 95 | $$ 96 | \theta_{t+1}=\theta_{t}-\eta \frac{\partial(\text { Loss })}{\partial \theta_{t}} 97 | $$ 98 | 99 | 引入梯度下降优化算法后: 100 | 101 | $$ 102 | \theta_{t+1}=\theta_{t}-\eta \frac{m_{t}}{\sqrt{V_{t}}} 103 | $$ 104 | 105 | ### 3.1 动量法(Momentum) 106 | 107 | 随机梯度下降的方法很难通过峡谷区域(也就是在一个维度梯度变化很大,另一个维度变化较小),这个很好理解,因为梯度下降是梯度更新最大的反方向,如果这个时候一个维度梯度变化很大,那么就很容易在这个方向上振荡,另一个方向就更新很慢,如下图: 108 | 109 | ![](image/image_OQIO6bJNUM.png) 110 | 111 | 动量法就是为了解决上述问题,能够对朝着极值点的方向加速,并能够一定程度上抑制震荡。使用动量法的优化路径会是下图2b中所示。 112 | 113 | 动量法的具体做法是:**将过去的时间步更新的向量的一部分 **$γ$** 添加到当前更新的向量上**。通过这种方式,历史时间步中使得优化轨迹来回震荡的方向的动量会相互抵消,剩下的主要是朝着极值点的方向的动量。公式如下所示: 114 | 115 | $$ 116 | \begin{aligned}m_{t} & =\gamma m_{t-1}+\eta \nabla_{\theta} J(\theta) \\ 117 | \theta_{t+1} & =\theta_t - m_{t}\end{aligned} 118 | $$ 119 | 120 | 动量项 $γ$ 通常设置为 0.9 或类似值。 121 | 122 | 本质上,当使用动量法时:对于梯度指向相同方向的维度,动量项会增加,而对于梯度改变方向的维度,动量项的更新会减少。 结果,我们获得了更快的收敛速度并减少了振荡。 123 | 124 | ### 3.2 NAG(Nesterov accelerated gradient) 125 | 126 | 然而,盲目地顺着斜坡滚下山坡的球是非常不令人满意的。 我们想要一个更聪明的球,一个知道它要去哪里的球,这样它就知道在山再次倾斜之前减速。 127 | 128 | NAG 是一种赋予我们的动量项这种先见之明的方法。 知道我们将使用动量项 $γv_t−1$ 来移动参数 $θ$。 因此,计算 $θ−γv_t−1$ 为我们提供了参数下一个位置的近似值(完全更新时梯度缺失),这是参数将在哪里的粗略概念。 现在可以通过计算梯度来有效地向前看。 129 | 130 | $$ 131 | \begin{aligned} m_{t} & =\gamma m_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma m_{t-1}\right) \\ 132 | \theta_{t+1} & =\theta_t - m_{t}\end{aligned} 133 | $$ 134 | 135 | ![](image/image_EkdkFEhzz3.png) 136 | 137 | 同样,将动量项 $γ$ 设置为 0.9 左右的值。 Momentum 首先计算当前梯度(图 3 中的小蓝色向量),然后在更新的累积梯度(蓝色大向量)的方向上大跳,而 NAG 首先在前一个累积梯度的方向上大跳( 棕色矢量),测量梯度,然后进行校正(绿色矢量)。 这种预期性的更新可以防止我们走得太快,从而提高响应能力,从而显着提高了 RNN 在许多任务上的性能。 138 | 139 | 既然我们能够使我们的更新适应我们的误差函数的斜率并反过来加速 SGD,我们还希望我们的更新适应每个单独的参数,以根据它们的重要性执行更大或更小的更新。 140 | 141 | ### 3.3 Adagrad 142 | 143 | 之前提到过这个问题:对于所有特征,我们的学习率一直没有变。 144 | 145 | Adagrad算法就是为了解决这个问题,**让学习率学习数据的特征自动调整其大小,Adagrad算法引入了二阶动量**(V),其表达式为: 146 | 147 | $$ 148 | \begin{array}{c}m_{t}=g_{t} \\ V_{t}=\sum_{\tau}^{t} g_{\tau}^{2} \\ \theta_{t+1}=\theta_{t}-\eta \frac{m_{t}}{\sqrt{V_{t}}}\end{array} 149 | $$ 150 | 151 | 其中$g(t)$为`t`时刻参数梯度, 152 | 153 | 下面来讲解为什么adagrad可以实现不同频率特征对其参数学习率改变,首先,看到二阶动量$V(t)$,它是梯度平方累加和,对于训练数据少的特征,自然对应的参数更新就缓慢,也就是说他们的梯度变化平方累加和就会比较小,所以对应于上面参数更新方程中的学习速率就会变大,所以对于某个特征数据集少,相应参数更新速度就快。为了防止上述分母为0,所以往往添加一个平滑项参数`ε`,参数更新方程也就变成: 154 | 155 | $$ 156 | \theta_{t+1}=\theta_{t}-\eta \frac{m_{t}}{\sqrt{V_{t}+\epsilon}} 157 | $$ 158 | 159 | 但是Adagrad同样也有问题,就是其分母随着训练数增加,也会跟着增加,这样会导致学习速率越来越小,最终变的无限小,从而无法有效更新参数。 160 | 161 | ### 3.4 RMSprop 162 | 163 | RMSprop算法由hinton教授提出,它与Adadelta算法公式其实是一样的,他们是在相同时间被独立的提出,公式自然也为: 164 | 165 | $$ 166 | \begin{array}{c}m_{t}=g_{t} \\ V_{t}=\gamma V_{t-1}+(1-\gamma) g_{t}^{2} \\ \theta_{t+1}=\theta_{t}-\eta \frac{m_{t}}{\sqrt{V_{t}+\epsilon}}\end{array} 167 | $$ 168 | 169 | hinton教授建议将$γ$设置为0.9,对于学习率,一个好的固定值为0.001。 170 | 171 | ### 3.5 Adam 172 | 173 | Adam (Adaptive Moment Estimation) **自适应矩估计**,是另一种**自适应学习率的算法**,它是一种将动量和Adadelta或RMSprop结合起来的算法,也就引入了两个参数$β_1$和$β_2$,其一阶和二阶动量公式为: 174 | 175 | $$ 176 | \begin{aligned} m_{t} & =\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ V_{t} & =\beta_{2} V_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2}\end{aligned} 177 | $$ 178 | 179 | 作者发现一阶和二阶动量初始训练时很小,接近为$0$,因为$β$值很大,于是作者重新计算一个偏差来校正: 180 | 181 | $$ 182 | \begin{array}{l}\hat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \hat{v}_{t}=\frac{v_{t}}{1-\beta_{2}^{t}}\end{array} 183 | $$ 184 | 185 | 其中`t`代表其`t`次方,所以刚开始训练时,通过除于 `(1-β)` 就可以很好修正学习速率,当训练多轮时,分母部分也接近1,又回到了原始方程,所以最后总的梯度更新方程为: 186 | 187 | $$ 188 | \begin{array}{c}m_{t}=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ V_{t}=\beta_{2} V_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2} \\ \widehat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \hat{V}_{t}=\frac{V_{t}}{1-\beta_{2}^{t}} \\ \theta_{t+1}=\theta_{t}-\eta \frac{\widehat{m}_{t}}{\sqrt{\hat{V}_{t}+\epsilon}}\end{array} 189 | $$ 190 | 191 | 其中$β1$默认值为0.9,$β2$默认值为0.999, $ε$为10^-8,Adam集合动量和Adadelta两者的优点,从经验中表明Adam在实际中表现很好,同时与其他自适应学习算法相比,更有优势。 192 | 193 | ## 4.可视化优化器 194 | 195 | ![](image/9cf7ce63ee9047df36576f6b5f2ca290__m9AiUI0Ya.gif) 196 | 197 | ![](image/1c6290931f35b50f794a8acca445e829_cCz574Huf6.gif) 198 | 199 | ## 5.其他SGD优化器 200 | 201 | 1、Shuffling and Curriculum Learning 202 | 203 | 2、Batch normalization 204 | 205 | 3、Early stopping 206 | 207 | 4、Gradient noise 208 | -------------------------------------------------------------------------------- /docs/dl/6.评估指标.md: -------------------------------------------------------------------------------- 1 | # 6.评估指标 2 | 3 | ## 1.BLEU 4 | 5 | ### 1.1 BLEU计算 6 | 7 | BLEU(Bilingual Evaluation Understudy)是一种在机器翻译领域广泛采用的评估指标,其通过计算机器翻译输出(下称为“候选文本”)与参考翻译文本(下称为“参考文本”)之间的**词汇相似度来评估翻译质量**。BLEU 主要**计算候选文本与参考文本的 **$𝑛$** 元组(𝑛-gram)共现频率**,评分结果在 `[0, 1]` 的区间内, 具体的计算方式如下所示: 8 | 9 | $$ 10 | \mathrm{BLEU}=\mathrm{BP} \times \exp \left(\sum_{n=1}^{N} w_{n} \times \log p_{n}\right) 11 | $$ 12 | 13 | 其中,$𝑤_𝑛$ 是 `𝑛` 元组的权重,用于调整不同长度的 `𝑛` 元组对最终评分的影响。具体 实践中,研究者通常设 𝑛 = 4,并平均分配 $𝑤_𝑛$。BP 表示长度惩罚因子,用于修正由于候选文本长度过短导致的评分偏差,其计算方式为: 14 | 15 | $$ 16 | \mathrm{BP}=\left\{\begin{array}{ll}1, & \text { if } l_{c}>l_{r} \\ \exp \left(1-\frac{l_{r}}{l_{c}}\right), & \text { if } l_{c} \leq l_{r}\end{array}\right. 17 | $$ 18 | 19 | 这里,$𝑙_𝑐$ 和 $𝑙_𝑟$ 分别表示候选文本的长度和最短的参考文本长度。而公式 BLEU中的 $𝑝_𝑛$ 代表 `𝑛` 元组的精确率,计算公式如下: 20 | 21 | $$ 22 | p_{n}=\frac{\sum_{\mathrm{n}-\text { gram } \in C} \min \left(\operatorname{count}_{C}(\mathrm{n}-\mathrm{gram}), \max _{R \in \mathcal{R}} \operatorname{count}_{R}(\mathrm{n}-\mathrm{gram})\right)}{\sum_{\mathrm{n} \text {-gram } \in C} \operatorname{count}_{C}(\mathrm{n} \text {-gram })} 23 | $$ 24 | 25 | 其中,`𝐶` 代表候选文本,`𝑅` 代表所有参考文本集合 `R` 中的一个文本,$count_𝐶 (n-gram)$ 和 $count_𝑅 (n-gram)$ 分别指 `𝑛` 元组在候选文本和参考文本中的出现次数 26 | 27 | 在做 n-gram 划分时,随着 n 的增大得分越来越低。这个是很直观的,当 n 非常大时就等于是要求生成的结果必须和人工标注的译文一摸一样才能得分。 28 | 29 | ### 1.2 BLEU 优缺点[#](#13-bleu "#") 30 | 31 | 优点: 32 | 33 | - BLEU 快速且易于计算,特别是与人工翻译速率模型输出相比的话尤为明显。 34 | - BLEU 无处不在,这使你将模型与同一任务的基准进行比较变得更为轻松。 35 | 36 | 缺点: 37 | 38 | - BLEU 是在计算准确率,所以该指标不能很好的衡量召回的质量。 39 | - 它不考虑意义; 40 | - 它不直接考虑句子结构; 41 | - 它不能很好地处理形态丰富的语言; 42 | - 它与人类的判断并不相符; 43 | 44 | ## 2.ROUGE指标 45 | 46 | ROUGE(Recall-Oriented Understudy for Gisting Evaluation)指标总共有四种:Rouge-N、Rouge-L、Rouge-W、Rouge-S。相比于 BLEU 计算的是准确率,ROUGE **指标计算的是召回率,即强调文本信息的覆盖度和完整度**。 47 | 48 | ### 2.1 Rouge-N 指标 49 | 50 | Rouge-N 的全称为 N-gram Co-Occurrence Statistics。 51 | 52 | 简单来说 Rouge-N 就是**将模型生成结果和标注结果按照 n-gram 划分后,计算召回率**。公式为: 53 | 54 | $$ 55 | ROUGE-n=\frac{\sum_{\mathrm{n} \text {-gram } \in R} \min \left(\operatorname{count}_{C}(\mathrm{n} \text {-gram }), \operatorname{count}_{R}(\mathrm{n} \text {-gram })\right)}{\sum_{\mathrm{n} \text {-gram } \in R} \operatorname{count}_{R}(\mathrm{n} \text {-gram })} 56 | $$ 57 | 58 | 其中,`𝐶` 代表候选文本,`𝑅` 代表参考文本。在此公式中,分母表示所有参考文本中 `𝑛` 元组的总数,而分子表示候选文本与参考文本中匹配的 `𝑛` 元组的数量 59 | 60 | 和 BLEU 一样,n 越大,得分越低。 61 | 62 | ### 2.2 Rouge-L 指标 63 | 64 | Rouge-L 的全称为 Longest Common Subsequence。 65 | 66 | 无论 BLEU 指标还是 Rouge-N 指标使用的都是词袋模型,它们都不考虑词语之间的相对顺序,而 Rouge-L 指标则是考虑了词语之间的相对顺序。这个名字里的 L 表示的是Longest Common Subsequence(最长公共子序列:注意这个非连续的)。 67 | 68 | ROUGE-L 以 F1 分数计算,结合了精确率和召回率的信息。精确率衡量了候选文本中有多少内容是与参考文本相关的,而召回率则衡量了参考文本中有多少内容被候选文本所覆盖。具体计算公式如下: 69 | 70 | $$ 71 | \begin{aligned} \text { Recall } & =\frac{\operatorname{LCS}(C, R)}{\operatorname{length}(R)} \\ \text { Precision } & =\frac{\operatorname{LCS}(C, R)}{\text { length }(C)} \\ \mathrm{F} 1 & =\frac{\left(1+\beta^{2}\right) \cdot \text { Precision } \cdot \text { Recall }}{\left(\beta^{2} \cdot \text { Precision }\right)+\text { Recall }}\end{aligned} 72 | $$ 73 | 74 | 在上述公式中,$LCS(𝐶, 𝑅)$ 表示 `𝐶` 和 `𝑅` 之间的最长公共子序列长度。$length(𝐶)$ 和 $length(𝑅)$ 分别代表候选文本和参考文本的长度。在 ROUGE-L 中,$\beta 75 | $ 用于决定召 回率的权重。 76 | 77 | ### 2.3 Rouge-W 指标 78 | 79 | Rouge-W 的全称为 Weighted Longest Common Subsequence。 80 | 81 | Rouge-L 指标虽然考虑了词语之间的相对顺序,但是由于其使用最长公共子序列,所以没有考虑到词语之间是否连续的问题。 82 | 83 | 如果使用 Rouge-L 计算的话,得分是相同的。所以提出了 Rouge-W 指标。简单来说,**Rouge-W 就是给连续匹配到的子序列更高的权重,最终让连续匹配的结果要比非连续匹配的结果得分更高一些**。 84 | 85 | Rouge-W 的计算公式如下: 86 | 87 | $$ 88 | \begin{aligned} R_{w l c s} & =f^{-1}\left(\frac{\mathrm{WLCS}(X, Y)}{f(m)}\right) \\ P_{w l c s} & =f^{-1}\left(\frac{\mathrm{WLCS}(X, Y)}{f(n)}\right) \\ F_{w l c s} & =\frac{\left(1+\beta^{2}\right) R_{u l c s} P_{w l c s}}{R_{w l c s}+\beta^{2} P_{w l c s}}\end{aligned} 89 | $$ 90 | 91 | 其中函数 $f(⋅)$ 就是实现给予连续匹配的序列更高权重的函数,比如连续的、相邻的 `x` 和 `y` 的权重 $f(xy)$ 要比不连续的单独的 $f(x)$ 和 $f(y)$ 的分值要高,即:$f(xy)>f(x)+f(y)$。函数 $f^{−1}(⋅)$ 是函数 $f(⋅)$ 的逆函数。$WLCS(⋅)$ 表示带有加权的最长公共子序列,这里加权的权重就是给连续匹配的子序列更高的权重。其他部分的计算和 Rouge-L 是一致的。 92 | 93 | > 该算法还是比较复杂的,关于函数 $f(⋅)$ 和其逆函数 $f^{−1}(⋅)$ 更多的性质,以及其具体的公式。还有 $WLCS(⋅)$ 算法的细节,请看原始论文:[https://aclanthology.org/W04-1013.pdf](https://aclanthology.org/W04-1013.pdf "https://aclanthology.org/W04-1013.pdf") 94 | 95 | ### 2.4 Rouge-S 指标 96 | 97 | Rouge-S 的全称为 Skip-Bigram Co-Occurrence Statistics。 98 | 99 | 在 Rouge-N 中对文本做 2-gram 划分(也称 bigram 划分)时,都是连续的进行划分。在 Rouge-S 中使用的 skip-bigram 则是在划分时允许跳过一些词。下面先放上计算公式,然后举例进行说明如何计算。 100 | 101 | Rouge-S 的计算公式如下: 102 | 103 | $$ 104 | \begin{array}{c}R_{s k i p 2}=\frac{\operatorname{SKIP} 2(X, Y)}{C(m, 2)} \\ P_{s k i p 2}=\frac{\operatorname{SKIP} 2(X, Y)}{C(n, 2)} \\ F_{s k i p 2}=\frac{\left(1+\beta^{2}\right) R_{s k i p 2} P_{s k i p 2}}{R_{s k i p 2} 2+\beta^{2} P_{s k i p 2}}\end{array} 105 | $$ 106 | 107 | 其中 `X` 表示人工标注的结果,`Y` 表示模型预测的结果,$SKIP2(X,Y)$ 表示标注结果按照 skip-bigram 拆分后与预测结果按照 skip-bigram 拆分后匹配上的个数。$C(m,2)$ 表示人工标注结果按照 skip-bigram 拆分后的个数,$C(n,2)$ 表示预测结果按照 skip-bigram 拆分后的个数。$β$ 是超参数。 108 | 109 | 其中 $SKIP2(X,Y)$ 表示所有样本的标注结果按 n-gram 拆分后与生成结果按 n-gram 拆分后匹配上个数的和;分母表示所有样本的标注结果按 n-gram 拆分后的和。下面举例说明计算方式。 110 | 111 | ## 3.分类指标 112 | 113 | ### 3.1 A、P、R、F1 114 | 115 | | **混淆矩阵** | | | 116 | | ---------------- | -------------------- | ------------------- | 117 | | | 预测值 **P(Positives)** | 预测值**N(Negatives)** | 118 | | 真实值**T(Ture)** | TP:正样本,预测结果为正(真阳性) | FN:正样本,预测结果为负(假阴性) | 119 | | 真实值**F (False)** | FP:负样本,预测结果为正(假阳性) | TN:负样本,预测结果为负(真阴性) | 120 | 121 | - **准确率**:所有预测正确的正例和负例,占所有样本的比例,其定义为:$Accuracy =\frac{T P+T N}{P+N}$ 122 | - **精确率**:模型**预测为正例的样本中真正为正例的比例**,其定义为:$Precision =\frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FP}}$ 123 | - **召回率**:所有**真正为正例的样本中被模型正确预测出来的比例**, 其定义为:$Recall =\frac{\mathrm{TP}}{\mathrm{TP}+\mathrm{FN}}$ 124 | - **F1分数**:是精确率和召回率的调和平均数,用于衡量模型在分类任 务上的综合性能,其定义为:$F1 =2 \times \frac{\text { Precision } \times \text { Recall }}{\text { Precision }+ \text { Recall }}$ 125 | 126 | ### 3.2 P-R曲线 127 | 128 | P-R曲线:通过选择不同的阈值,得到Recall和Precision,以Recall为横坐标,Precision为纵坐标得到的曲线图。 129 | 130 | ![](image/image_TO2iAcgR7r.png) 131 | 132 | PR曲线性质: 133 | 134 | - 如果一个学习器的P-R曲线被另一个学习器的曲线完全包住,后者性能优于前者; 135 | - 如果两个学习器的曲线相交,可以通过平衡点(如上图所示)来度量性能; 136 | - 如果有个划分点可以把正负样本完全区分开,那么P-R曲线面积是`1*1`; 137 | 138 | 阈值下降: 139 | 140 | - **Recall**:不断增加,因为越来越多的样本被划分为正例,假设阈值为0.,全都划分为正样本了,此时recall为1; 141 | - **Precision**:正例被判为正例的变多,但负例被判为正例的也变多了,因此precision会振荡下降,不是严格递减; 142 | - **AP(average precision)**:Precision-recall 曲线下围成的面积,一般一个分类器性能越好,AP值越高。 143 | - **mAP(mean average precision)**:多个类别AP的平均值。 144 | 145 | ### 3.3 ROC-AUC 146 | 147 | **ROC**(Receiver Operating Characteristic)曲线:**曲线的****横坐标为假正例率(FPR)****,即实际为负的样本有多少被预测为正;****纵坐标为TPR(真正例率)****,即实际为正的样本多少被预测为正**。 148 | 149 | $$ 150 | F P R=\frac{F P}{F P+T N} 151 | $$ 152 | 153 | $$ 154 | T P R=\frac{T P}{T P+F N}=\text { Recall } 155 | $$ 156 | 157 | TPR和FPR的范围均是`[0,1]`,通过选择不同的阈值得到TPR和FPR,然后绘制ROC曲线。 158 | 159 | ![](image/image_-5-KhHc6vb.png) 160 | 161 | **AUC (Area under Curve)**:即ROC曲线下的面积,介于0.1和1之间,作为数值可以直观的评价分类器的好坏,值`越大越好`。 162 | -------------------------------------------------------------------------------- /docs/dl/README.md: -------------------------------------------------------------------------------- 1 | # 深度学习 2 | 3 | ## 简介 4 | 5 | 主要来自于到处收集的深度学习容易混淆的基础知识 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/dl/image/1c6290931f35b50f794a8acca445e829_cCz574Huf6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/1c6290931f35b50f794a8acca445e829_cCz574Huf6.gif -------------------------------------------------------------------------------- /docs/dl/image/9cf7ce63ee9047df36576f6b5f2ca290__m9AiUI0Ya.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/9cf7ce63ee9047df36576f6b5f2ca290__m9AiUI0Ya.gif -------------------------------------------------------------------------------- /docs/dl/image/image_-5-KhHc6vb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_-5-KhHc6vb.png -------------------------------------------------------------------------------- /docs/dl/image/image_2AtuZrFran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_2AtuZrFran.png -------------------------------------------------------------------------------- /docs/dl/image/image_2KV3LOKN2S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_2KV3LOKN2S.png -------------------------------------------------------------------------------- /docs/dl/image/image_9ED50ulsDw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_9ED50ulsDw.png -------------------------------------------------------------------------------- /docs/dl/image/image_9PYcDpzk-_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_9PYcDpzk-_.png -------------------------------------------------------------------------------- /docs/dl/image/image_AHzmMqgKgV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_AHzmMqgKgV.png -------------------------------------------------------------------------------- /docs/dl/image/image_EkdkFEhzz3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_EkdkFEhzz3.png -------------------------------------------------------------------------------- /docs/dl/image/image_GlE3RW4neL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_GlE3RW4neL.png -------------------------------------------------------------------------------- /docs/dl/image/image_OQIO6bJNUM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_OQIO6bJNUM.png -------------------------------------------------------------------------------- /docs/dl/image/image_TO2iAcgR7r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_TO2iAcgR7r.png -------------------------------------------------------------------------------- /docs/dl/image/image_VQ92WkZEST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_VQ92WkZEST.png -------------------------------------------------------------------------------- /docs/dl/image/image_mObw4TwnQV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_mObw4TwnQV.png -------------------------------------------------------------------------------- /docs/dl/image/image_vZZ0x7ThiD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_vZZ0x7ThiD.png -------------------------------------------------------------------------------- /docs/dl/image/image_zrvZp-9GRb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/dl/image/image_zrvZp-9GRb.png -------------------------------------------------------------------------------- /docs/ml/1.ML概念.md: -------------------------------------------------------------------------------- 1 | # 1.ML概念 2 | 3 | #### 1.介绍一个最熟悉的机器学习算法 4 | 5 | #### 2.机器学习导致误差的原因?过拟合、欠拟合对应的偏差和方差是怎样的? 6 | 7 | - 偏差:模型无法表达数据集的复杂度,模型不够复杂,导致不能学习到基本关系,导致欠拟合; 8 | - 方差:数据量有限,模型对数据过度敏感,导致方差; 9 | - 过拟合容易导致高方差,欠拟合容易导致高偏差; 10 | 11 | #### 3.如何解决过拟合问题?哪些角度 12 | 13 | - 数据层面:更多数据、数据增强; 14 | - 模型层面:更简单模型、更优化的模型; 15 | - 正则化:权重衰减正则化; 16 | - bagging等集成学习方法,深度学习中的dropout; 17 | - 早停:训练集最优不一定在测试集最优 18 | - BN、LN等实践中也有助于降低过拟合风险; 19 | 20 | #### 5.说一下SVD怎么降维 21 | 22 | SVD(奇异值分解)进行降维的基本思路是**保留矩阵中最重要的信息部分,同时丢弃那些次要的或冗余的信息,从而达到简化数据的目的**。下面我将详细介绍如何利用SVD来进行降维。 23 | 24 | SVD是一种可以应用于任何大小矩阵的技术,它将一个矩阵分解为三个矩阵的乘积。对于一个m×n的矩阵A,它的SVD形式可以写为: 25 | 26 | $$ 27 | [ A = U \Sigma V^T ] 28 | $$ 29 | 30 | - $U$ :是一个`m×m`的正交矩阵,包含了A的左奇异向量。 31 | - $\Sigma$ :是一个`m×n`的对角矩阵,对角线上的元素是A的奇异值,按从大到小排序。 32 | - $V$ :是一个`n×n`的正交矩阵,包含了A的右奇异向量。 33 | 34 | 降维的核心**在于选取**$\Sigma$\*\* 矩阵中的前k个最大的奇异值(k < n)\*\*,这样可以保留矩阵A最重要的k个方向的信息。通过这种方式,可以将原本的n维数据映射到k维空间,实现降维的目的。 35 | 36 | 假设我们要将矩阵A降维到k维空间: 37 | 38 | 1. **计算SVD**:首先计算矩阵A的SVD分解,得到( $A = U \Sigma V^T$ )。 39 | 2. **截断奇异值矩阵**:从($ \Sigma$ )矩阵中选取前k个最大的奇异值构成一个新的k阶对角矩阵( $\Sigma_k $),这通常意味着保留( $\Sigma $)的前k行和前k列。 40 | 3. **选取主成分**:取( $U$ )矩阵的前k列构成新的矩阵( $U_k$ ),这实际上是从原始数据空间中选择了k个方向作为新的特征轴。 41 | 4. **重构矩阵**:利用( $U_k$ )和( $\Sigma_k$ )来重构一个近似矩阵( $A_{approx}$ ),这个矩阵是在k维空间内的最佳近似。有时也会直接使用( $U_k \Sigma_k$ )来表示降维后的数据,这样就可以得到一个m×k的矩阵,每个样本在这个新空间中的表示。 42 | 5. **降维后的应用**:降维后的数据可以用在多种场景中,如可视化、提高模型训练效率、减少过拟合风险等。 43 | 44 | #### 6.推导softmax做激活函数求导 45 | 46 | #### 7.正则化项L1和L2为什么有用 47 | 48 | - **L1正则化**,相当于为模型添加了一个先验知识,就是**权重矩阵W服从均值为0的拉普拉斯分布**; 49 | - **L2正则化**,相当于为模型添加了一个正态分布先验知识,就是**权重矩阵W服从均值为0的正态分布**。 50 | - **L1正则化和L2正则化可以看做是损失函数的惩罚项**。所谓『惩罚』是指对损失函数中的某些参数做一些限制。拟合过程中通常都倾向于让权值尽可能小,最后构造一个所有参数都比较小的模型。因为一般认为参数值小的模型比较简单,能适应不同的数据集,也在一定程度上避免了过拟合现象。 51 | 52 | #### 8.L1正则不可导,如何优化 53 | 54 | 在不可导处无法进行梯度下降,此时采用坐标轴下降法:坐标轴下降法是沿着坐标轴的方向,每次固定m-1个数值,对最后一个数值求局部最优解,迭代m次(证明:凸函数在每一个维度都取得最小值,则此处就是全局最小值); 55 | 56 | #### 9.什么样的特征容易产生比较小的权重 57 | 58 | 特征的权重反映了该特征对于模型预测结果的重要性。较小的权重可能意味着该特征对于模型输出的影响较弱,可能是由于多种原因造成的。以下是一些可能导致特征产生较小权重的因素: 59 | 60 | 1. **特征的稀有性**:当一个特征在数据集中很少出现时,模型可能会给这个特征分配较小的权重。例如,在推荐系统中,如果某个用户只看过一次某种类型的电影,而其他用户都没有看过这种类型的电影,那么在训练模型时,这种类型的电影可能会被赋予较低的权重。 61 | 2. **特征的相关性**:如果一个特征与其他特征高度相关,那么模型可能会倾向于选择那些更具代表性的特征,并给其余相关特征分配较小的权重。这是因为高度相关的特征提供的信息可能是冗余的,因此不需要太高的权重来表达它们的重要性。 62 | 3. **特征的噪声水平**:如果一个特征包含大量的噪声,那么模型可能会自动调整权重以忽略这部分特征,从而减少噪声对预测结果的影响。这种情况下,特征的权重会变得较小。 63 | 4. **特征的无关性**:如果一个特征对于预测目标几乎没有贡献,那么模型会自然地给这个特征分配一个很小甚至接近于零的权重。这样的特征可能不会帮助模型提高预测准确率。 64 | 5. **模型的正则化**:使用正则化技术(如L1或L2正则化)可以帮助减少模型的复杂度并防止过拟合。在L1正则化下,模型倾向于将不重要的特征权重压缩至零,而在L2正则化下,不重要的特征权重可能会变得非常小。 65 | 6. **训练数据的数量**:在数据量较少的情况下,模型可能会对某些特征赋予较小的权重,因为缺乏足够的证据证明这些特征的重要性。 66 | 7. **特征的动态范围**:如果一个特征的动态范围(即最大值与最小值之间的差距)很小,那么这个特征的权重也可能会较小,因为即使在数值上发生改变,对模型输出的影响也不大。 67 | 8. **模型训练算法**:不同的训练算法可能对特征权重有不同的影响。例如,在使用随机梯度下降(SGD)进行模型更新时,相比批量更新(batch update),更容易产生大量小权重的特征。 68 | 69 | 总之,特征的权重受到多种因素的影响,包括但不限于特征本身的质量、与目标变量的关系、数据集的特性以及所使用的模型训练方法等。为了更好地理解和优化模型,分析特征权重是非常有用的步骤之一。 70 | -------------------------------------------------------------------------------- /docs/ml/2.LR模型.md: -------------------------------------------------------------------------------- 1 | # 2.LR模型 2 | 3 | ## 1.线性回归(Linear Regression) 4 | 5 | - 线性:两个变量之间的关系**是**一次函数关系的——图象**是直线**,叫做线性。 6 | - 非线性:两个变量之间的关系**不是**一次函数关系的——图象**不是直线**,叫做非线性。 7 | - 回归:人们在测量事物的时候因为客观条件所限,求得的都是测量值,而不是事物真实的值,为了能够得到真实值,无限次的进行测量,最后通过这些测量数据计算**回归到真实值**,这就是回归的由来。 8 | 9 | ### 1.1 计算 10 | 11 | **一般表达式**: 12 | 13 | $$ 14 | Y=w x+b 15 | $$ 16 | 17 | 其中,$w$叫做$x$的系数,$b$叫做偏置项 18 | 19 | **损失函数**:MSE 20 | 21 | $$ 22 | J=\frac{1}{2 m} \sum_{m}^{i=1}\left(y^{\prime}-y\right)^{2} 23 | $$ 24 | 25 | 利用**梯度下降法**找到最小值点,也就是最小误差,最后把 $w$ 和 $b$ 给求出来。 26 | 27 | ### 1.2 过拟合、欠拟合 28 | 29 | 使用**正则化项**,也就是给loss function加上一个参数项,正则化项有**L1正则化、L2正则化、ElasticNet**。加入这个正则化项好处: 30 | 31 | - 控制参数幅度,不让模型“无法无天”。 32 | - 限制参数搜索空间 33 | - 解决欠拟合与过拟合的问题。 34 | 35 | #### (1)L2正则化(岭回归) 36 | 37 | 方程:$J=J_{0}+\lambda \sum_{w} w^{2}$,其中$J_0$表示上面的 loss function ,在loss function的基础上加入$w$参数的平方和乘以 $\lambda$; 38 | 39 | 假设:$L=\lambda\left(w_{1}^{2}+w_{2}^{2}\right)$ 40 | 41 | 此时任务变成**在**$L$**约束下求出J取最小值的解。求解**$J_0$**的过程可以画出等值线**。同时L2正则化的函数L也可以在$w_1$ $w_2$的二维平面上画出来。如下图: 42 | 43 | ![](image/image_8GgBb12BYf.png) 44 | 45 | $L$表示为图中的黑色圆形,随着梯度下降法的不断逼近,与圆第一次产生交点,而这个交点很难出现在坐标轴上。这就说明了**L2正则化不容易得到稀疏矩阵**,同时为了求出损失函数的最小值,使得w1和w2无限接近于0,达到防止过拟合的问题。 46 | 47 | **使用场景**:只要数据线性相关,用Linear Regression拟合的不是很好,**需要正则化**,可以考虑使用岭回归(L2), 如何输入特征的维度很高,而且是稀疏线性关系的话,岭回归就不太合适,考虑使用Lasso回归。 48 | 49 | #### (2)L1正则化(Lasso回归) 50 | 51 | L1正则化与L2正则化的区别在于惩罚项的不同: 52 | 53 | $$ 54 | J=J_{0}+\lambda\left(\left|w_{1}\right|+\left|w_{2}\right|\right) 55 | $$ 56 | 57 | 求解$J_0$的过程可以画出等值线。同时L1正则化的函数也可以在$w_1$ $w_2$的二维平面上画出来。如下图: 58 | 59 | ![](image/image_ELXaGaECoB.png) 60 | 61 | 惩罚项表示为图中的黑色棱形,随着梯度下降法的不断逼近,与棱形第一次产生交点,而这个交点很容易出现在坐标轴上。**这就说明了L1正则化容易得到稀疏矩阵****。** ​ 62 | 63 | **使用场景**:**L1正则化(Lasso回归)可以使得一些特征的系数变小,甚至还使一些绝对值较小的系数直接变为0**,从而增强模型的泛化能力 。对于高的特征数据,尤其是线性关系是稀疏的,就采用L1正则化(Lasso回归),或者是要在一堆特征里面找出主要的特征,那么L1正则化(Lasso回归)更是首选了。 64 | 65 | #### (3)ElasticNet回归 66 | 67 | ElasticNet综合了L1正则化项和L2正则化项,以下是它的公式: 68 | 69 | $$ 70 | \min \left(\frac{1}{2 m}\left[\sum_{i=1}^{m}\left(y_{i}^{\prime}-y_{i}\right)^{2}+\lambda \sum_{j=1}^{n} \theta_{j}^{2}\right]+\lambda \sum_{j=1}^{n}|\theta|\right) 71 | $$ 72 | 73 | **使用场景**:ElasticNet在我们发现用Lasso回归太过(太多特征被稀疏为0),而岭回归也正则化的不够(回归系数衰减太慢)的时候,可以考虑使用ElasticNet回归来综合,得到比较好的结果。 74 | 75 | ### 1.4 一些问题 76 | 77 | #### (1)线性回归要求因变量服从正态分布 78 | 79 | 假设线性回归的噪声服从均值为0的正态分布。 当噪声符合正态分布$N(0,\delta^2)$时,因变量则符合正态分布$N(ax(i)+b,\delta^2)$,其中预测函数$y=ax(i)+b$。这个结论可以由正态分布的概率密度函数得到。也就是说**当噪声符合正态分布时,其因变量必然也符合正态分布**。 80 | 81 | 在用线性回归模型拟合数据之前,首先要求数据应符合或近似符合正态分布,否则得到的拟合函数不正确。 82 | 83 | ## 2.逻辑回归(Logistics Regression) 84 | 85 | 逻辑回归是用来做**分类算法**的,大家都熟悉线性回归,一般形式是$Y=aX+b$,y的取值范围是$[-∞, +∞]$,有这么多取值,怎么进行分类呢?不用担心,伟大的数学家已经为我们找到了一个方法。 86 | 87 | 也就是把$Y$的结果带入一个非线性变换的**Sigmoid函数**中,即可得到$[0,1]$之间取值范围的数`S`,`S`可以把它看成是一个概率值,如果设置概率阈值为0.5,那么S大于0.5可以看成是正样本,小于0.5看成是负样本,就可以进行分类了。 88 | 89 | ### 2.1 Sigmoid函数 90 | 91 | 函数公式: 92 | 93 | $$ 94 | S(t)=\frac{1}{1+e^{-t}} 95 | $$ 96 | 97 | ![](image/image_Uyzi-bBIpS.png) 98 | 99 | 函数中`t`无论取什么值,其结果都在`[0,-1]`的区间内,回想一下,一个分类问题就有两种答案,一种是“是”,一种是“否”,那0对应着“否”,1对应着“是”; 100 | 101 | 好了,接下来把$aX+b$带入$t$中就得到了我们的逻辑回归的一般模型方程: 102 | 103 | $$ 104 | H(a, b)=\frac{1}{1+e^{(a X+b)}} 105 | $$ 106 | 107 | 结果P也可以理解为概率,换句话说概率大于0.5的属于1分类,概率小于0.5的属于0分类,这就达到了分类的目的。 108 | 109 | ### 2.2 损失函数 110 | 111 | 逻辑回归的损失函数是 **log loss**,也就是**对数似然函数**,函数公式如下: 112 | 113 | $$ 114 | \operatorname{Cost}\left(h_{\theta}(x), y\right)=\left\{\begin{aligned}-\log \left(h_{\theta}(x)\right) & \text { if } y=1 \\ -\log \left(1-h_{\theta}(x)\right) & \text { if } y=0\end{aligned}\right. 115 | $$ 116 | 117 | 公式中的 `y=1` 表示的是真实值为1时用第一个公式,真实 `y=0` 用第二个公式计算损失。 118 | 119 | 为什么要加上log函数呢?可以试想一下,当真实样本为1是,但`h=0`概率,那么`log0=∞`,这就对模型最大的惩罚力度;当`h=1`时,那么`log1=0`,相当于没有惩罚,也就是没有损失,达到最优结果。所以数学家就想出了用log函数来表示损失函数。 120 | 121 | 最后按照梯度下降法一样,求解极小值点,得到想要的模型效果。 122 | 123 | ### 2.3 逻辑回归常用优化方法 124 | 125 | #### (1)一阶方法 126 | 127 | 梯度下降、随机梯度下降、mini 随机梯度下降降法。随机梯度下降不但速度上比原始梯度下降要快,局部最优化问题时可以一定程度上抑制局部最优解的发生。 128 | 129 | #### (2)二阶方法:牛顿法、拟牛顿法: 130 | 131 | 这里详细说一下牛顿法的基本原理和牛顿法的应用方式。 132 | 133 | 牛顿法其实就是**通过切线与x轴的交点不断更新切线的位置,直到达到曲线与x轴的交点得到方程解**。在实际应用中我们因为常常要求解凸优化问题,也就是要求解函数一阶导数为0的位置,而牛顿法恰好可以给这种问题提供解决方法。实际应用中牛顿法首先选择一个点作为起始点,并进行一次二阶泰勒展开得到导数为0的点进行一个更新,直到达到要求,这时牛顿法也就成了二阶求解问题,比一阶方法更快。常常看到的x通常为一个多维向量,这也就引出了Hessian矩阵的概念(就是x的二阶导数矩阵)。 134 | 135 | 缺点:牛顿法是定长迭代,没有步长因子,所以不能保证函数值稳定的下降,严重时甚至会失败。还有就是牛顿法要求函数一定是二阶可导的。而且计算Hessian矩阵的逆复杂度很大。 136 | 137 | 拟牛顿法: **不用二阶偏导而是构造出Hessian矩阵的近似正定对称矩阵的方法称为拟牛顿**法。拟牛顿法的思路就是用一个特别的表达形式来模拟Hessian矩阵或者是他的逆使得表达式满足拟牛顿条件。主要有DFP法(逼近Hession的逆)、BFGS(直接逼近Hession矩阵)、 L-BFGS(可以减少BFGS所需的存储空间)。 138 | 139 | ### 2.4 一些问题 140 | 141 | #### (1)优点 142 | 143 | - LR能以概率的形式输出结果,而非只是0,1判定。 144 | - LR的可解释性强,可控度高。 145 | - 训练快,feature engineering之后效果赞。 146 | - 因为结果是概率,可以做ranking model。 147 | 148 | #### (2)应用 149 | 150 | - CTR预估/推荐系统的learning to rank/各种分类场景。 151 | - 某搜索引擎厂的广告CTR预估基线版是LR。 152 | - 某电商搜索排序/广告CTR预估基线版是LR。 153 | - 某电商的购物搭配推荐用了大量LR。 154 | - 某现在一天广告赚1000w+的新闻app排序基线是LR。 155 | 156 | #### (3)可以多分类吗? 157 | 158 | 可以的,其实可以从二分类问题过度到多分类问题(one vs rest),思路步骤如下: 159 | 160 | 1. 将类型`class 1`看作正样本,其他类型全部看作负样本,然后就可以得到样本标记类型为该类型的概率`p1`。 161 | 2. 然后再将另外类型`class 2`看作正样本,其他类型全部看作负样本,同理得到`p2`。 162 | 3. 以此循环,可以得到该待预测样本的标记类型分别为类型`class i`时的概率`pi`,最后\*\*取`pi`\*\***中最大的那个概率对应的样本标记类型作为我们的待预测样本类型**。 163 | 164 | ![](image/image_NDV1nnrl2G.png) 165 | 166 | 总之还是以二分类来依次划分,并求出最大概率结果。 167 | 168 | #### (4)为什么要对特征离散化 169 | 170 | 1. **非线性!非线性!非线性!** 逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合; 离散特征的增加和减少都很容易,易于模型的快速迭代; 171 | 2. **速度快!速度快!速度快!** 稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展; 172 | 3. **鲁棒性!鲁棒性!鲁棒性!** 离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰; 173 | 4. **方便交叉与特征组合**:离散化后可以进行特征交叉,由M+N个变量变为M\*N个变量,进一步引入非线性,提升表达能力; 174 | 5. **稳定性**:特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问; 175 | 6. **简化模型**:特征离散化以后,起到了简化了逻辑回归模型的作用,降低了模型过拟合的风险。 176 | 177 | #### (5)目标函数中增大L1正则化会怎么样? 178 | 179 | 所有的参数w都会变成0。 180 | 181 | ## 3.一些题目 182 | 183 | #### (1)LR是不是凸优化问题,如何判断LR达到最优值 184 | 185 | 逻辑回归(Logistic Regression,简称LR)是一个用于解决二分类或多分类问题的经典算法。在逻辑回归中,使用一个sigmoid函数(或softmax函数在多分类情况下)来预测事件发生的概率,并通过极大似然估计来拟合模型参数。为了最小化误差,逻辑回归的目标函数通常是一个对数似然函数的负数,这样的目标函数在某些情况下是凸函数。 186 | 187 | 对于二分类问题,逻辑回归的目标函数(损失函数)可以表示为: 188 | 189 | $$ 190 | [ L(\theta) = -\sum_{i=1}^{n} [y_i \log(h_\theta(x_i)) + (1 - y_i) \log(1 - h_\theta(x_i))] ] 191 | $$ 192 | 193 | 其中 $h_\theta(x) = \frac{1}{1 + e^{-\theta^Tx}}$ 是sigmoid函数,$y_i \in \{-1, 1\}$ 是标签,$\theta$ 是模型参数。 194 | 195 | 通过计算目标函数的二阶导数,**可以发现该函数是凸函数**。这意味着逻辑回归的损失函数在定义域内具有良好的性质,即任何局部最小值都是全局最小值。 196 | 197 | 逻辑回归作为一种凸优化问题,其目标是最小化损失函数。由于损失函数是凸函数,任何找到的局部最小值都是全局最小值。然而,逻辑回归并没有解析解,这意味着我们不能直接计算出参数$\theta$ 的确切值来达到全局最小值。因此,通常使用迭代优化算法,如梯度下降(Gradient Descent)、牛顿法(Newton's Method)或其他优化方法来逼近这个最小值。 198 | 199 | #### (2)LR,SVM, xgboost如何防止过拟合 200 | 201 | - LR一般采用L1和L2正则化(权重衰减); 202 | - **加入软间隔**:SVM引入了松弛变量,引入松弛变量使SVM能够容忍异常点的存在,很好的缓解了过拟合,SVM的最小化$||w||$本质上是要最大化间隔,但同时也是一种**正则化方法**,可以看作是对模型的结构约束,这样可以筛选掉一部分w很大的模型,削减假设空间,控制求解的模型是我们希望的,从而缓解过拟合。 203 | - XGBT可以控制树的深度、最大叶子结点数目、列采样等方法; 204 | 205 | #### (3)LR和树模型,离散特征和连续特征怎么处理 206 | 207 | **逻辑回归(LR)**:逻辑回归通常用于解决二分类或多分类问题,在处理特征时,它**倾向于使用离散化或转换后的特征**。 208 | 209 | - **连续特征**: 210 | - **离散化**:将连续特征转换为一系列的0、1特征,从而增强模型的非线性能力,使得逻辑回归能够更好地拟合数据。 211 | - **归一化/标准化**:如果直接使用连续特征而不离散化的话,通常会对特征进行归一化或标准化处理,以确保不同尺度的特征不会影响模型的学习过程。 212 | - **离散特征**: 213 | - **独热编码(One-Hot Encoding)**:将类别特征转换为多个二元特征,每个类别对应一个特征。 214 | - **标签编码(Label Encoding)**:有时也可以使用标签编码,但这通常适用于类别数目较少的情况,且需要注意避免引入不必要的顺序关系。 215 | - **嵌入编码(Embedding Encoding)**:对于高维的离散特征,可以使用嵌入编码将高维特征映射到较低维度的空间。 216 | - **目标编码(Target Encoding)**:对于某些场景,可以使用目标编码,这是一种基于目标变量的概率编码方法。 217 | 218 | **树模型** 219 | 220 | - **连续特征** 221 | - **不需要离散化**:树模型可以直接使用连续特征,因为它通过寻找最佳分割点来进行分裂,从而不需要像逻辑回归那样进行离散化处理。 222 | - **缩放处理**:尽管树模型对特征缩放不敏感,但在某些情况下,如特征重要性分析时,进行缩放处理可能会更有帮助。 223 | - **离散特征** 224 | - **不需要独热编码**:树模型可以直接处理离散特征,它会在内部自动寻找最佳的分裂点。 225 | - **标签编码**:有时也可以直接使用标签编码,尤其是在类别数目不多的情况下。 226 | - **多值离散化**:对于多值离散特征,可以通过构造特征交叉或者使用其他编码方式来增强模型的表达能力。 227 | 228 | 总的来说,逻辑回归倾向于将连续特征离散化,而树模型则不需要这样做。此外,逻辑回归在处理离散特征时往往需要进行编码,而树模型则可以直接处理未经编码的离散特征。 229 | 230 | #### (4)线性回归可以求闭式解,逻辑回归可以吗,为什么,LR用什么求解参数,为什么要用梯度下降算法 231 | 232 | - 不能:最大似然估计下没有。有近似解,如果是非最大似然估计,那么是可能推导出解析解的,也可以理解为是最大似然估计下的近似解。 233 | - 因为他的目标函数是凸函数,存在极小值,所以通过梯度下降法,或者牛顿迭代法都能计算出最优解。 234 | 235 | #### (5)概率和似然的区别 236 | 237 | 在数理统计中,两个术语则有不同的意思。“概率”描述了给定模型参数后,描述结果的合理性,而不涉及任何观察到的数据。而“似然”则描述了给定了特定观测值后,描述模型参数是否合理。 238 | 239 | 概率和似然都是指可能性,但在统计学中,概率和似然有截然不同的用法。 240 | 241 | - 概率描述了已知参数时的随机变量的输出结果; 242 | - 似然则用来描述已知随机变量输出结果时,未知参数的可能取值。 243 | 244 | #### (6)最大似然估计和后验概率的区别,分别用LR来推导损失函数的话有什么区别(乘以W的先验概率) 245 | 246 | 最大似然估计(Maximum Likelihood Estimation, MLE)和后验概率(Posterior Probability)是两种不同的概念,它们分别代表了不同的统计推断方法。 247 | 248 | **最大似然估计(MLE):**一种用于估计模型参数的技术,其**核心思想是在给定的观测数据下,寻找使得数据出现概率最大的参数值。** 249 | 250 | - 在数学上,最大似然估计是通过最大化似然函数来完成的。似然函数是基于已知数据,表达不同参数值使得数据出现的可能性的函数。如果模型参数记为 $\theta$ ,并且有一组观测数据$D$ ,那么最大似然估计的目标就是找到参数 $\theta$ ,使得似然函数 $L(\theta|D) = P(D|\theta) $达到最大。 251 | - 在逻辑回归(Logistic Regression, LR)中,损失函数通常是交叉熵损失(Cross Entropy Loss),它等价于对数似然函数的负值。即,最小化损失函数,实际上是在最大化对数似然函数。对于一组独立同分布(i.i.d.)的数据点,损失函数可以写成:$L(\theta) = -\sum_{i=1}^{n} \left[y_i \ln(P(y_i=1|\mathbf{x}_i,\theta)) + (1-y_i) \ln(1-P(y_i=1|\mathbf{x}_i,\theta))\right] $ 252 | - 其中 $P(y_i=1|\mathbf{x}_i,\theta)$ 是给定输入 $\mathbf{x}_i$ 和参数 $\theta$ 时,输出 $y_i=1$ 的概率。 253 | 254 | **后验概率**:是贝叶斯统计中的概念 **,指的是在给定观测数据后,模型参数的真实值的概率分布。** 后验概率通过贝叶斯公式来计算,它将先验概率(Prior Probability)与似然函数相结合。在贝叶斯框架下,参数被视为随机变量,具有某种先验分布。后验概率可以写作:$P(\theta|D) = \frac{P(D|\theta)P(\theta)}{P(D)}$ 255 | 256 | - 其中 $P(\theta)$ 是参数的先验概率, $P(D)$ 是边缘似然(Marginal Likelihood),它是一个归一化常数,确保后验概率是一个有效的概率分布。 257 | -------------------------------------------------------------------------------- /docs/ml/3.SVM.md: -------------------------------------------------------------------------------- 1 | # 3.SVM 2 | 3 | > 不准确的说,SVM它本质上即是一个分类方法,用 $w^T+b$ 定义分类函数,于是求w、b,为寻最大间隔,引出$1/2||w||^2$,继而引入拉格朗日因子,化为对拉格朗日乘子`a`的求解(求解过程中会涉及到一系列最优化或凸二次规划等问题),如此,求w\.b与求a等价,而a的求解可以用一种快速学习算法SMO,至于核函数,是为处理非线性情况,若直接映射到高维计算恐维度爆炸,故在低维计算,等效高维表现。 4 | 5 | ## 1.理解SVM 6 | 7 | 支持向量机,因其英文名为support vector machine,故一般简称SVM,通俗来讲,它是**一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解**。 8 | 9 | **线性分类器**:给定一些数据点,它们分别属于两个不同的类,现在要找到一个线性分类器把这些数据分成两类。如果用`x`表示数据点,用`y`表示类别(`y`可以取`1`或者`0`,分别代表两个不同的类),一个线性分类器的学习目标便是要在n维的数据空间中找到一个超平面(hyper plane),这个超平面的方程可以表示为( $w_T$中的T代表转置):$w^{T} x+b=0$ 10 | 11 | 这个超平面可以用分类函数 $f(x)=w^{T} x+b$表示,当f(x)等于0的时候,$x$便是位于超平面上的点,而$f(x)$大于0的点对应$y=1$的数据点,$f(x)$小于0的点对应 $y=-1$ 的点,如下图所示: 12 | 13 | ![](image/image_mlePzMQoOV.png) 14 | 15 | ### 1.1 函数间隔与几何间隔 16 | 17 | #### 函数间隔 18 | 19 | 在超平面$w_x+b=0$确定的情况下,$|w_x+b|$能够表示点$x$到距离超平面的远近,而通过观察$w_x+b$的符号与类标记$y$的符号是否一致可判断分类是否正确,所以,可以用 $y(w*x+b)$的正负性来判定或表示分类的正确性。于此,便引出了**函数间隔**(functional margin)的概念。 20 | 21 | 函数间隔公式:$\gamma=y\left(w^{T} x+b\right)=y f(x)$ 22 | 23 | 而超平面$(w,b)$关于数据集`T`中所有样本点($x_i$,$y_i$)的函数间隔最小值(其中,$x$是特征,$y$是结果标签,$i$表示第i个样本),便为超平面$(w, b)$关于训练数据集`T`的函数间隔: 24 | 25 | $$ 26 | \gamma=\min \gamma i(i=1, \ldots n) 27 | $$ 28 | 29 | 但这样定义的函数间隔有问题,即如果成比例的改变`w`和`b`(如将它们改成`2w`和`2b`),则函数间隔的值$f(x)$却变成了原来的2倍(虽然此时超平面没有改变),所以只有函数间隔还远远不够。 30 | 31 | #### **几何间隔** 32 | 33 | 事实上,可以对法向量$w$加些约束条件,从而引出真正定义点到超平面的距离--**几何间隔**(geometrical margin)的概念。 34 | 35 | 假定对于一个点 $x$ ,令其垂直投影到超平面上的对应点为 $x_0$,$w$ 是垂直于超平面的一个向量,$\gamma$为样本$x$到超平面的距离,如下图所示: 36 | 37 | ![](image/image_q6_H8kClGx.png) 38 | 39 | 这里我直接给出几何间隔的公式,详细推到请查看博文:[点击进入](https://blog.csdn.net/v_july_v/article/details/7624837 "点击进入") 40 | 41 | $$ 42 | \gamma^{\prime}=\frac{\gamma}{\|w\|} 43 | $$ 44 | 45 | 从上述函数间隔和几何间隔的定义可以看出:几何间隔就是**函数间隔除以**$||w||$,而且函数间隔$y*(wx+b) = y*f(x)$实际上就是$|f(x)|$,只是人为定义的一个间隔度量,而几何间隔|$f(x)|/||w||$才是直观上的点到超平面的距离。 46 | 47 | ### 1.2 最大间隔分类器定义 48 | 49 | 对一个数据点进行分类,当超平面离数据点的“间隔”越大,分类的确信度(confidence)也越大。所以,为了使得分类的确信度尽量高,需要**让所选择的超平面能够最大化这个“间隔”值**。这个间隔就是下图中的Gap的一半。 50 | 51 | ![](image/image_1EAlNZ-b_m.png) 52 | 53 | 通过由前面的分析可知:函数间隔不适合用来最大化间隔值,因为在超平面固定以后,可以等比例地缩放`w`的长度和`b`的值,这样可以使得 $f(x)=w^{T} x+b$的值任意大,亦即函数间隔可以在超平面保持不变的情况下被取得任意大。但几何间隔因为除上了,使得在缩放`w`和`b`的时候几何间隔的值是不会改变的,它只随着超平面的变动而变动,因此,这是更加合适的一个间隔。换言之,这里要找的最大间隔分类超平面中的 **“间隔”指的是几何间隔**。 54 | 55 | 如下图所示,中间的实线便是寻找到的最优超平面(Optimal Hyper Plane),其到两条虚线边界的距离相等,这个距离便是几何间隔,两条虚线间隔边界之间的距离等于2倍几何间隔,而虚线间隔边界上的点则是支持向量。由于这些支持向量刚好在虚线间隔边界上,所以它们满足 $y\left(w_{T} x+b\right)=1$,对于没有不是支持向量,则显然有 $y\left(w_{T} x+b\right)>1$ 56 | 57 | ![](image/image_-wlN4CmaWB.png) 58 | 59 | ### 1.3 最大间隔损失函数Hinge loss 60 | 61 | **SVM 求解使通过建立二次规划原始问题,引入拉格朗日乘子法,然后转换成对偶的形式去求解**,这是一种理论非常充实的解法。这里换一种角度来思考,在机器学习领域,一般的做法是经验风险最小化 (empirical risk minimization,ERM),即构建假设函数(Hypothesis)为输入输出间的映射,然后采用损失函数来衡量模型的优劣。求得使损失最小化的模型即为最优的假设函数,采用不同的损失函数也会得到不同的机器学习算法。SVM采用的就是Hinge Loss,用于“最大间隔(max-margin)”分类。 62 | 63 | $$ 64 | L_{i}=\sum_{j \neq t_{i}} \max \left(0, f\left(x_{i}, W\right)_{j}-\left(f\left(x_{i}, W\right)_{y_{i}}-\triangle\right)\right) 65 | $$ 66 | 67 | - 对于训练集中的第`i`个数据$x_i$ 68 | - 在$W$下会有一个得分结果向量$f(x_i,W)$ 69 | - 第`j`类的得分为我们记作$f(x_i,W)_j$ 70 | 71 | 要理解这个公式,首先先看下面这张图片: 72 | 73 | ![](image/image_VjyUAdnDna.png) 74 | 75 | 1. 在生活中我们都会认为没有威胁的才是最好的,比如拿成绩来说,自己考了第一名99分,而第二名紧随其后98分,那么就会有不安全的感觉,就会认为那家伙随时都有可能超过我。如果第二名是85分,那就会感觉安全多了,第二名需要花费很大的力气才能赶上自己。拿这个例子套到上面这幅图也是一样的。 76 | 2. 上面这幅图delta左边的红点是一个**安全警戒线**,什么意思呢?也就是说**预测错误得分**超过这个安全警戒线就会得到一个惩罚权重,让这个预测错误值退回到安全警戒线以外,这样才能够保证预测正确的结果具有唯一性。 77 | 3. 对应到公式中,$f(x_i,W)_j$就是错误分类的得分。后面一项就是 **`正确得分 - delta = 安全警戒线值`**,两项的差代表的就是惩罚权重,越接近正确得分,权重越大。当错误得分在警戒线以外时,两项相减得到负数,那么损失函数的最大值是0,也就是没有损失。 78 | 4. 一直往复循环训练数据,直到最小化损失函数为止,也就找到了分类超平面。 79 | 80 | ## 2.深入SVM 81 | 82 | ### 2.1 从线性可分到线性不可分 83 | 84 | 接着考虑之前得到的目标函数(`令函数间隔=1`): 85 | 86 | $$ 87 | \max \frac{1}{\|w\|} s.t., y_{i}\left(w^{T} x_{i}+b\right) \geq 1, i=1, \ldots, n 88 | $$ 89 | 90 | **转换为对偶问题**,解释一下什么是对偶问题,对偶问题是实质相同但从不同角度提出不同提法的一对问题。 91 | 92 | 由于求$\frac{1}{\|w\|}$的最大值相当于求$\frac{1}{2}\|w\|^{2}$的最小值,所以上述目标函数等价于(`w`由分母变成分子,从而也有原来的`max`问题变为`min`问题,很明显,两者问题等价): 93 | 94 | $$ 95 | \min \frac{1}{2}\|w\|^{2} s.t. , y_{i}\left(w^{T} x_{i}+b\right) \geq 1, i=1, \ldots, n 96 | $$ 97 | 98 | 因为现在的目标函数是二次的,约束条件是线性的,所以它是一个凸二次规划问题。这个问题可以用现成的QP (Quadratic Programming) 优化包进行求解。一言以蔽之:在一定的约束条件下,目标最优,损失最小。 99 | 100 | 此外,由于这个问题的特殊结构,还可以通过拉格朗日对偶性(Lagrange Duality)变换到对偶变量 (dual variable) 的优化问题,即通过求解与原问题等价的对偶问题(dual problem)得到原始问题的最优解,这就是线性可分条件下支持向量机的对偶算法,这样做的优点在于:**一者对偶问题往往更容易求解;二者可以自然的引入核函数,进而推广到非线性分类问题。** 101 | 102 | ### 2.2 核函数 103 | 104 | 事实上,大部分时候数据并不是线性可分的,这个时候满足这样条件的超平面就根本不存在。在上文中,已经了解到了SVM处理线性可分的情况,那对于非线性的数据SVM咋处理呢?对于非线性的情况,SVM 的处理方法是选择一个\*\*`核函数 κ(⋅,⋅) `\*\*,**通过将数据映射到高维空间,来解决在原始空间中线性不可分的问题**。 105 | 106 | 具体来说,**在线性不可分的情况下,支持向量机首先在低维空间中完成计算,然后通过核函数将输入空间映射到高维特征空间,最终在高维特征空间中构造出最优分离超平面,从而把平面上本身不好分的非线性数据分开。** 如图所示,一堆数据在二维空间无法划分,从而映射到三维空间里划分: 107 | 108 | ![](image/image_PEghHrm7Ih.png) 109 | 110 | ![](image/68747470733a2f2f6a756c796564752d696d672e6f73732d63.gif) 111 | 112 | 通常人们会从一些常用的核函数中选择(根据问题和数据的不同,选择不同的参数,实际上就是得到了不同的核函数),例如:**多项式核、高斯核、线性核。** 113 | 114 | 读者可能还是没明白核函数到底是个什么东西?再简要概括下,即以下三点: 115 | 116 | 1. 实际中,会经常遇到线性不可分的样例,此时,常用做法是把样例特征映射到高维空间中去(映射到高维空间后,相关特征便被分开了,也就达到了分类的目的); 117 | 2. 但进一步,如果凡是遇到线性不可分的样例,一律映射到高维空间,那么这个维度大小是会高到可怕的。那咋办呢? 118 | 3. 此时,核函数就隆重登场了,**核函数的价值在于它虽然也是将特征进行从低维到高维的转换,但核函数绝就绝在它事先在低维上进行计算,而将实质上的分类效果表现在了高维上**,避免了直接在高维空间中的复杂计算。 119 | 120 | **如果数据中出现了离群点outliers,那么就可以使用松弛变量来解决。** 121 | 122 | ### 2.3 总结 123 | 124 | 不准确的说,SVM它本质上即是一个分类方法,用 $w^T+b$ 定义分类函数,于是求w、b,为寻最大间隔,引出$1/2||w||^2$,继而引入拉格朗日因子,化为对拉格朗日乘子a的求解(求解过程中会涉及到一系列最优化或凸二次规划等问题),如此,求w\.b与求a等价,而a的求解可以用一种快速学习算法SMO,至于核函数,是为处理非线性情况,若直接映射到高维计算恐维度爆炸,故在低维计算,等效高维表现。 125 | 126 | ### 2.4 SVM应用 127 | 128 | SVM在很多诸如**文本分类,图像分类,生物序列分析和生物数据挖掘,手写字符识别等领域有很多的应用**,但或许你并没强烈的意识到,SVM可以成功应用的领域远远超出现在已经在开发应用了的领域。 129 | 130 | ## 3.一些问题 131 | 132 | #### (1)LR和SVM的联系与区别 133 | 134 | 相同点 135 | 136 | - 都是线性分类器。本质上都是求一个最佳分类超平面。 137 | - 都是监督学习算法。 138 | - 都是判别模型。判别模型不关心数据是怎么生成的,它只关心信号之间的差别,然后用差别来简单对给定的一个信号进行分类。常见的判别模型有:KNN、SVM、LR,常见的生成模型有:朴素贝叶斯,隐马尔可夫模型。 139 | 140 | 不同点 141 | 142 | - LR是参数模型,SVM是非参数模型,linear和rbf则是针对数据线性可分和不可分的区别; 143 | - 从目标函数来看,区别在于逻辑回归采用的是logistical loss,SVM采用的是hinge loss,这两个损失函数的目的都是增加对分类影响较大的数据点的权重,减少与分类关系较小的数据点的权重。 144 | - SVM的处理方法是只考虑support vectors,也就是和分类最相关的少数点,去学习分类器。而逻辑回归通过非线性映射,大大减小了离分类平面较远的点的权重,相对提升了与分类最相关的数据点的权重。 145 | - 逻辑回归相对来说模型更简单,好理解,特别是大规模线性分类时比较方便。而SVM的理解和优化相对来说复杂一些,SVM转化为对偶问题后,分类只需要计算与少数几个支持向量的距离,这个在进行复杂核函数计算时优势很明显,能够大大简化模型和计算。 146 | - logic 能做的 svm能做,但可能在准确率上有问题,svm能做的logic有的做不了。 147 | 148 | #### (2)线性分类器与非线性分类器的区别以及优劣 149 | 150 | 线性和非线性是针对模型参数和输入特征来讲的;比如输入`x`,模型$y=ax+ax^2$ 那么就是非线性模型,如果输入是$x$和$X^2$则模型是线性的。 151 | 152 | - **线性分类器可解释性好,计算复杂度较低,不足之处是模型的拟合效果相对弱些**。LR,贝叶斯分类,单层感知机、线性回归 153 | - **非线性分类器效果拟合能力较强,不足之处是数据量不足容易过拟合、计算复杂度高、可解释性不好**。决策树、RF、GBDT、多层感知机 154 | 155 | **SVM两种都有(看线性核还是高斯核)** 156 | 157 | #### (3)是否存在一组参数使SVM训练误差为0? 158 | 159 | 答:存在 160 | 161 | #### (4)训练误差为0的SVM分类器一定存在吗? 162 | 163 | 答:一定存在 164 | 165 | #### (5)加入松弛变量的SVM的训练误差可以为0吗? 166 | 167 | 答:使用SMO算法训练的线性分类器并不一定能得到训练误差为0的模型。这是由 于我们的优化目标改变了,并不再是使训练误差最小。 168 | 169 | #### (6)**带核的SVM为什么能分类非线性问题?** 170 | 171 | 答:核函数的本质是两个函数的內积,通过核函数将其隐射到高维空间,在高维空间非线性问题转化为线性问题, SVM得到超平面是高维空间的线性分类平面。其分类结果也视为低维空间的非线性分类结果, 因而带核的SVM就能分类非线性问题。 172 | 173 | #### (7)**如何选择核函数?** 174 | 175 | - 如果特征的数量大到和样本数量差不多,则选用LR或者线性核的SVM; 176 | - 如果特征的数量小,样本的数量正常,则选用SVM+高斯核函数; 177 | - 如果特征的数量小,而样本的数量很大,则需要手工添加一些特征从而变成第一种情况。 178 | -------------------------------------------------------------------------------- /docs/ml/4.EM & 聚类.md: -------------------------------------------------------------------------------- 1 | # 4.EM & 聚类 2 | 3 | ## 1.EM算法 4 | 5 | 最大期望算法(Expectation-maximization algorithm,又译为期望最大化算法),是在概率模型中寻找参数最大似然估计或者最大后验估计的算法,其中概率模型依赖于无法观测的隐性变量。 6 | 7 | 最大期望算法经过两个步骤交替进行计算, 8 | 9 | - **第一步**是计算期望(E),**利用对隐藏变量的现有估计值,计算其最大似然估计值**; 10 | - **第二步**是最大化(M),**最大化在E步上求得的最大似然值来计算参数的值**。 11 | - M步上找到的参数估计值被用于下一个E步计算中,这个过程不断交替进行。 12 | 13 | 极大似然估计用一句话概括就是:知道结果,反推条件$θ$。 14 | 15 | ### 1.1 似然函数 16 | 17 | 在数理统计学中,**似然函数**是一种关于统计模型中的参数的函数,表示模型参数中的似然性。“似然性”与“或然性”或“概率”意思相近,都是指某种事件发生的可能性。**而极大似然就相当于最大可能的意思****。** ​ 18 | 19 | **多数情况下是根据已知条件来推算结果,而最大似然估计是已经知道了结果,然后寻求使该结果出现的可能性最大的条件,以此作为估计值。** 20 | 21 | ### 1.2 极大似然函数的求解步骤 22 | 23 | 假定要从10万个人当中抽取100个人来做身高统计,那么抽到这100个人的概率就是(概率连乘): 24 | 25 | $$ 26 | L(\theta)=L\left(x_{1}, \ldots, x_{n} \mid \theta\right)=\prod_{i=1}^{n} p\left(x_{i} \mid \theta\right), \theta \in \ominus 27 | $$ 28 | 29 | 现在要求的就是这个 $\theta$值,也就是使得 $L(\theta)$ 的概率最大化,那么这时的参数 $\theta$ 就是所求。 30 | 31 | 为了便于分析,可以定义对数似然函数,将其变成连加的形式: 32 | 33 | $$ 34 | H(\theta)=\ln L(\theta)=\ln \prod_{i=1}^{n} p\left(x_{i} \mid \theta\right)=\sum_{i=1}^{n} \ln p\left(x_{i} \mid \theta\right) 35 | $$ 36 | 37 | 对于求一个函数的极值,最直接的设想是求导,然后让导数为0,那么解这个方程得到的$θ$就是了(当然,前提是函数$L(θ)$连续可微)。但,如果θ是包含多个参数的向量那怎么处理呢?当然是求$L(θ)$对所有参数的偏导数,也就是梯度了,从而`n`个未知的参数,就有`n`个方程,方程组的解就是似然函数的极值点了,最终得到这`n`个参数的值。 38 | 39 | 求极大似然函数估计值的一般步骤: 40 | 41 | 1. 写出似然函数; 42 | 2. 对似然函数取对数,并整理; 43 | 3. 求导数,令导数为0,得到似然方程; 44 | 4. 解似然方程,得到的参数即为所求; 45 | 46 | ### 1.3 EM算法求解步骤 47 | 48 | 1. 随机初始化分布参数 $\theta$ 49 | 2. E步:求Q函数,对于每一个`i`,计算根据上一次迭代的模型参数来计算出隐型变量的后验概率(其实就是隐形变量的期望),来作为隐藏变量的现估计值: 50 | $$ 51 | Q_{i}\left(z^{(i)}\right)=p\left(z^{(i)} \mid x^{(i)} ; \theta\right) 52 | $$ 53 | 3. M步:求使Q函数获得极大时的参数取值,将似然函数最大或获得最新的参数值: 54 | $$ 55 | \theta=\operatorname{argmax} \sum_{i} \sum_{z^{(i)}} Q_{i}\left(z^{(i)}\right) \log \frac{p\left(x^{(i)}, z^{(i)} ; \theta\right)}{Q_{i}\left(z^{(i)}\right)} 56 | $$ 57 | 4. 然后循环重复2、3步骤直到收敛 58 | 59 | ### 1.4 使用EM算法的模型 60 | 61 | 用EM算法求解的模型一般有GMM或者协同过滤,k-means其实也属于EM。EM算法一定会收敛,但是可能收敛到局部最优。由于求和的项数将随着隐变量的数目指数上升,会给梯度计算带来麻烦。 62 | 63 | ## 2.k-means算法 64 | 65 | 什么是聚类算法?聚类是一种机器学习技术,它涉及到数据点的分组。给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组。理论上,同一组中的数据点应该具有相似的属性和/或特征,而不同组中的数据点应该具有高度不同的属性和/或特征。**聚类是一种无监督学习的方法**,是许多领域中常用的统计数据分析技术。 66 | 67 | ### 2.1 算法过程 68 | 69 | K-means是最普及的聚类算法,算法接受一个未标记的数据集,然后将数据聚类成不同的组。 70 | 71 | K-means是一个迭代算法,假设想要将数据聚类成 `n` 个组,其方法为: 72 | 73 | - 首先选择`𝐾`个随机的点,称为**聚类中心(cluster centroids)**; 74 | - 对于数据集中的每一个数据,按照距离`𝐾`个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类。 75 | - 计算每一个组的平均值,将该组所关联的中心点移动到平均值的位置。 76 | - 重复步骤,直至中心点不再变化。 77 | 78 | 用$u^{1}, u^{2}, \ldots, u^{k}$来表示聚类中心,用$𝑐(1),𝑐(2),...,𝑐(𝑚)$来存储与第`𝑖`个实例数据最近的聚类中心的索引,K-means算法的伪代码如下: 79 | 80 | ```pascal 81 | Repeat { 82 | for i = 1 to m 83 | c(i) := index (form 1 to K) of cluster centroid closest to x(i) 84 | for k = 1 to K 85 | μk := average (mean) of points assigned to cluster k 86 | } 87 | ``` 88 | 89 | 算法分为两个步骤,第一个 for 循环是赋值步骤,即:对于每一个样例`𝑖`,计算其应该属于的类。第二个 for 循环是聚类中心的移动,即:对于每一个类`𝐾`,重新计算该类的质心。 90 | 91 | K-means算法也可以很便利地用于将数据分为许多不同组,即使在没有非常明显区分的组群的情况下也可以。下图所示的数据集包含身高和体重两项特征构成的,利用 K-均值算法将数据分为三类,用于帮助确定将要生产的 T-恤衫的三种尺寸。 92 | 93 | ![](image/image_sSoyfDDeXh.png) 94 | 95 | ### 2.2 损失函数 96 | 97 | K-均值最小化问题,是要**最小化所有的数据点与其所关联的聚类中心点之间的距离之和**,因此 K-均值的代价函数(又称畸变函数 Distortion function)为: 98 | 99 | $$ 100 | J\left(c^{(1)}, c^{(2)}, \ldots, c^{(m)}, u_{1}, \ldots, u_{k}\right)=\frac{1}{m} \sum_{i=1}^{m}\left\|X^{(1)}-u_{c^{(i)}}\right\|^{2} 101 | $$ 102 | 103 | 其中 $u_c^{(i)}$代表与$x^{(i)}$最近的聚类中心点。 我们的的优化目标便是找出使得代价函数最小的 $c^{(1)},c^{(2)},...,c^{(m)}$和$u_1,u_2,...,u_k$ 104 | 105 | ### 2.3 k值的选择 106 | 107 | 在运行 K-均值算法的之前,我们首先要随机初始化所有的聚类中心点,下面介绍怎样做: 108 | 109 | 1. 我们应该选择`𝐾 < 𝑚`,即聚类中心点的个数要小于所有训练集实例的数量。 110 | 2. 随机选择`𝐾`个训练实例,然后令𝐾个聚类中心分别与这`𝐾`个训练实例相等K-均值的一个问题在于,它有可能会停留在一个局部最小值处,而这取决于初始化的情况。 111 | 112 | 为了解决这个问题,我们通常需要多次运行 K-均值算法,每一次都重新进行随机初始化,最后再比较多次运行 K-均值的结果,选择代价函数最小的结果。这种方法在`𝐾`较小的时候(2--10)还是可行的,**但是如果**\*\*`𝐾`\*\***较大,这么做也可能不会有明显地改善。** 113 | 114 | ### 2.4 KNN和K-means区别 115 | 116 | K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。 117 | 118 | | KNN | K-Means | 119 | | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | 120 | | 1.KNN是分类算法 2.属于监督学习 3.训练数据集是带label的数据 | 1.K-Means是聚类算法 2.属于非监督学习 3.训练数据集是无label的数据,是杂乱无章的,经过聚类后变得有序,先无序,后有序。 | 121 | | 没有明显的前期训练过程,属于memory based learning | 有明显的前期训练过程 | 122 | | K的含义:一个样本x,对它进行分类,就从训练数据集中,在x附近找离它最近的K个数据点,这K个数据点,类别c占的个数最多,就把x的label设为c。 | K的含义:K是人工固定好的数字,假设数据集合可以分为K个蔟,那么就利用训练数据来训练出这K个分类。 | 123 | 124 | **相似点** 125 | 126 | 都包含这样的过程,给定一个点,在数据集中找离它最近的点。即二者都用到了NN(Nears Neighbor)算法思想。 127 | 128 | ### 2.5 K-Means优缺点及改进 129 | 130 | k-means:在大数据的条件下,会耗费大量的时间和内存。 优化k-means的建议: 131 | 132 | 1. 减少聚类的数目K。因为,每个样本都要跟类中心计算距离。 133 | 2. 减少样本的特征维度。比如说,通过PCA等进行降维。 134 | 3. 考察其他的聚类算法,通过选取toy数据,去测试不同聚类算法的性能。 135 | 4. hadoop集群,K-means算法是很容易进行并行计算的。 136 | 5. 算法可能找到局部最优的聚类,而不是全局最优的聚类。使用改进的二分k-means算法。 137 | 138 | 二分k-means算法:首先将整个数据集看成一个簇,然后进行一次k-means(k=2)算法将该簇一分为二,并计算每个簇的误差平方和,选择平方和最大的簇迭代上述过程再次一分为二,直至簇数达到用户指定的k为止,此时可以达到的全局最优。 139 | 140 | ## 3.高斯混合模型(GMM) 141 | 142 | ### 3.1 GMM思想 143 | 144 | 高斯混合模型(Gaussian Mixed Model,GMM)也是一种常见的聚类算法,与K均值算法类似,同样使用了EM算法进行迭代计算。高斯混合模型假设每个簇的数据都是符合高斯分布(又叫正态分布)的,当前**数据呈现的分布就是各个簇的高斯分布叠加在一起的结果。** 145 | 146 | > 第一张图是一个数据分布的样例,如果只用一个高斯分布来拟合图中的数据,图 中所示的椭圆即为高斯分布的二倍标准差所对应的椭圆。直观来说,图中的数据 明显分为两簇,因此只用一个高斯分布来拟和是不太合理的,需要推广到用多个 高斯分布的叠加来对数据进行拟合。 147 | 148 | > 第二张图是用两个高斯分布的叠加来拟合得到的结果。**这就引出了高斯混合模型,即用多个高斯分布函数的线形组合来对数据分布进行拟合。** 理论上,高斯混合模型可以拟合出任意类型的分布。 149 | 150 | ![](image/image_Cm_Ww_BWzc.png) 151 | 152 | ![](image/image_ZLJyowbArj.png) 153 | 154 | 高斯混合模型的核心思想是,**假设数据可以看作从多个高斯分布中生成出来的**。在该假设下,每个单独的分模型都是标准高斯模型,其均值 $u_i$ 和方差 $\sum_{i}$是待估计的参数。此外,每个分模型都还有一个参数 $\pi_i$,可以理解为权重或生成数据的概 率。高斯混合模型的公式为: 155 | 156 | $$ 157 | p(x)=\sum_{i=1}^{k} \pi_{i} N\left(x \mid u_{i}, \sum_{i}\right) 158 | $$ 159 | 160 | 通常并不能直接得到高斯混合模型的参数,而是观察到了一系列数据点,给出一个类别的数量`K`后,希望求得最佳的`K`个高斯分模型。因此,高斯混合模型的计算,便成了最佳的均值$μ$,方差$Σ$、权重$π$的寻找,这类问题通常通过最大似然估计来求解。遗憾的是,此问题中直接使用最大似然估计,得到的是一 个复杂的非凸函数,目标函数是和的对数,难以展开和对其求偏导。 161 | 162 | \*\*在这种情况下,可以用EM算法。 \*\*EM算法是在最大化目标函数时,先固定一个变量使整体函数变为凸优化函数,求导得到最值,然后利用最优参数更新被固定的变量,进入下一个循环。具体到高 斯混合模型的求解,EM算法的迭代过程如下。 163 | 164 | 首先,初始随机选择各参数的值。然后,重复下述两步,直到收敛。 165 | 166 | - E步骤。根据当前的参数,计算每个点由某个分模型生成的概率。 167 | - M步骤。使用E步骤估计出的概率,来改进每个分模型的均值,方差和权重。 168 | 169 | > 高斯混合模型是一个生成式模型。可以这样理解数据的生成过程,假设一个最简单的情况,即只有两个一维标准高斯分布的分模型$N(0,1)$和$N(5,1)$,其权重分别为0.7和0.3。那么,在生成第一个数据点时,先按照权重的比例,随机选择一个分布,比如选择第一个高斯分布,接着从$N(0,1)$中生成一个点,如−0.5,便是第一个数据点。在生成第二个数据点时,随机选择到第二个高斯分布$N(5,1)$,生成了第二个点4.7。如此循环执行,便生成出了所有的数据点。 170 | 171 | 也就是说,我们并不知道最佳的K个高斯分布的各自3个参数,也不知道每个 数据点究竟是哪个高斯分布生成的。所以每次循环时,**先固定当前的高斯分布不 变,获得每个数据点由各个高斯分布生成的概率。然后固定该生成概率不变,根据数据点和生成概率,获得一个组更佳的高斯分布。** 循环往复,直到参数的不再变化,或者变化非常小时,便得到了比较合理的一组高斯分布。 172 | 173 | ### 3.2 GMM与K-Means相比 174 | 175 | 高斯混合模型与K均值算法的相同点是: 176 | 177 | - 它们都是可用于聚类的算法; 178 | - 都需要 指定`K`值; 179 | - 都是使用EM算法来求解; 180 | - 都往往只能收敛于局部最优。 181 | 182 | 而它相比于K 均值算法的优点是,可以给出一个样本属于某类的概率是多少;不仅仅可以用于聚类,还可以用于概率密度的估计;并且可以用于生成新的样本点。 183 | 184 | ## 4.聚类算法的评估 185 | 186 | 由于数据以及需求的多样性,没有一种算法能够适用于所有的数据类型、数据簇或应用场景,似乎每种情况都可能需要一种不同的评估方法或度量标准。例 如,K均值聚类可以用误差平方和来评估,但是基于密度的数据簇可能不是球形, 误差平方和则会失效。在许多情况下,判断聚类算法结果的好坏强烈依赖于主观 解释。尽管如此,聚类算法的评估还是必需的,它是聚类分析中十分重要的部分之一。 187 | 188 | 聚类评估的任务是估计在数据集上进行聚类的可行性,以及聚类方法产生结 果的质量。这一过程又分为三个子任务。 189 | 190 | 1. **估计聚类趋势****。** 这一步骤是检测数据分布中是否存在非随机的簇结构。如果数据是基本随机 的,那么聚类的结果也是毫无意义的。我们可以观察聚类误差是否随聚类类别数 量的增加而单调变化,如果数据是基本随机的,即不存在非随机簇结构,那么聚 类误差随聚类类别数量增加而变化的幅度应该较不显著,并且也找不到一个合适 的K对应数据的真实簇数。 191 | 2. **判定数据簇数****。** 确定聚类趋势之后,我们需要找到与真实数据分布最为吻合的簇数,据此判定聚类结果的质量。数据簇数的判定方法有很多,例如手肘法和Gap Statistic方 法。需要说明的是,用于评估的最佳数据簇数可能与程序输出的簇数是不同的。 例如,有些聚类算法可以自动地确定数据的簇数,但可能与我们通过其他方法确 定的最优数据簇数有所差别。 192 | 3. **测定聚类质量****。** 在无监督的情况下,我们可以通过考察簇的分离情况和簇的紧 凑情况来评估聚类的效果。定义评估指标可以展现面试者实际解决和分析问题的 能力。事实上测量指标可以有很多种,以下列出了几种常用的度量指标,更多的 指标可以阅读相关文献。 193 | 194 | 轮廓系数、均方根标准偏差、R方(R-Square)、改进的HubertΓ统计。 195 | 196 | ## 5.一些问题 197 | 198 | #### (1)介绍kmeans,与其他聚类算法的对比 199 | 200 | - K-means 是我们最常用的基于欧式距离的聚类算法,其认为两个目标的距离越近,相似度越大; 201 | - 所以 K-means 的算法步骤为: 202 | 1. 选择初始化的 k 个样本作为初始聚类中心 $a=a_{1}, a_{2}, \ldots a_{k}$; 203 | 2. 针对数据集中每个样本 计算它到 k 个聚类中心的距离并将其分到距离最小的聚类中心所对应的类中 $x_i$; 204 | 3. 针对每个类别,重新计算它的聚类中心 $a_{j}=\frac{1}{\left|c_{i}\right|} \sum_{x \in c_{i}} x$(即属于该类的所有样本的质心); 205 | 4. 重复上面 2 3 两步操作,直到达到某个中止条件(迭代次数、最小误差变化等)。 206 | - 优点: 207 | - 容易理解,聚类效果不错,虽然是局部最优, 但往往局部最优就够了; 208 | - 处理大数据集的时候,该算法可以保证较好的伸缩性; 209 | - 当簇近似高斯分布的时候,效果非常不错; 210 | - 算法复杂度低。 211 | - 缺点: 212 | - K 值需要人为设定,不同 K 值得到的结果不一样; 213 | - 对初始的簇中心敏感,不同选取方式会得到不同结果; 214 | - 对异常值敏感; 215 | - 样本只能归为一类,不适合多分类任务; 216 | - 不适合太离散的分类、样本类别不平衡的分类、非凸形状的分类。 217 | 218 | #### (2)讲讲Kmeans、EM算法 219 | 220 | K-means算法和EM算法都是在无监督学习中广泛应用的聚类算法,但它们各自有着不同的特点和适用场景。 221 | 222 | ##### **K-means算法** 223 | 224 | K-means是一种简单而流行的聚类算法,它试图将数据划分为K个聚类,使得每个聚类内部数据点之间的平方误差最小。K-means算法采用迭代方法,通过计算样本点到聚类中心的距离来更新聚类。具体步骤包括: 225 | 226 | 1. **初始化**:选择K个初始聚类中心。 227 | 2. **分配**:计算每个数据点与各个聚类中心的距离,并将每个数据点分配给最近的聚类中心。 228 | 3. **更新**:根据每个聚类中的所有数据点,重新计算聚类中心(通常是聚类中所有点的均值)。 229 | 4. **迭代**:重复上述步骤2和3,直到聚类中心不再发生变化或变化小于某个阈值为止。 230 | 231 | K-means算法的优点在于其简单易实现,并且对于大规模数据集来说效率较高。然而,它也有一些缺点,如需要预先知道聚类数目K,对初始值敏感,以及对于非球形的聚类形状表现不佳。 232 | 233 | ##### **EM算法** 234 | 235 | EM算法,即期望最大化(Expectation-Maximization)算法,是一种迭代优化策略,它主要用于含有隐变量的概率模型参数估计。EM算法在每次迭代中包含两个步骤:E步(期望步)和M步(最大化步): 236 | 237 | - **E步**:在当前参数估计下,计算隐变量的后验概率分布。 238 | - **M步**:基于E步得到的后验概率分布,通过极大化对数似然函数来更新模型参数。 239 | 240 | EM算法广泛应用于处理含有隐变量的模型,如高斯混合模型(GMM)、隐马尔可夫模型(HMM)等。EM算法的优点在于能够处理隐含的数据结构,使得模型更加灵活和强大。然而,EM算法同样存在一些局限性,比如它可能会收敛到局部最优解,而不是全局最优解。 241 | 242 | ##### **K-means与EM算法的联系与区别** 243 | 244 | K-means算法可以视为EM算法的一个特例。当我们考虑一个高斯混合模型(GMM),其中每个分量的协方差矩阵均为常数时,K-means可以被看作是GMM的EM解法的一个特例。在这个意义上,K-means进行的是“硬分配”(hard assignment),即每个数据点仅属于一个聚类;而GMM的EM解法则基于后验概率分布,对数据点进行“软分配”(soft assignment),即每个高斯模型对数据聚类都有不同程度的贡献。 245 | 246 | 总之,K-means适用于数据大致呈球形分布并且聚类数目已知的情况,而EM算法则更适合处理含有隐变量的复杂模型,特别是当数据分布不是简单的球形时。 247 | 248 | #### (3)无监督学习,半监督学习,有监督学习的区别 249 | 250 | - **有监督学习** 需要大量带有标签的数据,目标是学习输入与输出之间的映射关系。 251 | - **无监督学习** 不需要标签,目标是发现数据中的结构或模式。 252 | - **半监督学习** 则是利用标记数据和未标记数据的组合来增强模型的学习能力,特别是在标记数据稀缺时尤为有用。 253 | -------------------------------------------------------------------------------- /docs/ml/README.md: -------------------------------------------------------------------------------- 1 | # 机器学习 2 | 3 | ## 简介 4 | 5 | 主要来自于到处收集的机器学习容易混淆的基础知识 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/ml/image/68747470733a2f2f6a756c796564752d696d672e6f73732d63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/68747470733a2f2f6a756c796564752d696d672e6f73732d63.gif -------------------------------------------------------------------------------- /docs/ml/image/image_-wlN4CmaWB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_-wlN4CmaWB.png -------------------------------------------------------------------------------- /docs/ml/image/image_1EAlNZ-b_m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_1EAlNZ-b_m.png -------------------------------------------------------------------------------- /docs/ml/image/image_8GgBb12BYf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_8GgBb12BYf.png -------------------------------------------------------------------------------- /docs/ml/image/image_Cm_Ww_BWzc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_Cm_Ww_BWzc.png -------------------------------------------------------------------------------- /docs/ml/image/image_ELXaGaECoB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_ELXaGaECoB.png -------------------------------------------------------------------------------- /docs/ml/image/image_NDV1nnrl2G.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_NDV1nnrl2G.png -------------------------------------------------------------------------------- /docs/ml/image/image_PEghHrm7Ih.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_PEghHrm7Ih.png -------------------------------------------------------------------------------- /docs/ml/image/image_Uyzi-bBIpS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_Uyzi-bBIpS.png -------------------------------------------------------------------------------- /docs/ml/image/image_VjyUAdnDna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_VjyUAdnDna.png -------------------------------------------------------------------------------- /docs/ml/image/image_ZLJyowbArj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_ZLJyowbArj.png -------------------------------------------------------------------------------- /docs/ml/image/image_mlePzMQoOV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_mlePzMQoOV.png -------------------------------------------------------------------------------- /docs/ml/image/image_q6_H8kClGx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_q6_H8kClGx.png -------------------------------------------------------------------------------- /docs/ml/image/image_sSoyfDDeXh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/ml/image/image_sSoyfDDeXh.png -------------------------------------------------------------------------------- /docs/nlp/README.md: -------------------------------------------------------------------------------- 1 | # 自然语言处理 2 | 3 | ## 简介 4 | 5 | 主要来自于到处收集的自然语言处理容易混淆的基础知识 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/rag/image/image_F-9kskhOyU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rag/image/image_F-9kskhOyU.png -------------------------------------------------------------------------------- /docs/rec/1.概要.md: -------------------------------------------------------------------------------- 1 | # 1.概要 2 | 3 | # 1.推荐系统的基本概念 4 | 5 | ## 1.1 小红书推荐系统转化流程 6 | 7 | ![](image/image_5uFd4P-Qlb.png) 8 | 9 | ### (1)**消费指标**:反映用户对推荐是否满意 10 | 11 | - **点击率** = 点击次数 / 曝光次数 :越高,证明推荐越精准 —— 不能仅追求它,不然都是标题党了 12 | - **点赞率 **= 点赞次数 / 点击次数 13 | - **收藏率 **= 收藏次数 / 点击次数 14 | - **转发率** = 转发次数 / 点击次数 15 | - **阅读完成率 **= 滑动到底次数 / 点击次数 × f(笔记长度) 16 | - f:归一化函数,与笔记长度有关,因笔记越长阅读完成率就越低,所以采用归一化 17 | 18 | 这些**都是短期消费指标,不能一味追求**。因为重复推荐相似内容可以提高消费指标,但容易让用户腻歪,进而降低用户活跃度。而尝试提供多样性的内容,可以让用户发现自己新的兴趣点,提高活跃度(但在这个过程中,消费指标可能下降)。反正就是尽量让用户多在平台投入精力 19 | 20 | ### (2)北极星指标:衡量推荐系统好坏,最关键的指标 21 | 22 | 在小红书考虑下面 3 个 23 | 24 | - **用户规模**:日活用户数(DAU)、月活用户数(MAU) 25 | - DAU:每天使用 1 次以上 26 | - MAU:每月使用 1 次以上 27 | - **消费**:人均使用推荐的时长、人均阅读笔记的数量 28 | - **发布**:发布渗透率、人均发布量 29 | 30 | 通常来说,点击率跟时长、阅读数量的涨跌是一致的,若出现不一致情况,以北极星指标为准。例如,把推荐系统的多样性做好,时长增加了,但点击率下降了,这样的策略也是可以上线的。 31 | 32 | 北极星指标 都是线上指标,只能上线了才能获得。 33 | 34 | ### (3)实验流程 35 | 36 | ![](image/image_EI4kbN2TX4.png) 37 | 38 | - **离线实验**:收集历史数据,在历史数据上做训练、测试。算法没有部署到产品中,没有跟用户交互。 39 | - **小流量AB测试**:把算法部署到实际产品中,用户实际跟算法做交互。一般分为两组,实验组和对照组,实验组用新策略,对照组使用旧策略,对比两者的业务指标,看是否优于旧策略。 40 | - **全流量上线**: 41 | 42 | # 2.推荐系统的链路 43 | 44 | **推荐系统目标**:从物品数据库中选取几十个物品,展示给用户。 45 | 46 | ![](image/image__Z0HsNo2I3.png) 47 | 48 | - **召回**:用召回通道,从物品的数据库中快速取回一些数据 49 | - **粗排**:用到规模比较小的机器学习模型给几千篇笔记打分,按照分数做排序和截断,保留分数最高的几百篇笔记 50 | - **精排**:用到大规模深度神经网络,对笔记逐一进行打分;精排的分数反应笔记对用户的兴趣;精排之后可以做截断,也可以不做截断。 51 | - **重排**:根据精排分数和多样性分数做笔记抽样,得到几十篇笔记,把相似内容打散,插入广告和运营内容 52 | 53 | ## 2.1召回 54 | 55 | **召回通道**:协同过滤、双塔模型、关注的作者、等等 56 | 57 | ![](image/image_8vVheB5mBI.png) 58 | 59 | 小红书有几十个召回通道,每个通道返回几十上百篇笔记,将所有召回通道的内容融合后,会去重,并过滤(例如去掉用户不喜欢的作者的笔记,不喜欢的话题) 60 | 61 | ## 2.2排序 62 | 63 | 排序:** \[几千] → 粗排 → \[几百] → 精排 → \[几百] → 重排 → \[几十]** 64 | 65 | ![](image/image_1SZ8p7JSfX.png) 66 | 67 | 用粗排做筛选,再用精排 —— 平衡计算量和准确性 68 | 69 | - 粗排模型小、简单,速度快,快速打分,可以做截断; 70 | - 精排用的模型大,计算量大,打分更可靠; 71 | 72 | 粗排和精排非常相似,唯一区别就是精排模型更大,用的特征更多。 73 | 74 | 模型的输入,包括用户特征、物品特征和统计特征,后续输入神经网络,神经网络会输出点击率、点赞率等(预测值),最后把多个预测值做融合,得到最终的排序分数,决定了这篇笔记是否展示给用户,以及笔记的位置是靠前还是靠后。 75 | 76 | ![](image/image_pE00eutJ6U.png) 77 | 78 | 本来是可以用精排分数排序后直接推荐的,但此时的结果还存在一些不足(重排,例如 多样性) 79 | 80 | ## 2.3重排 81 | 82 | 重排**根据多样性随机抽样(比如MMR、DPP),还要用规则将相似的笔记打散**,还得把广告插进去; 83 | 84 | 多样性抽样依据有:精排分数、多样性。 85 | 86 | **目的**: 87 | 88 | - 接着用规则打散相似笔记,不能把内容过于相似的笔记,排在相邻的位置上,减少一个页面中的同质化内容。 89 | - 插入广告、运营推广内容,根据生态要求调整排序(例如 不能同时出很多美女图片) 90 | 91 | 重排的结果,就是最终展示给用户的物品 92 | 93 | ![](image/image_zMk4F7kDuj.png) 94 | 95 | # 3.A/B 测试 96 | 97 | ## 3.1 A/B 测试举例 98 | 99 | - 召回团队实现了一种 GNN 召回通道,离线实验结果正向 100 | - 下一步是做线上的小流量 A/B 测试,考察新的召回通道对线上指标的影响 101 | - 模型中有一些参数,比如 GNN 的深度取值 $\in\{1,2,3\} $,需要用 A/B 测试选取最优参数;如开三组对比AB测试 102 | 103 | ## 3.2 随机分桶 104 | 105 | 分 b = 10 个桶,每个桶中有 10% 的用户;如果用户的数量足够大,每个组的DAU、留存等指标是相同的。 106 | 107 | 分桶方法: 108 | 109 | - 首先用哈希函数把用户 ID 映射成某个区间内的整数,然后把这些整数均匀随机分成 b 个桶 110 | - 全部 n 位用户,分成 b 个桶,每个桶中有 $\frac{n}{b}$ 位用户 111 | 112 | ![](image/image_M608Z9jh12.png) 113 | 114 | - 计算每个桶的业务指标,比如 DAU、人均使用推荐的时长、点击率、等等 115 | - 如果某个实验组指标显著优于对照组,则说明对应的策略有效,值得推全 116 | 117 | ## 3.3分层实验 118 | 119 | ### (1)目标 120 | 121 | 目标:解决流量不够用的问题 122 | 123 | 信息流产品的公司有很多部门和团队,大家都需要做 A/B 测试 124 | 125 | - 推荐系统(召回、粗排、精排、重排) 126 | - 用户界面 127 | - 广告 128 | 129 | 如果把用户随机分成 10 组,1 组做对照,9 组做实验,那么只能同时做 9 组实验,分组不够用。 130 | 131 | ### (2)**分层实验** 132 | 133 | - 分层实验:召回、粗排、精排、重排、用户界面、广告......(例如 GNN 召回通道属于召回层) 134 | - **同层互斥**:GNN 实验占了召回层的 4 个桶,其他召回实验只能用剩余的 6 个桶;避免一个用户数据被两个召回实验影响。 135 | - **不同层正交**:每一层独立随机对用户做分桶。每一层都可以独立用 100% 的用户做实验 136 | 137 | 参考文献:Tang et al. Overlapping experiment infrastructure: more, better, faster experimentation. In KDD, 2010. 138 | 139 | ### (3)分层实验举例 140 | 141 | - 召回层把用户分成 10 个桶:$\mathcal{U} _1,\mathcal{U} _2,...,\mathcal{U} _{10}$ 142 | - 精排层把用户分成 10 个桶:$\mathcal{V} _1,\mathcal{V} _2,...,\mathcal{V} _{10}$ 143 | - 设系统共有 n 个用户,那么$ |\mathcal{U}_i|=|\mathcal{V}_j | =n/10$ 144 | - 即每个召回桶里的用户数与每个精排桶里的用户数是差不多的 145 | - 召回桶 $\mathcal{U}_i $和召回桶$ \mathcal{U} _j$ 交集为 $\mathcal{U} \cap \mathcal{U} _j= \empty$ 146 | - 召回桶之间互斥,即 2 个召回实验不会同时作用到相同用户上 147 | - 召回桶 $\mathcal{U}_i$ 和精排桶 $\mathcal{V} _j $交集的大小为 $|\mathcal{U}\cap \mathcal{V}_j |=n/100$ 148 | 149 | **即 1 个用户虽然不能同时受 2 个召回实验的影响,但他可以受 1 个召回实验 + 1 个精排实验的影响**。 150 | 151 | ### (4)互斥 vs 正交 152 | 153 | 同层互斥: 154 | 155 | ![](image/image_dNmmm3qJi6.png) 156 | 157 | 不同层正交: 158 | 159 | ![](image/image_xIuiO1kw7v.png) 160 | 161 | 在用户界面的 2 号桶用户,被随机均匀打撒到了召回的 10 个桶中。**通常来说 用户界面实验的效果 和 召回实验的效果 不容易相互增强(或抵消)**,所以允许 1 个用户同时受两层实验的影响 162 | 163 | 如果所有实验都正交,则可以同时做无数组实验 164 | 165 | 必须使用互斥的原因 166 | 167 | - 同类的策略(例如精排模型的两种结构)天然互斥,对于一个用户,只能用其中一种 168 | - 同类的策略(例如添加两条召回通道)效果会相互增强(1+1>2)或相互抵消(1+1<2)。互斥可以避免同类策略相互干扰 169 | - 不同类型的策略(例如添加召回通道、优化粗排模型)通常不会相互干扰(1+1=2),可以作为正交的两层 170 | 171 | ## 3.4 Holdout 机制 172 | 173 | - 每个实验(召回、粗排、精排、重排)独立汇报对业务指标的提升 174 | - 公司考察一个部门(比如推荐系统)在一段时间内对业务指标总体的提升 175 | - Holdout 机制:取 10% 的用户作为 holdout 桶,推荐系统使用剩余 90% 的用户做实验,两者互斥 176 | - 10% holdout 桶 vs 90% 实验桶的 diff(需要归一化)为整个部门的业务指标收益 177 | 178 | ![](image/image_G6g9NEgw8Z.png) 179 | 180 | - holdout 桶里面不加任何新的实验,保持干净以便对照 181 | 182 | ![](image/image_NYHCr0fS8C.png) 183 | 184 | - 每个考核周期结束之后,清除 holdout 桶,让推全实验从 90% 用户扩大到 100% 用户 185 | - 重新随机划分用户,得到 holdout 桶和实验桶,开始下一轮考核周期 186 | - 新的 holdout 桶与实验桶各种业务指标的 diff 接近 0:划分随机均匀 187 | - 随着召回、粗排、精排、重排实验上线和推全,diff 会逐渐扩大 188 | 189 | ## 3.5实验推全 & 反转实验 190 | 191 | ### (1)推全实验 192 | 193 | 假设做重排策略实验,取一个桶作为实验组,一个桶作为对照组,实验影响了20%的用户,观测到正向的业务指标收益,可以推全。 194 | 195 | ![](image/image_egcqBvd27d.png) 196 | 197 | 原来实验关闭;推全时,新开一层,使用90%的用户 198 | 199 | ![](image/image_h_l_P1zRni.png) 200 | 201 | ### (2)反转实验 202 | 203 | - 有的指标(点击、交互)立刻受到新策略影响,有的指标(留存)有滞后性,需要长期观测。 204 | - 实验观测到显著收益后尽快推全新策略。目的是腾出桶供其他实验使用,或需要基于新策略做后续的开发。 205 | - 用反转实验解决上述矛盾,既可以尽快推全,也可以长期观测实验指标。 206 | - **在推全的新层中开一个旧策略的桶,长期观测实验指标** 207 | 208 | ![](image/image_CzBo1a7MrT.png) 209 | 210 | ## 3.6总结 211 | 212 | - **分层实验**:同层互斥(不允许两个实验同时影响一位用户)、不同层正交(实验有重叠的用户)。把容易相互增强(或抵消)的实验放在同一层,让它们的用户互斥 213 | - **Holdout**:保留 10% 的用户,完全不受实验影响,可以考察整个部门对业务指标的贡献 214 | - **实验推全**:新建一个推全层,与其他层正交 215 | - **反转实验**:在新的推全层上,保留一个小的反转桶,使用旧策略。长期观测新旧策略的 diff 216 | 217 | -------------------------------------------------------------------------------- /docs/rec/4.特征交叉.md: -------------------------------------------------------------------------------- 1 | # 4.特征交叉 2 | 3 | # 1.Factorized Machine (FM) 4 | 5 | FM 以前常用,现在用得少了,主要了解一下思想。 6 | 7 | 8 | ## 1.1 线性模型 9 | 10 | - 有d个特征,记作 $\mathbf{x}=\left[x_{1}, \cdots, x_{d}\right]$ 11 | - 线性模型:b为偏移项bias,w为权重参数,p为目标的预估,如果做分类,可以用激活函数 12 | 13 | $$ 14 | p=b+\sum_{i=1}^{d} w_{i} x_{i} 15 | $$ 16 | 17 | - 模型有d+1个参数:$\mathbf{w}=\left[w_{1}, \cdots, w_{d}\right]$和$b$ 18 | - 预测是特征的加权和(只有加,没有乘),即特征之间没有交叉 19 | 20 | ## 1.2 二阶交叉特征 21 | 22 | - 有d个特征,记作$\mathbf{x}=\left[x_{1}, \cdots, x_{d}\right]$ 23 | - 线性模型 + 二阶交叉特征: 24 | 25 | $$ 26 | p^2=b^2+\sum_{i=1}^dw_ix_i+\sum_{i=1}^d\sum_{j=i+1}^du_{ij}x_ix_j 27 | $$ 28 | 29 | - 前两项是线性模型,主要区别在第三项。$u_{ij}x_ix_j$是特征的交叉,其中u为权重; 30 | - 模型有 $O(d^2)$个参数;d较大时,参数数量过多,且容易出现过拟合 。 31 | 32 | 如何减少参数的数量?重点关注交叉权重$u_{ij}$,把所有$u_{ij}$组成权重矩阵U, 33 | 34 | ![](image/image_L0ZpX5japc.png) 35 | 36 | - 使用矩阵$VV^T$来近似矩阵U 37 | - k≪d,是一个超参数 38 | 39 | ![](image/image_zigdAf36nk.png) 40 | 41 | ## 1.3 Factorized Machine (FM) 42 | 43 | $$ 44 | p=b+\sum_{i=1}^{d} w_{i} x_{i}+\sum_{i=1}^{d} \sum_{j=i+1}^{d}\left(\mathbf{v}_{i}^{T} \mathbf{v}_{j}\right) x_{i} x_{j} 45 | $$ 46 | 47 | - FM 模型有$O(kd)$个参数(k≪d) 48 | 49 | ## 1.4 FM 总结 50 | 51 | - FM 是线性模型的替代品,能用线性回归、逻辑回归的场景,都可以用 FM 52 | 53 | - FM **使用二阶交叉特征,表达能力比线性模型更强 ** 54 | - 通过做近似$u_{i j} \approx \mathbf{v}_{i}^{T} \mathbf{v}_{j}$,FM 把二阶交叉权重的数量从$O(d^2)$降低到$O(kd)$ 55 | 56 | 参考文献:Steffen Rendle. Factorization machines. In ICDM, 2010. 57 | 58 | # 2.深度交叉网络(DCN) 59 | 60 | DCN用来代替简单的全连接网络,DCN既可以用于排序,也可以用于召回 61 | 62 | ## 2.1召回、排序模型 63 | 64 | ### (1)双塔模型 65 | 66 | 用户塔和物品塔可以用任意的网络结构 67 | 68 | ![](image/image_mODwPpJRwO.png) 69 | 70 | ### (2)标准多目标排序模型 71 | 72 | shared bottom可以用任意网络结构 73 | 74 | ![](image/image_5DVcAZyldb.png) 75 | 76 | ### (3)排序MMoE 77 | 78 | 专家神经网络也可以用任意的结构 79 | 80 | ![](image/image_ZwDC-fQYRn.png) 81 | 82 | ## 2.2交叉层(Cross Layer) 83 | 84 | - Hadamard Product:逐元素相乘,要求两个向量的形状相同 85 | - 这个操作类似于 ResNet 中的 跳跃链接 Skip Connection 86 | - 交叉层的参数,全部在全连接层中 87 | 88 | ![](image/image_AIHkQL_AM5.png) 89 | 90 | - 交叉层的输入是两个向量 $x_0$和$x_i$,$x_0$是神经网络最底层的输入,$x_i$是神经网络第i层的输入 91 | - 全连接层的输入输出向量大小是一样的,矩阵w和b是全连接层中的参数,也是交叉层中全部的参数。 92 | - o为Hadamard Product 93 | - 交叉层的输出与输入形状相同 94 | 95 | ![](image/image_4VRIt58qT6.png) 96 | 97 | ## 2.3 交叉网络(Cross Network) 98 | 99 | ![](image/image_wS1eMxRZfw.png) 100 | 101 | ![](image/image_YWTvk7V0Zr.png) 102 | 103 | ![](image/image_NiHZ3gX3ey.png) 104 | 105 | 参考文献 106 | 107 | - 这节课介绍的是 Cross Network V2\[1] 108 | - 老版本的 Cross Network 在论文\[2] 中提出 109 | 110 | 1. Ruoxi Wang et al. DCN V2: Improved Deep & Cross Network and Practical Lessons for Web-scale Learning to Rank Systems. In WWW, 2021. 111 | 2. Ruoxi Wang et al. Deep & Cross Network for Ad Click Predictions. In ADKDD, 2017. 112 | 113 | ## 2.4深度交叉网络 (Deep & Cross Network) 114 | 115 | - 把 **全连接网络、交叉网络、全连接层** 拼到一起,就是 深度交叉网络 DCN 116 | - 召回、排序模型中的各种 塔、神经网络、专家网络 都可以是 DCN 117 | 118 | ![](image/image_tRbq2lEbUV.png) 119 | 120 | # 3.LHUC网络结构 121 | 122 | **LHUC 在工业界有效,不过只用于精排 ** 123 | 124 | 标准的多目标排序模型,中间神经网络为shared bottom,被多个神经网络共享,用什么样的神经网络都可以,包括全连接网络、深度交叉网络和LHUC。 125 | 126 | ![](image/image_2bYQeQ7M2d.png) 127 | 128 | **Learning Hidden Unit Contributions (LHUC)** 129 | 130 | - LHUC 起源于语音识别\[1] 131 | - 快手将 LHUC 应用在推荐精排\[2],称作 **PPNet ** 132 | 133 | 参考文献: 134 | 135 | 1. Pawel Swietojanski, Jinyu Li, & Steve Renals. Learning hidden unit contributions for unsupervised acoustic model adaptation. IEEE/ACM Transactions on Audio, Speech, and Language Processing, 2016. 136 | 2. [快手落地万亿参数推荐精排模型](https://www.51cto.com/article/644214.html "快手落地万亿参数推荐精排模型") 137 | 138 | ## 3.1语音识别中的 LHUC 139 | 140 | 输入是一段语音信号,希望用神经网络对其做变换,得到更有效的表征,然后识别出语音中的文字。 141 | 142 | 语音是人说的,不同的人说话有所区别,所以是最好加入以下说话者的特征,对说话者的特征做embedding,得到说话者的向量。 143 | 144 | - 说话者的特征:例如说话者的 ID,年龄,性别 等 145 | 146 | 网络结构: 147 | 148 | - 把语音信号输入全连接层,得到一个向量; 149 | - 把说话者的特征输入另一个神经网络,得到另一个向量;这个神经网络内部包含多个全连接层,最后一个全连接层的激活函数是 **Sigmoid 乘以 2**,即输出向量介于 \[0,2] ; 150 | - 两个向量形状完全一样,计算两个向量的Hadamard Product,输出向量形状和两个输入向量形状相同;把两者信号相融合。 151 | - 把输出向量再输入下一个全连接层,再输出一个向量; 152 | - 把说话者的特征再输入一个神经网络,最后一层的激活函数也是 Sigmoid 乘以 2,即输出向量介于 \[0,2] ; 153 | - 最后做Hadamard Product,输出最终向量。 154 | 155 | ![](image/image_zaTzsYcK86.png) 156 | 157 | ## 3.2推荐系统排序模型中的 LHUC 158 | 159 | 输入变成了 物品特征 和 用户特征 160 | 161 | ![](image/image_IOwpCjNMD3.png) 162 | 163 | # 4.SENet & Bilinear Cross 164 | 165 | ## 4.1 SENet 166 | 167 | 参考文献: 168 | 169 | 1. Jie Hu, Li Shen, and Gang Sun. Squeeze-and-Excitation Networks. In CVPR, 2018. 170 | 2. Tongwen Huang, Zhiqi Zhang, and Junlin Zhang. FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction. In RecSys, 2019. 171 | 172 | 下面是推荐系统用到的离散特征,包括用户ID、物品ID等,对这些特征做Embedding,得到很多向量。 173 | 174 | ![](image/image_6YPUOGgnL2.png) 175 | 176 | ![](image/image_NRRP3WU9pM.png) 177 | 178 | - 设一共有m个特征,每个特征表示为k维向量,把所有特征表示成 $m\times k$的矩阵。 179 | - 对矩阵的行做AvgPool,得到m维元素;向量中的每一个向量,得到一个离散特征。 180 | - 用FC和ReLU,把m维的向量,压缩成 $\frac{m}{r}$向量;r是压缩比列,设置为大于 1 的数; 181 | - 在用FC和Sigmoid,恢复出m维的向量; 182 | - 两个矩阵行相乘,得到$m\times k$的矩阵;中间m维矩阵的作用,就是对特征做加权。例如:学习发现物品 ID 对任务的重要性不高,就给物品 ID embedding 降权 183 | 184 | ![](image/image_e-jdeFLaaZ.png) 185 | 186 | 刚刚为了方便,把m维离散特征映射成k个维度;其实这m个向量维度可以不同,但这不会影响SENet,SENet输出m个向量,和输入相同。 187 | 188 | ![](image/image_3WvbHFd6Ms.png) 189 | 190 | SENet 本质是对离散特征做 field-wise 加权; 191 | 192 | Field 举例: 193 | 194 | - 用户 ID Embedding 是 64 维向量 195 | 196 | - 64 个元素算一个 field,获得相同的权重 197 | 198 | 如果有m个 fields,那么权重向量是m维Field 间特征交叉; 199 | 200 | ## 4.2 Field间特征交叉 201 | 202 | SENet是一个Field之间的特征加权;Field间特征交叉是多个Field之间做特征交叉 203 | 204 | ### (1)特征交叉- 内积、哈达玛乘积 205 | 206 | - 哈达玛乘积的输出是$m^2$个向量,参数量过大;如果要用它做特征交叉,必须人工选择 tier 做交叉 207 | 208 | - 内积和哈达玛乘积都要求特征形状相同 209 | 210 | ![](image/image_CLjNrkQxa6.png) 211 | 212 | ### (2)**Bilinear Cross(內积) ** 213 | 214 | - 不要求特征形状相同○ 215 | - $m ~fields →m^2$个交叉特征(实数) 216 | - $m ~fields →m^2/2$个参数矩阵 217 | - 参数矩阵过多,**需要人工指定某些相关且重要的特征做交叉**,不能对所有特征做两两交叉 218 | 219 | ![](image/image_cjzM4ecvu3.png) 220 | 221 | 这也是,用哈达玛乘积,替换内积 222 | 223 | - $m ~fields →m^2$个向量 224 | 225 | - 在实践中依然需要人工指定某些特征做交叉 226 | 227 | ![](image/image_D4R-02kTP0.png) 228 | 229 | ## 4.3 FiBiNet 230 | 231 | 把 SENet 和 Bilinear Cross 结合起来就是 FiBiNet。 232 | 233 | 234 | 参考文献:Tongwen Huang, Zhiqi Zhang, and Junlin Zhang. FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction. In RecSys, 2019. 235 | 236 | ![](image/image_j1h3X4VerA.png) 237 | 238 | - 以前我们就直接把离散特征的 Embedding 拼接后再与连续特征拼接 239 | - FiBiNet 多做了一些工作 240 | - 对离散特征的 Embedding 做 Bilinear Cross,得到交叉特征并拼接为 1 个向量 241 | - 用 SENet 对 Embedding 做加权,再对这些向量做 Biliner Cross,得到交叉特征并拼接为 1 个向量 242 | - 王老师个人认为这里的 Biliner Cross 多余了,小红书没有用,而是直接做了拼接 243 | - 小红书借鉴了 FiBiNet,SENet 和 Bilinear Cross 在精排模型上确实有效 244 | - 模型结构以及 Bilinear Cross 的实现都与原文区别很大 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /docs/rec/5.行为序列.md: -------------------------------------------------------------------------------- 1 | # 5.行为序列 2 | 3 | # 1.用户行为序列建模 4 | 5 | - 用户行为序列简称为 LastN,即用户最后交互的n个物品 6 | 7 | - LastN 可以反映用户对什么样的物品感兴趣 8 | 9 | ## 1.1 **LastN 特征** 10 | 11 | - LastN:用户最近的n次交互(点击、点赞等)的物品 ID 12 | 13 | - 对 LastN 物品 ID 做 embedding,得到n个向量 14 | 15 | - 把n个向量取平均得到一个向量,作为用户的一种特征 16 | 17 | - 适用于召回双塔模型、粗排三塔模型、精排模型 18 | 19 | ![](image/image_MCxufwxlSs.png) 20 | 21 | 参考文献:Covington, Adams, and Sargin. Deep neural networks for YouTube recommendations. In ACM Conference on Recommender Systems, 2016. 22 | 23 | 24 | ## 1.2小红书的实践 25 | 26 | 小红书的召回、粗排、精排中都用到了 LastN 行为序列。 27 | 28 | - 取平均是早期的用法,效果不错;现在更多的是用 **Attention ** 29 | - 上面得到的多个**向量拼接起来**,作为一种用户特征,传到召回或排序模型中 30 | - Embedding 不只有物品 ID,还会有物品类别等特征 31 | 32 | ![](image/image_kosHodwpAP.png) 33 | 34 | # 2.DIN 模型 35 | 36 | 对LastN建模的一种方法,效果优于平均 37 | 38 | ## 2.1 DIN 模型 39 | 40 | - DIN 用加权平均代替平均,即注意力机制(attention) 41 | - 权重:**候选物品与用户 LastN 物品的相似度 ** 42 | 43 | 参考文献:Zhou et al. Deep interest network for click-through rate prediction. In KDD, 2018. 44 | 45 | 如下图所示: 46 | 47 | - 红色向量:用户交互过的LastN向量表征; 48 | - 蓝色向量:候选物品的向量表征;候选物品:比如粗排选出500个物品,这就是精排的候选物品; 49 | - 计算相似度:计算$x_1$与q的相似度,....., 计算$x_n$与q的相似度;计算相似度的方法很多,如 内积 和 余弦相似度 等 50 | - 紫色向量:与LastN向量相乘,得到加权和,权重是相似度 51 | 52 | ![](image/image_iSIctmYYbR.png) 53 | 54 | **DIN 模型总结 ** 55 | 56 | - 对于某候选物品,计算它与用户 LastN 物品的相似度 57 | - 以相似度为权重,求用户 LastN 物品向量的加权和,结果是一个向量 58 | - 把得到的向量作为一种用户特征,输入排序模型,预估(用户,候选物品)的点击率、点赞率等指标 59 | - **本质是注意力机制(attention) ** 60 | 61 | ![](image/image_FvepkhhpYx.png) 62 | 63 | DIN 的本质是注意力机制 64 | 65 | ## 2.2简单平均 vs. 注意力机制 66 | 67 | 简单平均 和 注意力机制 都适用于精排模型 68 | 69 | **简单平均适用于双塔模型、三塔模型 ** 70 | 71 | - 简单平均只需要用到 LastN,属于用户自身的特征,与候选物品无关 72 | - 把 LastN 向量的平均作为用户塔的输入 73 | 74 | **注意力机制不适用于双塔模型、三塔模型 ** 75 | 76 | - 注意力机制 需要用到 LastN + 候选物品 77 | - 用户塔看不到候选物品,不能把 注意力机制 用在用户塔 ,但是DIN需要候选特征,所以DIN不能放在用户塔。 78 | 79 | ![](image/image_oXaUPepJGU.png) 80 | 81 | ![](image/image__KwcoqndE_.png) 82 | 83 | # 3.SIM 模型 84 | 85 | SIM 模型的主要目的是保留用户的长期兴趣。 86 | 87 | ## 3.1回顾 DIN 模型 88 | 89 | DIN 模型 90 | 91 | - 计算用户 LastN 向量的加权平均 92 | - 权重是候选物品与 LastN 物品的相似度 93 | 94 | DIN 模型的缺点: 95 | 96 | - 注意力层的计算量 $∝n$(用户行为序列的长度),只能记录最近几百个物品,否则计算量太大 97 | - **关注短期兴趣,遗忘长期兴趣;**通过实验发现,增长记录的行为序列,可以显著提升推荐系统的所有指标,但增加的计算量太大了 98 | 99 | 参考文献:Zhou et al. Deep interest network for click-through rate prediction. In KDD, 2018. 100 | 101 | ![](image/image_X-3xjswNi2.png) 102 | 103 | **如何改进 DIN?** 104 | 105 | - **目标**:保留用户长期行为序列(n很大),而且计算量不会过大 106 | - 改进 DIN:DIN 对 LastN 向量做加权平均,权重是相似度 ;**如果某 LastN 物品与候选物品差异很大,则权重接近零;快速排除掉与候选物品无关的 LastN 物品,降低注意力层的计算量。 ** 107 | 108 | ## 3.2 SIM 模型 109 | 110 | - 保留用户长期行为记录,n的大小可以是几千;如果不用SIM,n的大小一般是200左右 111 | 112 | - **对于每个候选物品,在用户 LastN 记录中做快速查找,找到k个相似物品 ** 113 | - 把 LastN 变成 TopK,然后输入到注意力层 114 | 115 | - SIM 模型减小计算量(从n降到k) 116 | 117 | - 参考文献:Qi et al. Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Through Rate Prediction. In CIKM, 2020. 118 | 119 | ### (1)查找 120 | 121 | - 方法一:**Hard Search**:根据规则做筛选○根据候选物品的类目,保留 LastN 物品中类目相同的;简单,快速,无需训练 。 122 | - 方法二:**Soft Search**:把物品做 embedding,变成向量 ;把候选物品向量作为 query,做k近邻查找,保留 LastN 物品中最接近的k个;**效果更好,编程实现更复杂 ** 123 | 124 | ### (2)注意力机制 125 | 126 | 本质上核DIN没有区别,**只不过用用户的TopK交互记录,而不是LastN交互记录**。 127 | 128 | ![](image/image_9vlSe0CY4G.png) 129 | 130 | ## 3.3 Trick:使用时间信息 131 | 132 | 用户与某个 LastN 物品的交互时刻距今为$\delta$ 133 | 134 | 对$\delta$做离散化,再做 embedding,变成向量d;例如把时间离散为 1 天内、7 天内、30 天内、一年、一年以上 135 | 136 | 137 | 把两个向量做 concatenation,表征一个 LastN 物品交互记录 138 | 139 | - 向量$x$是物品 embedding 140 | - 向量$d$是时间的 embedding 141 | 142 | ![](image/image_xcucF0MAb5.png) 143 | 144 | **为什么 SIM 使用时间信息? ** 145 | 146 | - DIN 的序列短,记录用户近期行为 147 | - SIM 的序列长,记录用户长期行为 148 | - 时间越久远,重要性越低 149 | 150 | ## 3.4结论 151 | 152 | 长序列(长期兴趣)优于短序列(近期兴趣) 153 | 154 | 注意力机制优于简单平均 155 | 156 | Soft search 还是 hard search?取决于工程基建 157 | 158 | 使用时间信息有提升 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /docs/rec/README.md: -------------------------------------------------------------------------------- 1 | # 王树森推荐系统 2 | 3 | 主要来自王树森老师讲的推荐系统: 4 | 5 | - [官方 GitHub 仓库](https://github.com/wangshusen/RecommenderSystem "官方 GitHub 仓库") 6 | - B站视频:[https://space.bilibili.com/1369507485/channel/collectiondetail?sid=615109](https://space.bilibili.com/1369507485/channel/collectiondetail?sid=615109 "https://space.bilibili.com/1369507485/channel/collectiondetail?sid=615109") 7 | - 讲义:[wangshusen/RecommenderSystem (github.com)](https://github.com/wangshusen/RecommenderSystem "wangshusen/RecommenderSystem (github.com)") 8 | - 联系方式:ShusenWang[@xiaohongshu.com](/xiaohongshu.com "@xiaohongshu.com") 9 | 10 | ### 主要内容 11 | 12 | - [1.概要](/docs/rec/1.概要.md) 13 | - [2.召回](/docs/rec/2.召回.md) 14 | - [3.排序](/docs/rec/3.排序.md) 15 | - [4.特征交叉](/docs/rec/4.特征交叉.md) 16 | - [5.行为序列](/docs/rec/5.行为序列.md) 17 | - [6.重排](/docs/rec/6.重排.md) 18 | - [7.物品冷启动](/docs/rec/7.物品冷启动.md) 19 | 20 | -------------------------------------------------------------------------------- /docs/rec/image/image_-c9_lwqj_l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_-c9_lwqj_l.png -------------------------------------------------------------------------------- /docs/rec/image/image_0-Ga1DCKwo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_0-Ga1DCKwo.png -------------------------------------------------------------------------------- /docs/rec/image/image_0pwcMiTsOT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_0pwcMiTsOT.png -------------------------------------------------------------------------------- /docs/rec/image/image_0qFhFDLE6M.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_0qFhFDLE6M.png -------------------------------------------------------------------------------- /docs/rec/image/image_1SZ8p7JSfX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_1SZ8p7JSfX.png -------------------------------------------------------------------------------- /docs/rec/image/image_1lMyM1lqV3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_1lMyM1lqV3.png -------------------------------------------------------------------------------- /docs/rec/image/image_1seADePZzK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_1seADePZzK.png -------------------------------------------------------------------------------- /docs/rec/image/image_1vzxIJWpJw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_1vzxIJWpJw.png -------------------------------------------------------------------------------- /docs/rec/image/image_28ITuuUy2p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_28ITuuUy2p.png -------------------------------------------------------------------------------- /docs/rec/image/image_2C0Y35qWpv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_2C0Y35qWpv.png -------------------------------------------------------------------------------- /docs/rec/image/image_2WzVKJf3zS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_2WzVKJf3zS.png -------------------------------------------------------------------------------- /docs/rec/image/image_2bYQeQ7M2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_2bYQeQ7M2d.png -------------------------------------------------------------------------------- /docs/rec/image/image_3WvbHFd6Ms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_3WvbHFd6Ms.png -------------------------------------------------------------------------------- /docs/rec/image/image_3X4y4vTuYc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_3X4y4vTuYc.png -------------------------------------------------------------------------------- /docs/rec/image/image_3jSmbGIWjO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_3jSmbGIWjO.png -------------------------------------------------------------------------------- /docs/rec/image/image_3oBGLNyBjf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_3oBGLNyBjf.png -------------------------------------------------------------------------------- /docs/rec/image/image_3sNKnDe5oQ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_3sNKnDe5oQ.png -------------------------------------------------------------------------------- /docs/rec/image/image_4KUrLTZSlt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_4KUrLTZSlt.png -------------------------------------------------------------------------------- /docs/rec/image/image_4Nhihh1RvM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_4Nhihh1RvM.png -------------------------------------------------------------------------------- /docs/rec/image/image_4VRIt58qT6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_4VRIt58qT6.png -------------------------------------------------------------------------------- /docs/rec/image/image_4xpAKAJs9R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_4xpAKAJs9R.png -------------------------------------------------------------------------------- /docs/rec/image/image_57embG0Blf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_57embG0Blf.png -------------------------------------------------------------------------------- /docs/rec/image/image_5DVcAZyldb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_5DVcAZyldb.png -------------------------------------------------------------------------------- /docs/rec/image/image_5HvjKCac84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_5HvjKCac84.png -------------------------------------------------------------------------------- /docs/rec/image/image_5uFd4P-Qlb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_5uFd4P-Qlb.png -------------------------------------------------------------------------------- /docs/rec/image/image_5xAIj-eIAs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_5xAIj-eIAs.png -------------------------------------------------------------------------------- /docs/rec/image/image_6J3FAs8p3v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_6J3FAs8p3v.png -------------------------------------------------------------------------------- /docs/rec/image/image_6YPUOGgnL2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_6YPUOGgnL2.png -------------------------------------------------------------------------------- /docs/rec/image/image_7AB46ql7Jk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_7AB46ql7Jk.png -------------------------------------------------------------------------------- /docs/rec/image/image_7GvVjtBfqJ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_7GvVjtBfqJ.png -------------------------------------------------------------------------------- /docs/rec/image/image_7l9xATVYys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_7l9xATVYys.png -------------------------------------------------------------------------------- /docs/rec/image/image_8-GAXyLYFr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_8-GAXyLYFr.png -------------------------------------------------------------------------------- /docs/rec/image/image_81a-t6r1pX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_81a-t6r1pX.png -------------------------------------------------------------------------------- /docs/rec/image/image_89Drp77iFr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_89Drp77iFr.png -------------------------------------------------------------------------------- /docs/rec/image/image_8RNkmrt2_C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_8RNkmrt2_C.png -------------------------------------------------------------------------------- /docs/rec/image/image_8o8agbx8T7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_8o8agbx8T7.png -------------------------------------------------------------------------------- /docs/rec/image/image_8vVheB5mBI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_8vVheB5mBI.png -------------------------------------------------------------------------------- /docs/rec/image/image_9vlSe0CY4G.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_9vlSe0CY4G.png -------------------------------------------------------------------------------- /docs/rec/image/image_AIHkQL_AM5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_AIHkQL_AM5.png -------------------------------------------------------------------------------- /docs/rec/image/image_BIyTFzMSZv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_BIyTFzMSZv.png -------------------------------------------------------------------------------- /docs/rec/image/image_BO2LKkXOvD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_BO2LKkXOvD.png -------------------------------------------------------------------------------- /docs/rec/image/image_BgVc5Y6cBf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_BgVc5Y6cBf.png -------------------------------------------------------------------------------- /docs/rec/image/image_BsJapeD-_o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_BsJapeD-_o.png -------------------------------------------------------------------------------- /docs/rec/image/image_C6e2dZFM8N.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_C6e2dZFM8N.png -------------------------------------------------------------------------------- /docs/rec/image/image_CJoCP17GvW.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CJoCP17GvW.png -------------------------------------------------------------------------------- /docs/rec/image/image_CK230euPN4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CK230euPN4.png -------------------------------------------------------------------------------- /docs/rec/image/image_CLjNrkQxa6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CLjNrkQxa6.png -------------------------------------------------------------------------------- /docs/rec/image/image_CcZ86wfDTw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CcZ86wfDTw.png -------------------------------------------------------------------------------- /docs/rec/image/image_CoGLwk6LIu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CoGLwk6LIu.png -------------------------------------------------------------------------------- /docs/rec/image/image_CzBo1a7MrT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_CzBo1a7MrT.png -------------------------------------------------------------------------------- /docs/rec/image/image_D4R-02kTP0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_D4R-02kTP0.png -------------------------------------------------------------------------------- /docs/rec/image/image_DW3Rd2Wk_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_DW3Rd2Wk_n.png -------------------------------------------------------------------------------- /docs/rec/image/image_E6nGivyquc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_E6nGivyquc.png -------------------------------------------------------------------------------- /docs/rec/image/image_EI4kbN2TX4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_EI4kbN2TX4.png -------------------------------------------------------------------------------- /docs/rec/image/image_F6dhnh2qbQ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_F6dhnh2qbQ.png -------------------------------------------------------------------------------- /docs/rec/image/image_FeBXn0GhzL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_FeBXn0GhzL.png -------------------------------------------------------------------------------- /docs/rec/image/image_FvepkhhpYx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_FvepkhhpYx.png -------------------------------------------------------------------------------- /docs/rec/image/image_G6g9NEgw8Z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_G6g9NEgw8Z.png -------------------------------------------------------------------------------- /docs/rec/image/image_GPt66RfR6z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_GPt66RfR6z.png -------------------------------------------------------------------------------- /docs/rec/image/image_Gip-URcw9d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Gip-URcw9d.png -------------------------------------------------------------------------------- /docs/rec/image/image_H_CwyEvwCx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_H_CwyEvwCx.png -------------------------------------------------------------------------------- /docs/rec/image/image_Hn-lrisNa-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Hn-lrisNa-.png -------------------------------------------------------------------------------- /docs/rec/image/image_I50dj7yBEb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_I50dj7yBEb.png -------------------------------------------------------------------------------- /docs/rec/image/image_IOwpCjNMD3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_IOwpCjNMD3.png -------------------------------------------------------------------------------- /docs/rec/image/image_Jq6f3XhyS3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Jq6f3XhyS3.png -------------------------------------------------------------------------------- /docs/rec/image/image_K4QBc0qZQZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_K4QBc0qZQZ.png -------------------------------------------------------------------------------- /docs/rec/image/image_L0ZpX5japc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_L0ZpX5japc.png -------------------------------------------------------------------------------- /docs/rec/image/image_LUdBQB0S5u.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_LUdBQB0S5u.png -------------------------------------------------------------------------------- /docs/rec/image/image_M608Z9jh12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_M608Z9jh12.png -------------------------------------------------------------------------------- /docs/rec/image/image_MCxufwxlSs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_MCxufwxlSs.png -------------------------------------------------------------------------------- /docs/rec/image/image_MDz6ke3VVL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_MDz6ke3VVL.png -------------------------------------------------------------------------------- /docs/rec/image/image_MHzIkwJFsw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_MHzIkwJFsw.png -------------------------------------------------------------------------------- /docs/rec/image/image_Ma6fm_wZ_l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Ma6fm_wZ_l.png -------------------------------------------------------------------------------- /docs/rec/image/image_MkPh7xZCFm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_MkPh7xZCFm.png -------------------------------------------------------------------------------- /docs/rec/image/image_MwXGfVnOEE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_MwXGfVnOEE.png -------------------------------------------------------------------------------- /docs/rec/image/image_NRRP3WU9pM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_NRRP3WU9pM.png -------------------------------------------------------------------------------- /docs/rec/image/image_NYHCr0fS8C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_NYHCr0fS8C.png -------------------------------------------------------------------------------- /docs/rec/image/image_NiHZ3gX3ey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_NiHZ3gX3ey.png -------------------------------------------------------------------------------- /docs/rec/image/image_Oj3BlHhaR_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Oj3BlHhaR_.png -------------------------------------------------------------------------------- /docs/rec/image/image_PGMrIELLsg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_PGMrIELLsg.png -------------------------------------------------------------------------------- /docs/rec/image/image_PVBLfuCWTt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_PVBLfuCWTt.png -------------------------------------------------------------------------------- /docs/rec/image/image_RGiOdnd8pP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_RGiOdnd8pP.png -------------------------------------------------------------------------------- /docs/rec/image/image_Rs-fIUSKmD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Rs-fIUSKmD.png -------------------------------------------------------------------------------- /docs/rec/image/image_SLQxKYsSS0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_SLQxKYsSS0.png -------------------------------------------------------------------------------- /docs/rec/image/image_SYwggjx4oY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_SYwggjx4oY.png -------------------------------------------------------------------------------- /docs/rec/image/image_SxItlIaLWB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_SxItlIaLWB.png -------------------------------------------------------------------------------- /docs/rec/image/image_Tfwv_42EQu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Tfwv_42EQu.png -------------------------------------------------------------------------------- /docs/rec/image/image_TvdXfJcTCB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_TvdXfJcTCB.png -------------------------------------------------------------------------------- /docs/rec/image/image_U8wh9Vfs3m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_U8wh9Vfs3m.png -------------------------------------------------------------------------------- /docs/rec/image/image_UkPqQlcso-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_UkPqQlcso-.png -------------------------------------------------------------------------------- /docs/rec/image/image_W0b7sV_AW2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_W0b7sV_AW2.png -------------------------------------------------------------------------------- /docs/rec/image/image_W2MrRVHDza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_W2MrRVHDza.png -------------------------------------------------------------------------------- /docs/rec/image/image_W4DHHkFRmJ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_W4DHHkFRmJ.png -------------------------------------------------------------------------------- /docs/rec/image/image_WfjfGcwBVQ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_WfjfGcwBVQ.png -------------------------------------------------------------------------------- /docs/rec/image/image_X-3xjswNi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_X-3xjswNi2.png -------------------------------------------------------------------------------- /docs/rec/image/image_YWTvk7V0Zr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_YWTvk7V0Zr.png -------------------------------------------------------------------------------- /docs/rec/image/image_Zp8t8F0p5q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Zp8t8F0p5q.png -------------------------------------------------------------------------------- /docs/rec/image/image_ZwDC-fQYRn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_ZwDC-fQYRn.png -------------------------------------------------------------------------------- /docs/rec/image/image_ZxvgHV0_0_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_ZxvgHV0_0_.png -------------------------------------------------------------------------------- /docs/rec/image/image_Zy3HHldsZb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_Zy3HHldsZb.png -------------------------------------------------------------------------------- /docs/rec/image/image__KwcoqndE_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image__KwcoqndE_.png -------------------------------------------------------------------------------- /docs/rec/image/image__Z0HsNo2I3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image__Z0HsNo2I3.png -------------------------------------------------------------------------------- /docs/rec/image/image__cO_SLTofi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image__cO_SLTofi.png -------------------------------------------------------------------------------- /docs/rec/image/image_axmVLY6Ik4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_axmVLY6Ik4.png -------------------------------------------------------------------------------- /docs/rec/image/image_bpbVb26Fqo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_bpbVb26Fqo.png -------------------------------------------------------------------------------- /docs/rec/image/image_cjzM4ecvu3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_cjzM4ecvu3.png -------------------------------------------------------------------------------- /docs/rec/image/image_clKaQ1OT8W.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_clKaQ1OT8W.png -------------------------------------------------------------------------------- /docs/rec/image/image_dNmmm3qJi6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_dNmmm3qJi6.png -------------------------------------------------------------------------------- /docs/rec/image/image_d_Tj6Uk4_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_d_Tj6Uk4_n.png -------------------------------------------------------------------------------- /docs/rec/image/image_e-jdeFLaaZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_e-jdeFLaaZ.png -------------------------------------------------------------------------------- /docs/rec/image/image_e19PdpsF8e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_e19PdpsF8e.png -------------------------------------------------------------------------------- /docs/rec/image/image_egcqBvd27d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_egcqBvd27d.png -------------------------------------------------------------------------------- /docs/rec/image/image_fiDdgrgvCO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_fiDdgrgvCO.png -------------------------------------------------------------------------------- /docs/rec/image/image_h-JdOb6bHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_h-JdOb6bHA.png -------------------------------------------------------------------------------- /docs/rec/image/image_hHDhp6PO7s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_hHDhp6PO7s.png -------------------------------------------------------------------------------- /docs/rec/image/image_hWhDQ9HB9z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_hWhDQ9HB9z.png -------------------------------------------------------------------------------- /docs/rec/image/image_h_l_P1zRni.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_h_l_P1zRni.png -------------------------------------------------------------------------------- /docs/rec/image/image_hiQmSo-x_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_hiQmSo-x_0.png -------------------------------------------------------------------------------- /docs/rec/image/image_i3Bqkzf_GU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_i3Bqkzf_GU.png -------------------------------------------------------------------------------- /docs/rec/image/image_iSIctmYYbR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_iSIctmYYbR.png -------------------------------------------------------------------------------- /docs/rec/image/image_iShVEnF6Yg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_iShVEnF6Yg.png -------------------------------------------------------------------------------- /docs/rec/image/image_iTVMfwwJNh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_iTVMfwwJNh.png -------------------------------------------------------------------------------- /docs/rec/image/image_imPcZGdrGv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_imPcZGdrGv.png -------------------------------------------------------------------------------- /docs/rec/image/image_iva8FLR943.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_iva8FLR943.png -------------------------------------------------------------------------------- /docs/rec/image/image_j1h3X4VerA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_j1h3X4VerA.png -------------------------------------------------------------------------------- /docs/rec/image/image_jCcdGPTvVH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_jCcdGPTvVH.png -------------------------------------------------------------------------------- /docs/rec/image/image_k7S54sQC6j.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_k7S54sQC6j.png -------------------------------------------------------------------------------- /docs/rec/image/image_k8dNw9k5Ba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_k8dNw9k5Ba.png -------------------------------------------------------------------------------- /docs/rec/image/image_kTbzOBottp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_kTbzOBottp.png -------------------------------------------------------------------------------- /docs/rec/image/image_kdGWIqhRTx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_kdGWIqhRTx.png -------------------------------------------------------------------------------- /docs/rec/image/image_kosHodwpAP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_kosHodwpAP.png -------------------------------------------------------------------------------- /docs/rec/image/image_l_iktEIkRV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_l_iktEIkRV.png -------------------------------------------------------------------------------- /docs/rec/image/image_lgfvyRfSTt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_lgfvyRfSTt.png -------------------------------------------------------------------------------- /docs/rec/image/image_m-qWuNiq5w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_m-qWuNiq5w.png -------------------------------------------------------------------------------- /docs/rec/image/image_m6_c31EjLw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_m6_c31EjLw.png -------------------------------------------------------------------------------- /docs/rec/image/image_mODwPpJRwO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_mODwPpJRwO.png -------------------------------------------------------------------------------- /docs/rec/image/image_ncWaODgw2m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_ncWaODgw2m.png -------------------------------------------------------------------------------- /docs/rec/image/image_o2EuYCVmLx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_o2EuYCVmLx.png -------------------------------------------------------------------------------- /docs/rec/image/image_o5Ak6yyHCX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_o5Ak6yyHCX.png -------------------------------------------------------------------------------- /docs/rec/image/image_oXaUPepJGU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_oXaUPepJGU.png -------------------------------------------------------------------------------- /docs/rec/image/image_ovVgYq5YSc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_ovVgYq5YSc.png -------------------------------------------------------------------------------- /docs/rec/image/image_pE00eutJ6U.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_pE00eutJ6U.png -------------------------------------------------------------------------------- /docs/rec/image/image_pJSzVC1ma9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_pJSzVC1ma9.png -------------------------------------------------------------------------------- /docs/rec/image/image_pgtuA8uQtF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_pgtuA8uQtF.png -------------------------------------------------------------------------------- /docs/rec/image/image_rnzkChV_td.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_rnzkChV_td.png -------------------------------------------------------------------------------- /docs/rec/image/image_smA5iQsBsD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_smA5iQsBsD.png -------------------------------------------------------------------------------- /docs/rec/image/image_tRbq2lEbUV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_tRbq2lEbUV.png -------------------------------------------------------------------------------- /docs/rec/image/image_tRxTN6ETAF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_tRxTN6ETAF.png -------------------------------------------------------------------------------- /docs/rec/image/image_tSl9WOnZwF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_tSl9WOnZwF.png -------------------------------------------------------------------------------- /docs/rec/image/image_tdYg8_xWwp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_tdYg8_xWwp.png -------------------------------------------------------------------------------- /docs/rec/image/image_tncVQjZAgp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_tncVQjZAgp.png -------------------------------------------------------------------------------- /docs/rec/image/image_uGSDWU-Odn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_uGSDWU-Odn.png -------------------------------------------------------------------------------- /docs/rec/image/image_uQOeuJ5hAI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_uQOeuJ5hAI.png -------------------------------------------------------------------------------- /docs/rec/image/image_vE5i49fP7D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_vE5i49fP7D.png -------------------------------------------------------------------------------- /docs/rec/image/image_vP8Uoyc8tH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_vP8Uoyc8tH.png -------------------------------------------------------------------------------- /docs/rec/image/image_wS1eMxRZfw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_wS1eMxRZfw.png -------------------------------------------------------------------------------- /docs/rec/image/image_wUlx8lS-ox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_wUlx8lS-ox.png -------------------------------------------------------------------------------- /docs/rec/image/image_x3TlzA1Dvz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_x3TlzA1Dvz.png -------------------------------------------------------------------------------- /docs/rec/image/image_xIuiO1kw7v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_xIuiO1kw7v.png -------------------------------------------------------------------------------- /docs/rec/image/image_xcucF0MAb5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_xcucF0MAb5.png -------------------------------------------------------------------------------- /docs/rec/image/image_y5UxXFuNLf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_y5UxXFuNLf.png -------------------------------------------------------------------------------- /docs/rec/image/image_zMk4F7kDuj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_zMk4F7kDuj.png -------------------------------------------------------------------------------- /docs/rec/image/image_zaTzsYcK86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_zaTzsYcK86.png -------------------------------------------------------------------------------- /docs/rec/image/image_zigdAf36nk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/rec/image/image_zigdAf36nk.png -------------------------------------------------------------------------------- /docs/search/1.开篇语.md: -------------------------------------------------------------------------------- 1 | # 1.开篇语 2 | 3 | RAG在整个大模型技术栈里的重要性毋庸置疑,而在RAG中,除了大模型之外,另一个不可或缺的部分,就是搜索系统,大模型的正确、稳定、可控生成,离不开精准可靠的搜索系统,大量的实验中都有发现,在搜索系统足够准确的前提下,大模型的犯错情况会骤然下降,因此,更全面、系统地了解搜索系统将很重要。 4 | 5 | 开篇语主要是和大家介绍一下搜索系统的概况,包括他的具体场景,以及在目前大模型环境下的地位以及使用场景区别。 6 | 7 | ## 1.搜索系统概念的理解 8 | 9 | 所谓搜索系统,大家比较普遍认可的概念是,**能从海量的信息中找到所需要的内容的方案,都可以被称为搜索**,除了大家所熟知的百度搜索外,在图书馆里找一本书,在音乐软件里找一首音乐,在美团上找一家外卖,这些背后的事,都可以被称为搜索。有几个角度希望和大家展开说一下。 10 | 11 | 首先是,搜索并不是一个很新的概念,而是一个发展比较久的学问了。北大有图书馆学情报学系,清华大学也有“信息管理与信息系统专业”,虽说所属方向略有差别,但其内部有一个关键的目标就是对信息的优化管理以及使用,其本质和搜索系统非常匹配,这么看搜索的研究可以说是历史悠久了。 12 | 13 | 第二,**搜索的内容并非局限,而且各自的技术也非常丰富**。搜索不能局限在百度这样的大搜上(一般而言大搜是指开放域,比较广泛的搜索),刚才提了几个例子,搜图书、搜音乐、搜外卖、搜商品,这些都算是搜索,而且实际上也已经渗透到大家生活的方方面面了,往高端的说法,可以说是“多模态”,当然可能也不局限在多模态,类似商品、外卖这种异构信息的搜索,就已经超出了常规的文本、图片、声音、视频的简单模态范畴了,尽管多模态和异构的研究看似有些陌生或者不成熟,但也已经在自己的领域非常满足用户的需求,因此,在对问题进行研究、分析的时候不能把搜索问题局限在文本之类的简单信息上。 14 | 15 | 第三,**必要强调搜索和推荐的核心区别**。在SIGIR相关的顶会,有说过搜索和推荐在匹配上的类似点,搜索是文档和query的相似,推荐是物料和用户的相似,但实际从产品层面,用户对匹配的要求是不一样的,在大部分情况下,用户对搜索系统的要求更高更严格,其背后的根本原因是用户在使用搜索系统的时候是有明确目标的,相关都不见的足够,毕竟类似复述query的答案、高频文档不见得有意义,要求要所答即所问,在张俊林比较出名的搜索上书籍《这就是所搜索引擎》里同样也强调了“准”的重要性。 16 | 17 | ## 2.搜素系统的场景 18 | 19 | 为了拓宽大家对搜索系统的理解,这里举几个比较典型的搜索系统场景,同时也和大家说一下这几个搜索场景内部具体的业务特性以及应对方法。 20 | 21 | ### 2.1 泛搜/大搜 22 | 23 | 比较常用的通用性搜索,常见的如百度、谷歌等,当然现在很多所谓的AI搜索,大都属于这个范畴里。对于早期版本,比较简单的方式就是不做很特别的处理,依赖通用baseline方案直接搜,直接用字面、向量等,当然大模型也是一定程度可依赖的,但实际上,也可能会有很多特别地问题,此时就要分意图、分领域针对性的处理,这个在之前的说法叫做意图识别,现在就是路由(route)或者是更潮的方案就是agent。 24 | 25 | 当然,不同的系统里面可能会有不同的结果,具体好不好,就见仁见智了。例如同样是搜索“六级词汇”,百度和号称AI搜索的天工AI的结果分别是这样的: 26 | 27 | ![](image/image_AWm29bJAD1.png) 28 | 29 | > 百度搜索结果 30 | 31 | ![](image/image_n9zXOmxs4T.png) 32 | 33 | > 天工AI搜索结果 34 | 35 | 两者对比下来,可能百度的结果在多样性和有效性上会更高一些,天工的这个结果应该是经过了模型生成处理,内容上没什么毛病,不过基本上没有解决实际的问题,只是把内容拓展解释了一下,没有给出六级词汇表之类的。 36 | 37 | ### 2.2 音乐/视频搜索 38 | 39 | 音乐/视频搜索,这种搜索对物料的性质有很高的要求,而且用户在现实的使用上,更多倾向于标签或者某些关键字段的检索,同样举例子吧。 40 | 41 | 比较常见的,根据歌手返回音乐,下面是网易云音乐的结果: 42 | 43 | ![](image/image_EPp4qqExAg.png) 44 | 45 | > 网易云音乐搜索结果 46 | 47 | 这个没有想象中那么简单,对于用户的输入,我们需要首先识别到他是一个“歌手”,把他从歌名或者歌词中解区分出来,这里就需要大量的实体抽取的技术来实现,显然这不是直接字面检索或者向量检索就能准确稳定的实现的。 48 | 49 | 当然,音乐还有一种非常特别的技术——听歌识曲,这里的用户输入就很明显和其他的不同,这里输入的是一段音频了,如何把给定的片段表征好然后再曲库里检索,也同样非常有技术含量,这里推荐看这些文章。 50 | 51 | - 腾讯音乐的新一代歌曲识别技术:[https://zhuanlan.zhihu.com/p/541450154](https://zhuanlan.zhihu.com/p/541450154 "https://zhuanlan.zhihu.com/p/541450154") 52 | - 这个系列的文章也值得推荐:[https://zhuanlan.zhihu.com/p/75360272](https://zhuanlan.zhihu.com/p/75360272 "https://zhuanlan.zhihu.com/p/75360272") 53 | 54 | ### 2.3 商品搜索 55 | 56 | 商品搜索可以说是最接近推荐系统的一种搜索了。我们在淘宝、精通搜索的时候,往往都只会给很简单的一个实体名词,例如“电脑”,顶多会加一些补充说明的关键词,例如“4060”,或者是“i7”,但实际情况下,这些搜索词下都会有大量的商品,典型的还有就是服装类的,如“长裤”、“裙子”等,下面有数不尽符合这个query的产品,此时的排序显然就不能随机了,可以考虑依靠热度、用户偏好、最近活动、新品等信息来进行综合的评判,在这个情况下,就和推荐系统极为相似了。 57 | 58 | 很早的一篇淘宝的embedding的文章([KDD21-淘宝向量检索](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487695\&idx=1\&sn=370ac19afbbb2c27a07ed6c3fa8b9b70\&chksm=e8824851dff5c1474f522ef37a17661900fd1494c9043ebc1b94426d219fc0053f098538b4b9\&scene=21#wechat_redirect "KDD21-淘宝向量检索"))来看,这个性质就非常明显,在模型里,要兼顾query信息、短长期行为、产品信息等,综合起来完成表征,这里因地制宜的思想体现的很明确,背后也体现了作者对业务问题的理解深度,简单的生搬硬套向量匹配显然并不能解决这些问题。 59 | 60 | 在论文内,作者还简单介绍了淘宝搜索的技术架构,技术架构的事先不展开说,下一篇会专门讲,大家可以提前感受一下: 61 | 62 | ![](image/image_TmG08B6YFp.png) 63 | 64 | ## 3.大模型场景下搜索系统的理解 65 | 66 | NLP最常见的两个场景,就是搜索和对话,在大模型的新时代,也是如此,此时,搜索成为一个重要的NLP载体,让大模型上了船,而另一方面,大模型也让搜索系统更新换代,带来很多新的发展。这里,我来说说我的几个理解吧。 67 | 68 | 首先,要认清这两个名词的性质和所面临的问题。大模型的本质还是一项技术,或者说是一个工具,它能被用在很多场景,但既然是工具,就有被替代、不被选择的可能,直接说“大模型替代了XX”,显然是鲁莽的,相反,在面对实际问题的时候,我们应该把他和原有的方案放在一起,进行严格的对比分析再来进行选择,如果不好分辨,则可以进行相应的实验;而搜索系统,这个和推荐系统类似,都是一个系统,也可以说是一个产品,既然是系统或者产品,内部就是多个技术合力完成的,这里可以放大模型,也可以是别的模型,甚至精排至今还在高频使用估计已经被称为原始时代的机器学习模型,而另一方面类似推荐系统也仍旧有NLP的一席之地——内容理解。而为了成就一个优秀的产品,我们对技术的看法就不能简单的新不新、low不low,而还要考虑具体的算法效果,达成效果所需要的成本,以及用户应用时的性能体验。 69 | 70 | 其次,RAG是大模型的一个很好的应用,这里的R,可以把他拓展成一个五脏俱全的搜索系统,而在优化他的过程中,一个比较稳的方案,就是直接去参考类似的搜索系统常用方案,这里的架构也可以充分参考来构建,之所以说是稳的,是因为这都是前人已经踩平的路了,其他的可能多少也有尝试。当然,如果要创新,肯定还是要多想多尝试,沿着旧路肯定最多就只能第二了。 71 | 72 | 第三,在我的视角看,一些所谓的AI搜索,然后把这些东西和之前就有或者有了很久的搜索给割席,在技术视角看就像是一个运营话术,为了破圈让用户尝试而已。从我看的资料来看,不外乎就是用了大模型生成,或者就是用了所谓的自然语言处理技术而已,但这些技术老牌大厂百度、谷歌、必应之类的,就不能用吗,显然不是,而且真不是没有用到,下图就是百度的结果,那这个算不算AI搜索呢?至于自然语言处理技术,就更离谱了,类似的技术早就在搜索圈里广泛使用了,所以做技术的还是尽量不要被这种说法给带偏了,以为只有用啥才是AI,这样技术选型就被无关的内容限制了。 73 | 74 | ![](image/image_83LuygiASf.png) 75 | 76 | 最后,搜索领域发展至今来看,一直是稳定的代表。从搜索的发展历史来看,搜索的顶峰似乎都不是很高,但是每次打的迭代都能让搜索喝到汤,从早年NLP起步,到百度等的搜索系统崛起,再到后续BERT、大模型等,虽并不耀眼,但一直在发光,而且人类对知识检索的需求一直都存在,因此搜索场景可能是一个相对稳定的领域方向吧。 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/search/3.文档内容处理.md: -------------------------------------------------------------------------------- 1 | # 3.文档内容处理 2 | 3 | RAG在整个大模型技术栈里的重要性毋庸置疑,而在RAG中,除了大模型之外,另一个不可或缺的部分,就是搜索系统,大模型的正确、稳定、可控生成,离不开精准可靠的搜索系统,大量的实验中都有发现,在搜索系统足够准确的前提下,大模型的犯错情况会骤然下降,因此,更全面、系统地了解搜索系统将很重要。 4 | 5 | 本期介绍的是文档内容处理,这块主要聚焦在**离线非推理阶段**,俗话说,巧妇难为无米之炊,文档就是搜索系统的米,没有文档资源,搜索无从谈起,然而,面对各式各样的文档,往往需要进行各种处理,使之变成方便检索、方便展示的形态,才能为我们所用,本文主要就讲解,文档内容处理的核心工作以及常用的方法。 6 | 7 | ## 1.文档内容处理的流程 8 | 9 | 和原来讲RAG文档处理文章里写的相同([知识文档处理和使用流程](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489470\&idx=1\&sn=50f618e87545a1ef12e3480bd44e64f1\&chksm=e8824f20dff5c6365532bd45aa1853086014cad3bc31f5bbb73235da791ee45b16738501ba5c\&scene=21#wechat_redirect "知识文档处理和使用流程")),知识从原始材料到最终使用,主要会经历**离线和在线两个阶段**。 10 | 11 | - **离线阶段**是指,是把原始材料存入数据库的流程,这个阶段是离线处理的,所以被称为离线阶段; 12 | - **在现阶段**是指通过query被检索出来并且使用的,这就是在线阶段。 13 | 14 | 离线阶段会经历这几个过程: 15 | 16 | - **基础文档解析**:将各种形式的文档,转化可以容易处理模式,常见的是转为文本。 17 | - **内容理解**:从文档中提取各种重要信息,可以是关键词、实体、标签、摘要、切片等显式信息,也可以是embedding这种隐式信息。 18 | - **入库**:存到数据库中,做成方便检索的索引,供在线的搜索使用。 19 | 20 | 在线阶段会经历这几个过程: 21 | 22 | - **检索出库**:被搜索出来,从数据库中被取出。 23 | - **排序、判别、过滤**:对检索出来的知识进行进一步的筛选,选出最合适的备选知识。 24 | - **内容使用**:对检索出来的结果进行利用。 25 | 26 | 可以看到,整个流程和RAG相比只有最后一步略有不同,其他的情况都非常类似。 27 | 28 | 在线阶段本期先不讲,后面的章节会逐步展开,本文主要讲离线阶段的工作。 29 | 30 | ## 2.内容解析 31 | 32 | 离线阶段的工作就是把原始材料接入内部搜索引擎,这里的关键难题在于**原始材料的类型是多种多样的**,一般通用RAG的原始材料的来源是用户自主上传的文档,所以很多开源项目的工作重心都放在各种类型文档的解析([RAG开源项目Qanything源码阅读2-离线文件处理](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489699\&idx=1\&sn=95dc387b8935163b41035354518a182f\&chksm=e882403ddff5c92bb25d1741848503b91fe2cd1dc7fdd804684f888415a9acbb2fd17deab5f6\&scene=21#wechat_redirect "RAG开源项目Qanything源码阅读2-离线文件处理")),例如QAnything内就有大量针对pdf、doc、png等格式的处理,然而从搜索的角度看,输入的原始材料并不局限于此。 33 | 34 | 现在要说的,是另一种格式,那就是接口模式和HTML内容的接入。 35 | 36 | 接口模式大都来源于企业或者大团队之间的合作,在进行合作后,会有一些文档数据,会通过接口的方式接通,常见的就是通过http链接,通过批量的方式进行同步,举个例子: 37 | 38 | ```python 39 | import json,requests 40 | 41 | def run_client_info(url, query): 42 | response = requests.post("{}/info".format(url), json={"query": query}) 43 | return json.loads(response.text) 44 | ``` 45 | 46 | 此处是通过http请求一个接口,并将返回的内容转化为json,在python里就是dict类型,内部的数据就已经完成了读取。 47 | 48 | 另一种就是HTML内容接入,这种一般是通过网络爬虫的方式接入的,时至今日有些搜索引擎的爬虫(前排提醒,爬虫需要注意版权等法律风险),这里的内容很大概率就是html的格式,例如这个是百度热搜下一个条目的内容: 49 | 50 | ```html 51 |
52 | ``` 53 | 54 | 一般我们关注的是两个内容,一个是href下的链接方便进一步爬取,另一个是具体的文字内容,即“照见传承的两棵榕树”这部分,常见的html解析方案,大家可以参考`beautifulsoup`和`lxml`。 55 | 56 | ## 3.内容理解 57 | 58 | 内容理解,这次换个说法,内容理解的核心目的是**为了提升在线搜索的匹配效果**。我们原始获取、解析好的内容一般是混杂的,不规则的,而且很大概率和用户的搜索习惯并不匹配,直接使用很可能会搜不到,而如果对这些内容进行合适的处理,例如抽取一些关键词、关键标签,或者进行合理的切片、向量化,就能很大程度降低在线检索的压力,提升搜索的准确率和召回率,需要强调的是,**在线搜索的准召,并不只在于在线流程里的query理解、召回和排序,还需要关注离线的内容理解,内容理解如果有足够的优化,能降低在线准召很大的压力。** 59 | 60 | 这里讲两种最常见的内容理解手段,**标签抽取**和**向量化**,并对这俩内部的含义进行详细的扩展,让大家更能理解这两个方法在实际应用中的地位,以及具体实操需要关注的细节。 61 | 62 | ### 3.1 标签抽取 63 | 64 | 标签抽取式内容理解中很常见的方案,**为了更好地进行在线匹配,离线提前做好标签抽取,标签抽取可以配合query理解,让搜索快速达到高准确的效果**。 65 | 66 | 举个例子,对于音乐场景的搜索,用户的搜索习惯一般是输入歌手、歌名、专辑、风格、作曲人、作词人等,还有一些是歌词,这些内容多半有一个特点——标签化,用户输入“周杰伦”,那直接查“singer=‘周杰伦’”即可,而这里的前提就是,知识库内需要有这个字段,即结构化的信息,而有这个的前提是,需要从原有的内容里抽取。至于抽取的方法,在NLP领域这方面已经非常成熟,这就是一个NER(命名实体识别)或者是序列标注任务,当然如果有合适的词典,直接用词典匹配也可以轻松解决([我常说的词典匹配到底怎么做](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487674\&idx=1\&sn=d7c37cffab4b61ce08d0ddd8c26c0934\&chksm=e8824824dff5c132b530e6bc36fd980064be421cbc58f13fd77c5d76efa6234d669ea2123e5b\&scene=21#wechat_redirect "我常说的词典匹配到底怎么做"))。 67 | 68 | 这种针对性更强的思路相比于大家很常见的向量召回方案,有如下几个优点: 69 | 70 | - 准确率高。 71 | - 可解释性更强,可控性也比较高。 72 | - 因为直面用户搜索习惯,所以大盘效果和用户体验提升非常明显。 73 | 74 | 缺点也比较明显: 75 | 76 | - 离线工作增加,而且离线内容理解存在效果问题。 77 | - 定制化明显不通用。(但其实比较成熟的系统,有自己的NLP通用能力,可以把这种类似标签提取的任务通用化,也是可以的) 78 | 79 | 另外需要注意的是,标签抽取强依赖对用户习惯的洞察,要有目的地提取有效的标签,如果命中率低了,这点的意义肯定不会很大。 80 | 81 | ### 3.2 向量化 82 | 83 | 向量化应该是现在大家最容易想到(只能想到)的内容理解方法,这确实是一个比较通用的方案了,但实际上这里会有很多需要考量的因素,列举一些: 84 | 85 | - **向量化的依据是什么**,内容文本语义、用户行为、领域方向、划分粒度等。不同的向量化依据会衍生出不同的向量和匹配模式。 86 | - **目前的内容是否适合向量**,例如数字、地理位置这种,向量可能不是那么好的选择。 87 | - 即使适合,还有很多因素会影响向量的质量,例如长文本会稀释句子里的关键信息,从而无法被搜到或者总是被搜到。 88 | 89 | 可见,即使是向量化,背后的要考虑的内容还是会比较多的,现在仔细展开来讲。 90 | 91 | **向量化依据**,即,要把一个文档或者某个内容做向量化,是需要有参考依据的,否则和拿随机数做向量并无区别。来展开说下向量化可能的依据以及内部要考虑的细节: 92 | 93 | - **语义的向量**大家会比较熟悉,甚至现在已经有开源的模型可以直接使用。但相似的概念在具体业务视角可能并不相同,需要结合实际业务定义,可能要考虑做进一步的模型微调,当然包括QA匹配和QQ匹配等句子对是否对称的问题,需要根据这个合理选择或者拆解任务模型。 94 | - **用户行为的模型**。类似推荐系统里,有些用户行为或者高频的query,可以根据用户的点击行为,找到更喜欢被点击的内容,这个思路和协同过滤是类似的。 95 | - **对于语义空间差距比较大的多个领域**,模型统一处理的效果可能并不是很好,此时拆开是一个不错的选择,各自模型管各自的领域,对综合效果的提升也有收益。 96 | 97 | 第二个问题则是**向量模型的缺陷**,向量模型是有自己的优势和劣势的,并非所有方案都适合用向量,或者说向量模型并非万能,在使用过程中要警惕向量模型是否踩到了某些业务的痛点从而导致不可用。 98 | 99 | - **数字等比较特殊的数据类型**,现在的模型普遍对数字不够敏感,数字效果较差,如果是对数字比较重视的业务场景,向量模型可能并不那么适合。 100 | - **相似实体较多的场景**,像工业场景下的型号,差一个字可能差距很远的,化学、医学领域像氯化钠、氯化钾啥的,对向量模型而言会比较困难,相比之下不如考虑用标签提取的思路,可能会更加适合。 101 | 102 | 第三点则是**经验之谈**,有关向量的调优和问题的定位问题,例如长文本表征总会因为内容过多而被稀释或者忽略,此时相似度做起来就没那么容易,这个需要和切片之类的操作配合,实现更好的表征和检索。 103 | 104 | 最后强调一下,向量不仅为了通用,为了突破效果上限,真的很有必要精雕,通过任务拆细、微调的方式,对最终的召回质量提升会很明显,在系统搭建的后期会是重要的提升点。 105 | 106 | ### 3.3 其他操作 107 | 108 | 这里为了完整性,多提一些操作,为了方便检索提升召回率啥的,是可以进一步多去做一些挖掘工作的,这些活可能看起来比较脏,但做起来是真的有些收益,包括但不限于这些: 109 | 110 | - **切片尽量把内容缩短**,或者直接对长句做个摘要转化(用大模型)再来入库。 111 | - **多挖掘一些同义词、同义说法**,放一起检索有利于提升召回率。 112 | - **能结构化尽量结构化**,包括各种库表数据,不要着急合并成纯文本来做。 113 | 114 | ## 4.内容入库/索引 115 | 116 | 入库本质是个偏工程的活,但在实际应用过程,算法会高频修改这个,例如新增挖掘的字段,更新向量检索方案之类的,所以我个人是非常推荐大家尽可能去了解,甚至把这活一定程度把握到自己的手里,会更方便自己把事推进下去。 117 | 118 | 然后,因为搜索引擎目前发展的已经比较完整完善,所以此处更多是给大家推荐多种技术方案,方便大家进行选择,同时也很建议大家能系统学习。 119 | 120 | 因为入库是个数据工程,不同的数据量应该采取不同的方案,此处按照3个等级来给大家介绍。 121 | 122 | - 如果是千条以下数据,其实并没有什么必要上特别的数据库和数据结构,只要模型不大,逐个匹配的性能已经可以足够支撑,除非目前已经成为了明显短板,否则不用升级,常规的排序模型面对的差不多也就是这个数据量。 123 | - 如果是几十万以内的数据,目前机器的内存仍然吃得下,那单机方案也是可以支持的,简单的可以自己写一个倒排索引,类似向量召回则可以考虑FAISS、ngt、hnswlib等工具直接随着服务来弄即可。 124 | - 如果数据比较多,或者机器内存压力比较大,则要考虑分布式的中间件来做了,比较常用的例如ElasticSearch、Milvus等,都可以支撑检索,当然选型的时候要注意看各种数据库支持的索引,是否支持自己预期的那种,别到时候用一半发现自己需要的功能中间件不支持会很尴尬。 125 | 126 | 在此,给大家推荐几个比较合适的工具,建议大家系统学学: 127 | 128 | - **单机的向量检索库**,非常火的**FAISS**,然后**hnswlib**、**annoy**、**ngt**都非常推荐大家了解下。 129 | - python的字面索引生态好像不是很好,只知道woosh,如果大家还知道别的欢迎评论区推荐。 130 | - **分布式的中间件工具**,**ElasticSearch、Milvus比较常见,postgre、redis、mysql**等工具有空也建议大家学习下。 131 | - 互联网场景,数据比较多的,大数据生态也要了解,关键词有**hadoop、hdfs、hive、spark**(python版有pyspark)。 132 | 133 | ## 5.小结 134 | 135 | 本文主要讲搜索场景下对原始文档内容、知识的多种处理方案,在讲解方案的同时也给出了可能面对的问题以及方案思考的注意点,希望对大家有所帮助。 136 | 137 | 另外再次补充,之前写过两篇非常相似的文章,有些内容并未在本文出现,例如某些实操的细节,RAG场景的特定操作等,有兴趣可以继续阅读。 138 | 139 | - [心法利器\[110\] | 知识文档处理和使用流程](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489470\&idx=1\&sn=50f618e87545a1ef12e3480bd44e64f1\&chksm=e8824f20dff5c6365532bd45aa1853086014cad3bc31f5bbb73235da791ee45b16738501ba5c\&scene=21#wechat_redirect "心法利器\[110] | 知识文档处理和使用流程") 140 | - [前沿重器\[46\] RAG开源项目Qanything源码阅读2-离线文件处理](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489699\&idx=1\&sn=95dc387b8935163b41035354518a182f\&chksm=e882403ddff5c92bb25d1741848503b91fe2cd1dc7fdd804684f888415a9acbb2fd17deab5f6\&scene=21#wechat_redirect "前沿重器\[46] RAG开源项目Qanything源码阅读2-离线文件处理") 141 | -------------------------------------------------------------------------------- /docs/search/6.精排.md: -------------------------------------------------------------------------------- 1 | # 6.精排 2 | 3 | RAG在整个大模型技术栈里的重要性毋庸置疑,而在RAG中,除了大模型之外,另一个不可或缺的部分,就是搜索系统,大模型的正确、稳定、可控生成,离不开精准可靠的搜索系统,大量的实验中都有发现,在搜索系统足够准确的前提下,大模型的犯错情况会骤然下降,因此,更全面、系统地了解搜索系统将很重要。 4 | 5 | 本期的内容是精排,即对召回的内容进行进一步筛选,从而得到更好的结果。 6 | 7 | 这个可以说是最百花齐放的模块了,在实践过程中,搜索发展到后期这部分的花活就会变得异常多,无论是论文还是各种分享,但我发现论文和各种分享多半是从自身面对的场景出发的,因地制宜的成分很多,因此这次换个说法,先从思路下手,先把这部分的整体逻辑讲明白,然后再用一些案例来进行讲解。 8 | 9 | ## 1.精排的意义 10 | 11 | 所谓的精排,在整个搜索里,**核心功能是在获得召回结果的基础上,整理出精准的结果。**这里有一个前提,那就是在召回结果的基础上,没有召回的精排是没有意义的。 12 | 13 | 这里就要引出一个问题,就是两者会有什么区别。这个问题谈清楚了,大家就会明白精排在整个搜索过程中的作用。 14 | 15 | 最直接的,**召回和精排的对象是不一样的。召回面对的是整个数据库里的所有数据,而精排面对的是召回已经找回来的少量数据**,这是两者处理思路不同的核心原因。 16 | 17 | **召回是大海捞针,精排是百里挑一**。召回的过程类似筛简历,用一些比较粗暴的方式快速过滤很多“一定不对的内容”,从而得到相对不那么离谱的答案。类似向量召回之类的,要通过把句子向量化才能进行快速匹配和筛选,其本质就是在空间中以query为中心画个圈,只把圈内的内容拿出来;精排则像是面试,对几个简历还算不错的人进行进一步的筛选,这一步因为是进行深入面试和理解,尽管精排的准确性高但是速度慢,所以需要召回来进行配合。 18 | 19 | **精排的性质是优中选优**。继续从对象触发,精排面对的是召回已经找出的数据,这些数据从某个角度而言,已经被判为和query存在一定关系,但是随着物料的增加,“有一点关系”并不足够满足用户需求,所以要进行更精确的比对,因此此处要做的是进一步提升召回物料之间的差距。 20 | 21 | 另外,精排的综合性要求更高。召回层是可以基于很多不同的依据来分别做的,而精排则不然,需要尽可能把多个因素放一起综合地来做。 22 | 23 | ## 2.精排需要考虑的因素 24 | 25 | 前文有提到,**精排的综合性要求很高**,就需要考虑很多因素,相比召回,在这一步就要求考虑的很全面,现在先把需要考虑的因素用比较笼统的方式列举出来,然后再逐个剖析他们如何表征以及怎么放入模型中。 26 | 27 | - **和query的相关性**。这点毫无疑问应该排在前列,毕竟用户进行搜索的核心目标就是要解决query描述的问题,不相关的话搜索无从谈起。 28 | - **物料质量**。在物料已经比较多的情况下,就要开始考虑把质量比较高的物料放到前面。 29 | - **用户偏好**。在有用户信息的搜索系统下,或者因为业务需求,就需要将结合考虑到用户的偏好,比较典型的像音乐、电商等搜索场景,对个性化的要求就会比较高。 30 | 31 | **和query的相关性**,主要可以从这几个角度来去看。 32 | 33 | - **语义相似度**。这个大家应该都比较容易想到,早年比较流行的方式就是类似ESIM之类的方案来做([ESIM:语义相似度领域小模型的尊严](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247486697\&idx=2\&sn=186f232ff36593033e1e64b16043d3b6\&chksm=e8825477dff5dd615f67646a5690aa99155ceac4c150fa6d74bdb77bc3afe5b4170a73d6bc3a\&scene=21#wechat_redirect "ESIM:语义相似度领域小模型的尊严")),效果确实比非交互的相似度效果好,后续基于bert的句子对相似度也是不错的,而且训练的模式会比较简单,直接用‘q-d-label’的模式就能训练一个还可以的结果,在后续的版本中,迭代到learning to rank方案也比较丝滑。 34 | - **用户行为体现的相似度**。这个思路和推荐中用的点击率预估是非常相似的,用户搜Q点D,本质就是对内容一定程度的认可,甚至是更为直接的相似度信息,毕竟用户是对这个结果认可的。当然了,有些内容,即使不相关用户也可能点进去,例如某些猎奇或者不合规的内容。 35 | 36 | 至于**物料的质量**,这个可以从两个角度出发。 37 | 38 | - **物料本身的质量**。如话题、文案的合规性、丰富度、新鲜度等,这个会比较简单。 39 | - **用户群体对物料的评价**。如点击率、单位时间点击量、命中query丰富度、停留时间、点击离开率等,这些是基于用户行为对物料的评价。 40 | 41 | 最后就是**用户偏好**,应该也是后期需要花费时间比较多的一部分。 42 | 43 | - **多个维度的协同过滤的方式**。例如搜索这个query的用户更倾向于点击的内容、某个画像的用户更倾向于点击的内容(群体特征)、该用户平时的点击偏好(个人直接特征)等。 44 | 45 | 尽管上述的因素在生产实践中并不是按照这个来应用的,但因为特征来源广泛,往往还充斥着很多无效的信息。我所提出的上述思路更多是为了让大家更加结构化地理解整个精排内部所需要的信息,不容易错漏,相比一个一个比对,根据特定结构化思维来整理效率会更高。 46 | 47 | 当然,这只是我们常说的考虑因素,而**在实践过程,需要把上面考虑的因素,结合信息来源和使用方法,构造成适合应用的模式,即特征**,从而应用在精排模型中,于是就能推导出精排方案的框架。 48 | 49 | ## 3.精排方案的框架 50 | 51 | 常规的算法建模,不外乎要考虑的就是三点:**数据、特征、模型**。早期数据可以通过语义相似度或者是人工标注数据快速构造baseline,后续则逐步切换为在线用户的行为数据,此处不赘述,本章重点讲解后面两种。 52 | 53 | 在前面一章节讲到了需要考虑的因素,在实际应用情况,会把内容根据信息来源以及后续使用方法进行有机组合构建。 54 | 55 | 一般地,从数据来源来看,会把所有特征按照**4个维度**来构造。 56 | 57 | - **Query侧**:通过query理解来获取,常见的意图、实体包括某些关键词等。 58 | - **Doc侧**:即文档信息,一般通过内容理解,即在文档内容处理模块处理构造([聊聊搜索系统3:文档内容处理](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489797\&idx=1\&sn=842095bf602758dd3d56fb1297c59ded\&chksm=e882419bdff5c88d02634ced0a8bd2fbb497de9bf93cd6e2060919cb7c96087ec3aec5f88814\&scene=21#wechat_redirect "聊聊搜索系统3:文档内容处理")),这里包括一些类似物料质量、文档摘要等的内容。 59 | - **用户侧**:用户偏好信息,这个一般是在用户出现行为的过程就能记录,在推理过程一般只需要读取。 60 | - **交互特征**:Query和Doc之间的匹配度特征,注意这里是一些小特征,如某些计算得到的相似度,语义相似度、字面相似度等,还有一些统计得到的特征,如如历史的曝光点击率等,再者还有一些召回层带下来的信息,多种粗排的相似度特征,召回链路及其个数等。 61 | 62 | 有了这些特征就可以**开始构造模型把他们融合起来了**。合并的链路喜欢分为3个流派。 63 | 64 | - **规则加分模式**。在前期数据不足不好训练的情况下,直接对几个特征用规则进行简单组合即可使用,别小看这个方法,这个方案在很长一段时间都可以拿来使用。 65 | - **机器学习组合模式**。通过机器学习模型,例如比较有名的xgboost,可以快速把这些特征进行组合构造。 66 | - **深度学习及其变体**。因为特别的特征需要用特别的结构来吸纳,所以出现了多种魔改的特征,但效果确实在对应场景有所提升。 67 | 68 | 于是,便有了所期待的模型。 69 | 70 | 这便是我想聊的框架,数据、特征、模型的基础框架,构成搜索精排在实践过程的重要组成部分。在这个框架下,我们可以结合搜索当前的状态以及目前可获得的资源,来灵活设计自己目前需要的方案。 71 | 72 | - **数据是模型学习的基础**,是特征的原料。借助数据能发现可解释的规律,各种突出区分度的特征则是从数据筛选、分析而来。 73 | - **特征是数据依据的表达**,是query和doc匹配的信息来源。只有构造合理的特征,模型才会生效,所以他是数据依据的表达,同时q和d所谓的是否匹配, 74 | - **模型是数据的通用表示**,是特征有机组合完成推理的桥梁。 75 | 76 | ## 4.案例分析 77 | 78 | 相比列举方法,案例在这里可能会更合适,通过案例分析,尤其对他们面对的问题分析,让大家进一步理解“因地制宜”的重要性。 79 | 80 | ### 4.1 美团 81 | 82 | 美团的分享一直都维持的很好,在搜索方面也涌现了很多优秀的文章,具体可以在这里翻阅:[美团技术团队](https://www.zhihu.com/org/mei-tuan-dian-ping-ji-shu-tuan-dui "美团技术团队")。 83 | 84 | 本次要讲的精排,并非作为一个专题来讲,而是分布在很多文章内部,通过多篇文章的阅读才梳理出内部的一些细节。涉及这些关键文章: 85 | 86 | - 搜索广告召回技术在美团的实践:[https://zhuanlan.zhihu.com/p/707169501](https://zhuanlan.zhihu.com/p/707169501 "https://zhuanlan.zhihu.com/p/707169501") 87 | - 大众点评内容搜索算法优化的探索与实践:[https://zhuanlan.zhihu.com/p/688404734](https://zhuanlan.zhihu.com/p/688404734 "https://zhuanlan.zhihu.com/p/688404734") 88 | - 多业务建模在美团搜索排序中的实践:[https://zhuanlan.zhihu.com/p/388211657](https://zhuanlan.zhihu.com/p/388211657 "https://zhuanlan.zhihu.com/p/388211657") 89 | - Transformer 在美团搜索排序中的实践:[https://zhuanlan.zhihu.com/p/131590390](https://zhuanlan.zhihu.com/p/131590390 "https://zhuanlan.zhihu.com/p/131590390") 90 | 91 | 美团搜索毫无疑问是一个非常具有特点的场景,结合众多技术文章的分析来看,美团搜索在场景上,具有如下的特点: 92 | 93 | - 特殊的多业务场景。美食、电影、机票、酒店等个典型场景聚合,显然这种聚合和一般地百度开放域搜索还不太一样,业务场景各异,且各自之间存在高低频的差异,再者不同业务还可能有不同的子目标。 94 | - 和电商类似,用户在输入习惯上,可能有大量的内容聚焦在特定的专有名词或者tag上,如“烧烤”、“麦当劳”等。 95 | - 检索需要很大程度以来用户画像信息。典型的例子——地点,美团是一个高度依赖地点的场景,美团的几乎所有场景在用户检索时都很大程度依赖地点信息,用户搜索的“烧烤”就需要很大程度地参考地点信息,当然还有别的类似用户个人偏好等也有结合实际场景的依赖,例如美食对口味有依赖等。 96 | 97 | 结合上面特点,美团也进行了大量的特别设计。 98 | 99 | 首先是特殊的多业务场景,构造了**多业务配额模型(Multi-Business Quota Model,MQM)**以确认综合搜索下各个业务的配额,有利于他们的有机组合。下面提供了MQM-V2的结构图,从图中可以看到: 100 | 101 | - 采用多目标的建模方式,以每一路召回是否被点击为目标进行建模,并计算他们整体的联合概率。 102 | - 引入了按业务拆分的召回方式,同时这些召回方式在精排内存在一定冷启动需求,所以构造了二维目标应对这种冷启动问题。 103 | - 此处的特征考虑了query、user、context、cross等特征。 104 | - 用户行为建模上,使用的是transformers结构。 105 | 106 | ![](image/image_XVxR0bMHFn.png) 107 | 108 | > MQM-V2 模型结构图 109 | 110 | 另外,**多业务的精排模型(Multi-Business Network,MBN)**也根据这个场景问题进行了特别的优化,下面给出的是精排模型V4的结构。可以看到有如下特点: 111 | 112 | - 最下游子模块各自建模,应对不同的业务需求,形成快速、独立迭代能力。 113 | - 此处特殊的是CGC层,这是一种多任务学习下的思路,来源于腾讯提出的PLE(Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized Recommendations),考虑多个专家的模式应对不同场景的问题。(补充,在V3版本中有考虑过MMOE(Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts))(再补充,注意这篇文章的时间线是21年7月,即3年前) 114 | - 值得注意的是,这里单独把POI特征给单独拿了出来做表征。 115 | 116 | ![](image/image_faaG_kkI8R.png) 117 | 118 | > MBN-V4 模型结构图 119 | 120 | 至于第二点,就是用户比较喜欢输入tag、专名的问题,其实在特征工程上就能发现,在query特征之外,还考虑到了大量其他的特征,尤其是user、poi等特征,特别地针对用户兴趣建模,也是有专门的设计。这里比较有特点的是考虑了transformers结构,此处给出一个美团曾经使用过的一种结构(Transformer\&Deep),这篇一定程度参考了AutoInt(Automatic Feature Interaction Learning via Self-Attentive Neural Networks) 121 | 122 | ![](image/image_iYqSeUzGYk.png) 123 | 124 | > Transformer\&Deep 125 | 126 | 至于最后一点,就是用户画像信息的使用,这点承接第二点,从上述模型来看,美团在用户信息表征上做了很多研究工作,尤其是用户的个人行为,毕竟用户行为很大程度反映了用户的偏好,这里给出第三版本的用户行为建模网络。同时友好的是,作者在文章里讲述了很多transformer应用的经验。 127 | 128 | - 实验表明Transformer能更好地对用户行为(item序列)进行有效建模,甚至由于相对简单的Attention-pooling。 129 | - 长序列下Transformer对比GRU优势会更明显,短序列尽管会缩小但仍旧优秀。 130 | - 位置编码对长序列有一定效果,但如果已经切分,则效果会被大幅度削弱。 131 | - Transformer编码层不需要太多。 132 | - “头”的个数影响不大。 133 | 134 | ![](image/image_WGZTznvdV9.png) 135 | 136 | > 用户行为建模网络-V3 137 | 138 | ### 4.2 知乎 139 | 140 | 相比美团,知乎更像是传统意义的搜索,其主要的物料基本是用户UGC的问答和博客文章,知乎在搜索精排上的迭代发展,也表现出这一特点,而且这个过程会更加纯粹,对用户的参考会更少一些,通过分析可以看到比较纯粹的搜索精排优化,我们来看一起看看。[https://mp.weixin.qq.com/s/DZZ\_BCiNw0EZg7V0KvhXVw](https://mp.weixin.qq.com/s/DZZ_BCiNw0EZg7V0KvhXVw "https://mp.weixin.qq.com/s/DZZ_BCiNw0EZg7V0KvhXVw") 141 | 142 | 直接从整个优化历程来逐个分析。 143 | 144 | GBDT。GBDT具备比较基础的特征融合能力,也是比较高的baseline。这应该是很多搜索系统常见的基础工作了。 145 | 146 | TF-Ranking。考虑特征容量和技术迭代,以及多目标排序原因,而升级DNN,同时形成了比较规范的特征输入模块、特征转化模块和主网络部分。 147 | 148 | ![](image/image_uJ0fQLzMd7.png) 149 | 150 | > TF-Ranking 151 | 152 | 主网络下,开始考虑多目标排序,权衡阅读时长、点赞、收藏、分享、评论等反馈行为,简单的考虑共享参数层+任务独立参数层的结构来完成(文章中使用Hard sharing来表示)(类似前面美团提到的多业务配额模型),该方式需要通过实验的方式来权衡多目标之间的关系,后面则优化升级为MMOE(Modeling task relationships in multi-task learning with multi-gate mixture-of-experts.),即多个expert加权的方式,权重任务间共享又让任务之间存在独立性。 153 | 154 | 考虑搜索中常见的位置偏差(用户浏览行为是从上到下,因此靠前的更容易得到点击),这方面推荐中也是有的,因此优化方案上也存在一些推荐系统的影子,此处考虑两个策略: 155 | 156 | - 降低头部样本权重,如硬编码位置权重、自学习位置权重等。该方案收益不高。 157 | - 通过一个独立的 shallow tower 对 Position Bias 进行建模(Recommending what video to watch next: a multitask ranking system)。如前面的TF-Ranking的图中提到的(Card position)部分。 158 | 159 | **学习排序问题**。前面一再强调,精排是一个优中选优的对比问题,而这类型的问题,在学术界也有专门的研究,即learning to rank(LTR,之前我竟然还写过点简单的入门,很早之前了 [学习排序入门级概述](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247484897\&idx=1\&sn=18f855802c0a82c15e2c8b30623d81d2\&chksm=e8825d7fdff5d4697efcbcb2ac9fe71b0774704b0bafe9419b6e7ba0b45530cfb532ebf4f2eb\&scene=21#wechat_redirect "学习排序入门级概述")),此处考虑使用List wise loss方案(综合效果最优),在推理阶段同样要考虑到list wise,即在对单条打分的同时也要考虑其他被召回的文档,此处使用的是SE Block的结构(Squeeze-and-excitation networks.)。 160 | 161 | 文本特征也是需要考虑的。比较简单的方式就是先计算一个语义相似度然后把语义相似度当做特征放入模型,而比较详细的方案就是直接把语义模型(如bert)放入到LTR中进行训练,甚至是整体模型中进行训练。 162 | 163 | 另外还有一些诸如个性化、GBDT编码特征、生成对抗模型、在线学习等思路在文中也有简单提到,不赘述。 164 | 165 | ## 5.重排 166 | 167 | 重排是基于业务的一个特殊排序阶段,和推荐类似,很多时候精排考虑的更多的还是query+用户画像和doc之间的匹配度,但在**重排阶段还需要考虑实际的业务需求**,如多样性、内容连贯性等,例如常规的相似度的排序结果在搜索里面很可能会出现同质化,此时就需要通过重排来一定程度实现更符合业务目标的排序。 168 | 169 | 这里提3个比较常用的重排策略([https://www.zhihu.com/question/462539445/answer/3079023802)。](https://www.zhihu.com/question/462539445/answer/3079023802%EF%BC%89%E3%80%82 "https://www.zhihu.com/question/462539445/answer/3079023802)。") 170 | 171 | - **全局排序**:listwise策略,这个同样是LTR的内容,采用诸如序列生成的方式,输出一个用户体验最好的内容序列。 172 | - **流量调控**:在重排层,借助流量的调控,把热门、新品等有利因素的物料往前倾斜。 173 | - **打散策略**:在一定窗口下,通过惩罚的方式把某些过于同质的内容往后调整。 174 | 175 | 当然,这里的策略都有提到一个点,这些重排策略或多或少都有提到目标,从目标出发解决问题才更直接,不能因为的新颖性或者自己新学到而迫切考虑使用。 176 | 177 | ## 6.大模型精排 178 | 179 | 有关大模型的精排部分,是有在阅读一些论文并进行一些常识。不过在实践上收益其实并不高,初步结论是“用处不大没必要硬用”,当然这个也有待进一步探索。目前是发现在精排层会有如下问题。 180 | 181 | - 由于特征的稀疏性、表征连续性、上下文信息等问题,这些特征很难通过prompt的形式有效输入,尤其是后期比较完善的系统。 182 | - 实验表现上,输入大模型的数据顺序对最终决策的影响还是比较大。 183 | - 上限很难打过现有比较完善的精排模型。 184 | - 老生常谈了,大模型的成本和更新敏捷度问题。 185 | 186 | 但值得注意的是,在比较早期,特征不多也不复杂的情况下,可以暂时充当精排模块,但也只是暂时,在同一时期只要有比较好的语义相似度模型(甚至粗排的语义表征相似度),也有可能超过简单基于prompt的大模型。 187 | 188 | ## 7.小结 189 | 190 | 精排是搜索后期优化的重点部分了,结合大厂走在前面的先决条件,精排方面的分享、论文都很多,所以本文聊下来挺容易刹不住车的,但我还是聚焦于精排研发的常用思路,方便大家把零散的内容给串起来,同时,精排以及重排是最接近用户的一部分了,因此和用户习惯、业务需求关系最为紧密,我们在进行分析的过程,还是需要多看case,多剖析用户习惯,从而实现更优秀的精排效果。 191 | 192 | -------------------------------------------------------------------------------- /docs/search/7.补充模块.md: -------------------------------------------------------------------------------- 1 | # 7.补充模块 2 | 3 | RAG在整个大模型技术栈里的重要性毋庸置疑,而在RAG中,除了大模型之外,另一个不可或缺的部分,就是搜索系统,大模型的正确、稳定、可控生成,离不开精准可靠的搜索系统,大量的实验中都有发现,在搜索系统足够准确的前提下,大模型的犯错情况会骤然下降,因此,更全面、系统地了解搜索系统将很重要。 4 | 5 | 本期的内容是搜索的其他附加模块,重点讲几个和搜索有关的场景以及常见的解决方案。这篇文章比较轻松,都是一些概念和思路解释,只是补充说明一些可能会被忽略的内容。 6 | 7 | ## 1.搜索引导 8 | 9 | 搜索引导在很早之前我有讲过:[美团搜索引导技术启示](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247487129\&idx=1\&sn=0c8a249b365caca3715123a7a9afc894\&chksm=e8825607dff5df1166865c3e867ef3edff6f4a338544626dbdc4b35a8a7c49b7aba1da8eb855\&scene=21#wechat_redirect "美团搜索引导技术启示"),这个内容比较完整的讲解,可以参考《美团机器学习实践》的8.3。 10 | 11 | 搜索引导是指在用户搜索过程中给用户提供引导的统称,具体可以分为3种,搜索前、搜索中、搜索后引导,3个的内部所用的技术因为信息不同所以具体的技术方案会有所不同。这个“引导”,简单的理解,就是给用户进行query推荐。 12 | 13 | - 搜索前,往往是根据用户的画像以及目前的新热内容进行推荐,常见的在搜索框下“猜你喜欢”、或者是预填在搜索框内的内容。 14 | - 搜索中,指搜索过程中,用户输入一半时,下方出现的推荐内容,主要是根据用户已经输入的内容进行预想。 15 | - 搜索后,指用户点击确定后,还给他推荐的一些相关的query。 16 | 17 | ![](image/image_mpuobqHvS-.png) 18 | 19 | 下面展开聊一聊这3个内容的具体场景细节和常见技术,只是简单聊不会展开。 20 | 21 | ### 1.1 搜索前 22 | 23 | 搜索前引导是没什么先验信息的,因此**更多是推荐性质的**,再者搜索界面往往比较空,里面会放很多东西。主要思路如下: 24 | 25 | - 新、热信息,推荐常态了。 26 | - 根据用户画像进行推荐,就当做推荐系统来做。 27 | - 用户搜索历史。 28 | 29 | ### 1.2 搜索中 30 | 31 | 搜索过程中,用户已经输入了部分内容,此时的用户注意力基本聚焦在自己想输入的query上,所以这个时候没必要做太多复杂多样的工作,**给出比较贴合目前用户输入内容的提示会比较好**,主要思路如下: 32 | 33 | - 用前缀树等方式,基于前缀召回一些高度相关、高质量、高点击的内容。 34 | - 可以适当进行个性化。 35 | - 但是请注意,此处的时延要求很高,必须尽快出,卡顿的时间内用户可能已经输入很多内容,尤其是pc端web段。 36 | 37 | ### 1.3 搜索后 38 | 39 | 搜索后,又回到了类似搜索前的状态,但与之不同的是此时用户已经有用户query,所以**可以结合用户query做一些额外的尝**试: 40 | 41 | - 给出一些和用户query相似的句子,但检索出来的内容质量比较高(例如高有点率,即别的用户有点击的概率)。 42 | - 搜了这些query的用户还搜了XX,用这个思路来找回,类似协同过滤了。 43 | 44 | 这个搜索引导的任务会挺适合做一种训练,就是根据问题思考问题特点并提出特定技术方案的训练,整个产品快速理解产品需求、用户习惯等,这些分析和探索的思维模式,非常值得吸收,大家也可以循着我的思路再过一遍。 45 | 46 | ## 2.搜索广告 47 | 48 | 广告是现在互联网非常常见的模式,搜索广告应该也不少见。 49 | 50 | ![](image/image_LpWtTTda_N.png) 51 | 52 | 搜索广告目前需要考虑的内容: 53 | 54 | - 搜索广告和推荐广告,跟搜索和推荐的类似,搜索广告是需要结合用户query的,给出的内容大概率要和query比较相关。这个是核心点。 55 | - 相比搜索和推荐,广告本质是3方的权衡,用户、平台和广告方,而当考虑广告方收益后,用户的利益大概率要被一定程度牺牲。 56 | - 广告商要求精准投放,对特定用户投放才会有效,用户视角对相关的内容反感度也不会很高,因此在匹配度和精准度上,各方的目标还是相对一致的。 57 | 58 | 因此,在权衡全局利益下,搜索广告的整体思路如下: 59 | 60 | - **搜索广告考虑一定程度query相似度**,否则投放质量和用户体验都会下降明显,所以query理解的相关工作仍旧需要做。 61 | - **广告物料肯定远不如用户生成或者已有文档的数量多,所以搜索广告在召回层的要求需要一定程度下降。** 62 | - 精排和重排层,结合广告投放价值等进行综合排序。 63 | 64 | ## 3.大模型 65 | 66 | 大模型时代来临,大模型想必是大家关心的重点,所以也单独拿出来说说自己的理解。大模型能助力搜索系统进行进一步提升,同时对于新的搜索系统,也很大程度降低早期启动时间。下面分几个情况来讨论大模型在搜索中的应用情况。 67 | 68 | - **离线文档处理**:大模型的核心优势是few-shot甚至zero-shot的高baseline能力,在文档处理内,需要对文档内进行特定的关键词、实体、摘要进行抽取,大模型是一个非常快速的方案。 69 | - **query理解**:用大模型来做分类、实体抽取之类的任务已经是不是一个困难的事了,至少能省去很多标注的成本,或者是通过大模型来做粗标,无论如何从这个角度来讲,算是一个启动捷径。另外,大模型来做query拓展,收益也不低([微软新文query2doc:用大模型做query检索拓展](http://mp.weixin.qq.com/s?__biz=MzIzMzYwNzY2NQ==\&mid=2247489295\&idx=1\&sn=fcb269e47dc27fcaf31201aa1c75dafb\&chksm=e8824f91dff5c687a3a95d18490c8d2ba9b18d1b7cd5bc614e01ef3d7dd6d72aa62bcc0c2b0d\&scene=21#wechat_redirect "微软新文query2doc:用大模型做query检索拓展"))。 70 | - **召回**:召回层一般是直接做检索,在相似度上大模型的工作还需要探究,当然借助大模型做向量化的工作也不是没有,不过类似BGE-M3之类的操作,可能收益会比较高,直接用大模型的收益不如转为用大模型做拓展然后向量化。 71 | - **精排**:大模型做精排在早期还是可以尝试的,不过到了后期,还是不如特征之类比较成熟的方式,特征的有机组合和迭代节奏上有优势,且上限也不低。大模型在多特征多信息的环境下还是有些难度,可能会吃不下或者理解不了。 72 | 73 | 总的来说,大模型在这里的应用有如下特点: 74 | 75 | - 有比较高的baseline,在数据匮乏,无法训练自有模型的时候,可以考虑大模型启动。 76 | - 但是到了后期,很多问题可以用小模型替代,效果和性能可能还能提升,成本下降。 77 | 78 | 这里再补充一个点,可能会有人问到RAG,这里可以看出,大模型和搜索系统是相辅相成互相帮助的关系了,大模型用在搜索系统里能对搜索系统产生正面作用,而反过来,搜索系统在RAG中能快速查出对大模型有用的信息。 79 | 80 | ## 4.小结 81 | 82 | 本文主要对系列内没提到但比较重要的部分进行补充说明,主要讲的是搜索引导、搜索广告、大模型相关部分。 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/search/README.md: -------------------------------------------------------------------------------- 1 | # 搜索系统 2 | 3 | > 文章摘自: 4 | > - 作者:叉烧 5 | > - 链接:[四万字聊搜索系统](https://mp.weixin.qq.com/s/QhehI1WFCJ6R-5yAatFSFQ "四万字聊搜索系统") 6 | 7 | ### 简介 8 | 9 | - 开篇语(本期):给大家简单介绍一下搜索系统的概况,以及现在大家比较关注在大模型领域的发展情况。 10 | - 搜索系统的常见架构:经过多代人的探索,目前探索出相对成熟可靠,适配多个场景、人力、生产迭代等因素的综合性方案。 11 | - 文档内容处理:对原始文档内容、知识的多种处理方案。 12 | - Query理解:对query内容进行解析,方便后续检索使用。 13 | - 索引和检索、粗排:使用query理解的结果,从海量数据中找到所需的信息。 14 | - 精排:对检索的内容进行进一步的精筛,提升返回的准确性。 15 | - 其他搜索的附加模块:补充说明一些和搜索有关的模块 16 | 17 | ### 主要内容 18 | 19 | - [1.开篇语](docs/search/1.开篇语.md) 20 | - [2.常见架构](docs/search/2.常见架构.md) 21 | - [3.文档内容处理](docs/search/3.文档内容处理.md) 22 | - [4.query理解](docs/search/4.query理解.md) 23 | - [5.召回:检索、粗排、多路召回](docs/search/5.召回:检索、粗排、多路召回.md) 24 | - [6.精排](docs/search/6.精排.md) 25 | - [7.补充模块](docs/search/7.补充模块.md) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/search/image/image_2NnOFonb0B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_2NnOFonb0B.png -------------------------------------------------------------------------------- /docs/search/image/image_6HwW7szTAZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_6HwW7szTAZ.png -------------------------------------------------------------------------------- /docs/search/image/image_6YYlfq3Qj6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_6YYlfq3Qj6.png -------------------------------------------------------------------------------- /docs/search/image/image_83LuygiASf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_83LuygiASf.png -------------------------------------------------------------------------------- /docs/search/image/image_AWm29bJAD1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_AWm29bJAD1.png -------------------------------------------------------------------------------- /docs/search/image/image_BrSNasOa0G.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_BrSNasOa0G.png -------------------------------------------------------------------------------- /docs/search/image/image_EPp4qqExAg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_EPp4qqExAg.png -------------------------------------------------------------------------------- /docs/search/image/image_LpWtTTda_N.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_LpWtTTda_N.png -------------------------------------------------------------------------------- /docs/search/image/image_TmG08B6YFp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_TmG08B6YFp.png -------------------------------------------------------------------------------- /docs/search/image/image_WGZTznvdV9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_WGZTznvdV9.png -------------------------------------------------------------------------------- /docs/search/image/image_XVxR0bMHFn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_XVxR0bMHFn.png -------------------------------------------------------------------------------- /docs/search/image/image_faaG_kkI8R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_faaG_kkI8R.png -------------------------------------------------------------------------------- /docs/search/image/image_hG8wpp_-sk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_hG8wpp_-sk.png -------------------------------------------------------------------------------- /docs/search/image/image_iYqSeUzGYk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_iYqSeUzGYk.png -------------------------------------------------------------------------------- /docs/search/image/image_mpuobqHvS-.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_mpuobqHvS-.png -------------------------------------------------------------------------------- /docs/search/image/image_n9zXOmxs4T.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_n9zXOmxs4T.png -------------------------------------------------------------------------------- /docs/search/image/image_rkvExLW81V.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_rkvExLW81V.png -------------------------------------------------------------------------------- /docs/search/image/image_uJ0fQLzMd7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_uJ0fQLzMd7.png -------------------------------------------------------------------------------- /docs/search/image/image_waQQM4WyMr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wdndev/ai_interview_note/225afb568d62a8e21fc20d5c99fda5a75b104057/docs/search/image/image_waQQM4WyMr.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | --------------------------------------------------------------------------------