数学基础
- 线性代数
- 概率论与随机过程
- 数值计算
- 蒙特卡洛方法与 MCMC 采样
- 机器学习方法概论
统计学习
深度学习
- 深度学习简介
- 深度前馈网络
- 反向传播算法
- 正则化
- 深度学习中的最优化问题
- 卷积神经网络
- CNN:图像分类
- 循环神经网络 RNN
- Transformer
- 一、Transformer [2017]
- 二、Universal Transformer [2018]
- 三、Transformer-XL [2019]
- 四、GPT1 [2018]
- 五、GPT2 [2019]
- 六、GPT3 [2020]
- 七、OPT [2022]
- 八、BERT [2018]
- 九、XLNet [2019]
- 十、RoBERTa [2019]
- 十一、ERNIE 1.0 [2019]
- 十二、ERNIE 2.0 [2019]
- 十三、ERNIE 3.0 [2021]
- 十四、ERNIE-Huawei [2019]
- 十五、MT-DNN [2019]
- 十六、BART [2019]
- 十七、mBART [2020]
- 十八、SpanBERT [2019]
- 十九、ALBERT [2019]
- 二十、UniLM [2019]
- 二十一、MASS [2019]
- 二十二、MacBERT [2019]
- 二十三、Fine-Tuning Language Models from Human Preferences [2019]
- 二十四 Learning to summarize from human feedback [2020]
- 二十五、InstructGPT [2022]
- 二十六、T5 [2020]
- 二十七、mT5 [2020]
- 二十八、ExT5 [2021]
- 二十九、Muppet [2021]
- 三十、Self-Attention with Relative Position Representations [2018]
- 三十一、USE [2018]
- 三十二、Sentence-BERT [2019]
- 三十三、SimCSE [2021]
- 三十四、BERT-Flow [2020]
- 三十五、BERT-Whitening [2021]
- 三十六、Comparing the Geometry of BERT, ELMo, and GPT-2 Embeddings [2019]
- 三十七、CERT [2020]
- 三十八、DeCLUTR [2020]
- 三十九、CLEAR [2020]
- 四十、ConSERT [2021]
- 四十一、Sentence-T5 [2021]
- 四十二、ULMFiT [2018]
- 四十三、Scaling Laws for Neural Language Models [2020]
- 四十四、Chinchilla [2022]
- 四十七、GLM-130B [2022]
- 四十八、GPT-NeoX-20B [2022]
- 四十九、Bloom [2022]
- 五十、PaLM [2022] (粗读)
- 五十一、PaLM2 [2023](粗读)
- 五十二、Self-Instruct [2022]
- 句子向量
- 词向量
- 传统CTR 预估模型
- CTR 预估模型
- 一、DSSM [2013]
- 二、FNN [2016]
- 三、PNN [2016]
- 四、DeepCrossing [2016]
- 五、Wide 和 Deep [2016]
- 六、DCN [2017]
- 七、DeepFM [2017]
- 八、NFM [2017]
- 九、AFM [2017]
- 十、xDeepFM [2018]
- 十一、ESMM [2018]
- 十二、DIN [2017]
- 十三、DIEN [2019]
- 十四、DSIN [2019]
- 十五、DICM [2017]
- 十六、DeepMCP [2019]
- 十七、MIMN [2019]
- 十八、DMR [2020]
- 十九、MiNet [2020]
- 二十、DSTN [2019]
- 二十一、BST [2019]
- 二十二、SIM [2020]
- 二十三、ESM2 [2019]
- 二十四、MV-DNN [2015]
- 二十五、CAN [2020]
- 二十六、AutoInt [2018]
- 二十七、Fi-GNN [2019]
- 二十八、FwFM [2018]
- 二十九、FM2 [2021]
- 三十、FiBiNET [2019]
- 三十一、AutoFIS [2020]
- 三十三、AFN [2020]
- 三十四、FGCNN [2019]
- 三十五、AutoCross [2019]
- 三十六、InterHAt [2020]
- 三十七、xDeepInt [2023]
- 三十九、AutoDis [2021]
- 四十、MDE [2020]
- 四十一、NIS [2020]
- 四十二、AutoEmb [2020]
- 四十三、AutoDim [2021]
- 四十四、PEP [2021]
- 四十五、DeepLight [2021]
- 图的表达
- 一、DeepWalk [2014]
- 二、LINE [2015]
- 三、GraRep [2015]
- 四、TADW [2015]
- 五、DNGR [2016]
- 六、Node2Vec [2016]
- 七、WALKLETS [2016]
- 八、SDNE [2016]
- 九、CANE [2017]
- 十、EOE [2017]
- 十一、metapath2vec [2017]
- 十二、GraphGAN [2018]
- 十三、struc2vec [2017]
- 十四、GraphWave [2018]
- 十五、NetMF [2017]
- 十六、NetSMF [2019]
- 十七、PTE [2015]
- 十八、HNE [2015]
- 十九、AANE [2017]
- 二十、LANE [2017]
- 二十一、MVE [2017]
- 二十二、PMNE [2017]
- 二十三、ANRL [2018]
- 二十四、DANE [2018]
- 二十五、HERec [2018]
- 二十六、GATNE [2019]
- 二十七、MNE [2018]
- 二十八、MVN2VEC [2018]
- 二十九、SNE [2018]
- 三十、ProNE [2019]
- Graph Embedding 综述
- 图神经网络
- 一、GNN [2009]
- 二、Spectral Networks 和 Deep Locally Connected Networks [2013]
- 三、Fast Localized Spectral Filtering On Graph [2016]
- 四、GCN [2016]
- 五、神经图指纹 [2015]
- 六、GGS-NN [2016]
- 七、PATCHY-SAN [2016]
- 八、GraphSAGE [2017]
- 九、GAT [2017]
- 十、R-GCN [2017]
- 十一、 AGCN [2018]
- 十二、FastGCN [2018]
- 十三、PinSage [2018]
- 十四、GCMC [2017]
- 十五、JK-Net [2018]
- 十六、PPNP [2018]
- 十七、VRGCN [2017]
- 十八、ClusterGCN [2019]
- 十九、LDS-GNN [2019]
- 二十、DIAL-GNN [2019]
- 二十一、HAN [2019]
- 二十二、HetGNN [2019]
- 二十三、HGT [2020]
- 二十四、GPT-GNN [2020]
- 二十五、Geom-GCN [2020]
- 二十六、Graph Network [2018]
- 二十七、GIN [2019]
- 二十八、MPNN [2017]
- 二十九、UniMP [2020]
- 三十、Correct and Smooth [2020]
- 三十一、LGCN [2018]
- 三十二、DGCNN [2018]
- 三十三、AS-GCN
- 三十四、DGI [2018]
- 三十五、DIFFPOLL [2018]
- 三十六、DCNN [2016]
- 三十七、IN [2016]
- 图神经网络 2
- 图神经网络 3
- 推荐算法(传统方法)
- 一、Tapestry [1992]
- 二、GroupLens [1994]
- 三、ItemBased CF [2001]
- 四、Amazon I-2-I CF [2003]
- 五、Slope One Rating-Based CF [2005]
- 六、Bipartite Network Projection [2007]
- 七、Implicit Feedback CF [2008]
- 八、PMF [2008]
- 九、SVD++ [2008]
- 十、MMMF 扩展 [2008]
- 十一、OCCF [2008]
- 十二、BPR [2009]
- 十三、MF for RS [2009]
- 十四、 Netflix BellKor Solution [2009]
- 推荐算法(神经网络方法 1)
- 一、MIND [2019](用于召回)
- 二、DNN For YouTube [2016]
- 三、Recommending What Video to Watch Next [2019]
- 四、ESAM [2020]
- 五、Facebook Embedding Based Retrieval [2020](用于检索)
- 六、Airbnb Search Ranking [2018]
- 七、MOBIUS [2019](用于召回)
- 八、TDM [2018](用于检索)
- 九、DR [2020](用于检索)
- 十、JTM [2019](用于检索)
- 十一、Pinterest Recommender System [2017]
- 十二、DLRM [2019]
- 十三、Applying Deep Learning To Airbnb Search [2018]
- 十四、Improving Deep Learning For Airbnb Search [2020]
- 十五、HOP-Rec [2018]
- 十六、NCF [2017]
- 十七、NGCF [2019]
- 十八、LightGCN [2020]
- 十九、Sampling-Bias-Corrected Neural Modeling [2019](检索)
- 二十、EGES [2018](Matching 阶段)
- 二十一、SDM [2019](Matching 阶段)
- 二十二、COLD [2020 ] (Pre-Ranking 模型)
- 二十三、ComiRec [2020](https://www.wenjiangs.com/doc/0b4e1736-ac78)
- 二十四、EdgeRec [2020]
- 二十五、DPSR [2020](检索)
- 二十六、PDN [2021](mathcing)
- 二十七、时空周期兴趣学习网络ST-PIL [2021]
- 推荐算法之序列推荐
- 一、FPMC [2010]
- 二、GRU4Rec [2015]
- 三、HRM [2015]
- 四、DREAM [2016]
- 五、Improved GRU4Rec [2016]
- 六、NARM [2017]
- 七、HRNN [2017]
- 八、RRN [2017]
- 九、Caser [2018]
- 十、p-RNN [2016]
- 十一、GRU4Rec Top-k Gains [2018]
- 十二、SASRec [2018]
- 十三、RUM [2018]
- 十四、SHAN [2018]
- 十五、Phased LSTM [2016]
- 十六、Time-LSTM [2017]
- 十七、STAMP [2018]
- 十八、Latent Cross [2018]
- 十九、CSRM [2019]
- 二十、SR-GNN [2019]
- 二十一、GC-SAN [2019]
- 二十二、BERT4Rec [2019]
- 二十三、MCPRN [2019]
- 二十四、RepeatNet [2019]
- 二十五、LINet(2019)
- 二十六、NextItNet [2019]
- 二十七、GCE-GNN [2020]
- 二十八、LESSR [2020]
- 二十九、HyperRec [2020]
- 三十、DHCN [2021]
- 三十一、TiSASRec [2020]
- 推荐算法(综述)
- 多任务学习
- 系统架构
- 实践方法论
- 深度强化学习 1
- 自动代码生成
工具
- CRF
- lightgbm
- xgboost
- scikit-learn
- spark
- numpy
- matplotlib
- pandas
- huggingface_transformer
- 一、Tokenizer
- 二、Datasets
- 三、Model
- 四、Trainer
- 五、Evaluator
- 六、Pipeline
- 七、Accelerate
- 八、Autoclass
- 九、应用
- 十、Gradio
Scala
- 环境搭建
- 基础知识
- 函数
- 类
- 样例类和模式匹配
- 测试和注解
- 集合 collection(一)
- 集合collection(二)
- 集成 Java
- 并发
十三、其它不可变集合
Scala
提供了很多具体的不可变集合类,它们实现的特质各不相同(Map,Set,Sequence
),可以是无限的也可以是有限的。List
是有限的不可变序列。它提供 $ O(1) $ 时间的对首个元素和剩余元素的访问,以及 $ O(1) $ 时间的在列表头部新增元素的操作。其它很多操作都是 $ O(n) $ 时间的。Stream
和列表很像,不过其元素都是惰性的。因此,Stream
是无限长的,只有被请求到的元素才会被计算。除此之外,流的特性和List
是一样的。列表通过
::
操作符构造,而流是通过#::
来构造:xxxxxxxxxx
val str = 1 #:: 2 #:: 3 #:: Stream.emtpy流的基本要求是惰性计算,因此它的
toString
方法并不会强制任何额外的求值计算,只会给出头部的结果。如上面的str
的.toString
为Stream(1. ?)
。下面是一个更复杂的例子:
xxxxxxxxxx
def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b)需要说明的是:计算
Fibonacci
序列的同时不会引发无限递归。如果函数使用了::
而不是#::
,那么每次对fibFrom
的调用都会引发另一个调用,这样就会造成无限递归。不过由于它用的是#::
,因此表达式右边只会在被请求时才会被求值。如:xxxxxxxxxx
val fibs = fibFrom(1,1).take(7) // 此时 fibs 还没有全部求值 fibs.toList // 此时 fibs 每个元素求值
Vector
是对头部之外的其它元素也提供 $ O(1) $ 复杂度访问的集合类型。但是,这个常量时间是 “从效果上讲的常量时间”。向量的创建和修改和其它序列没有什么不同:
xxxxxxxxxx
val vec = Vector.empty val vec2 = vec :+ 1 :+ 2 val vec3 = 100 +: vec2向量的内部结构是宽而浅的树,树的每个顶点包含多达
32
个元素、或32
个子节点。- 小于等于
32
个元素的向量可以用单个结点来表示。 - 小于等于
32 x 32
=1024
个元素的向量可以通过单次额外的间接跳转来访问。
- 小于等于
如果我们允许从根部到叶子最多
2
跳,则向量可以包含多达 $ 2^{15} $ 个元素;如果允许最多3
跳,则向量可以包含多达 $ 2^{25} $ 个元素。如果允许最多5
跳,则向量可以包含多达 $ 2^{30} $ 个元素。因此对于所有正常大小的向量,选择一个元素只需要最多
5
次基本的数组操作。这就是我们说的“从效果上讲的常量时间”。向量是不可变的,因此无法原地修改向量元素的值。不过,通过
updated
方法可以创建一个与给定向量在单个元素上有差异的新向量:xxxxxxxxxx
val vec = Vector(1,2,3) val vec2 = vec updated(2,4) // Vector(1,2,4)和选择操作一样,函数式向量的更新也是消耗“从效果上讲的常量时间”:更新向量中的某个元素可以通过拷贝包含该元素的结点、以及从根部开始到该结点路径上的所有结点,其它结点无需拷贝。
这意味着一次函数式的向量更新只会创建出
1~5
个新的结点,其中每个结点包含32
个元素或者子节点。这比可变数组的原地更新要更加昂贵,但是比起拷贝整个向量而言要便宜的多。
由于向量在快速的任意位置的索引,以及任意位置的函数式更新之间取得了较好的平衡,因此它们目前是不可变的带下标索引的序列
IndexedSeq
的默认实现。immutable.Stack
是不可变的栈。可以使用push
来压一个元素入栈;可以用pop
来弹一个元素出栈;可以用top
来查看栈顶的元素而不是将它弹出。所有这些操作都是常量时间。xxxxxxxxxx
val stack = scala.collection.immutable.Stack.empty val stack1 = stack.push(1)不可变的栈在
Scala
中很少用到,因为它们的功能完全被List
包含。对不可变的栈的push
操作对应于List
的::
操作,对不可变的栈的pop
操作对应于List
的tail
操作。immutable.Queue
是不可变的队列。可以用enqueue
来追加一个元素或者一组元素,可以用dequeue
来移除头部的元素(出队列):xxxxxxxxxx
val queue = scala.collection.immutable.Queue val queue1 = queue.enqueue(1) val queue2 = queue.enqueue(List(1,2,3)) val (ele,queue3) = queue.dequeue注意:
dequeue
返回的是一个包含被移除元素以及队列剩余部分的tuple
。immutable.Range
是一个有序的整数序列,整数之间有相同的间隔。在Scala
中创建Range
的方法是to
和by
:xxxxxxxxxx
val range1 = 1 to 3 // Range(1,2,3) val range2 = 5 to 14 by 3 // Rnage(5,8,11,14)其中
to
指定Range
的起止位置,by
指定Range
间隔。如果需要创建的
Range
不包含上限,则可以用until
而不是to
:xxxxxxxxxx
val range3 = 1 until 3 // Range(1,2)Range
的内部表示占据了 $ O(1) $ 的空间,因为它只需要用三个数来表示:开始位置、结束位置、步长。因此大多数Range
操作非常快。哈希字典树
Hash Trie
:哈希字典树是实现高效的不可变Set
和不可变Map
的标准方式。它们的内部表现形式和向量类似,也是每个结点有32
个元素或32
棵子树的树,不过元素选择是基于哈希码的(而不是指针)。举例来说:要想找到
Map
中给定的键,首先用键的哈希码的最低5
位找到第一棵子树、然后用哈希码的下一个5
位找到第二棵子树,依次类推。当某个结点所有元素的哈希码(已用到部分)各不相同时,该选择过程就停止了。哈希字典树在快速的查找、高效的函数式插入
+
、高效的函数式删除-
之间取得了不错的平衡。这也是为什么它是不可变Map
和不可变Set
默认的实现的原因。实际上,
Scala
对于元素少于5
个的不可变Set
和不可变Map
还有进一步的优化:- 带有
k
(1<=k <=4
) 个元素的Set
和Map
采用的是包含对应k
个字段的单个对象,每个元素对应一个字段。 - 空的
Set
和Map
使用单例对象来表示。
- 带有
红黑树:红黑树是一种平衡二叉树,某些结点标记为”红色“、某些结点标记为”黑色“。和其它平衡二叉树一样,对它们的操作可以可靠地在 $ O(\log n) $ 时间内完成。
Scala
的TreeSet, TreeMap
的内部使用红黑树来实现,红黑树也是SortedSet
的标准实现。xxxxxxxxxx
val set = collection.immutable.TreeSet.empty[Int] set +1 +3 +3不可变位组
bit set
:位组bit set
用于表示某个非负整数的bit
的集合。从内部讲,位组使用一个Array[Long]
来表示。第一个Long
(64位
)表示整数0~63
,第二个Long
表示整数64~127
,以此类推。如果集合中最大整数在数百这个量级,则位组非常紧凑;如果集合中最大整数非常大,比如
100万
,则它需要1.00万/64
大约1.6
万个Long
来表示。对位组的操作非常快:测试某个整数是否在位组中只需要 $ O(1) $ 的时间;向位组中添加整数的时间复杂度和底层
Array[Long]
的长度成正比,而这个长度通常很小。xxxxxxxxxx
val bitSet = scala.collection.immutable.BitSet.empty val bitSet2 = bitSet ++ List(3,4,4,0) // 内部表示为 Array[Long](25)。 3,4,4,0 用 bit 序列表示为 10011,我们从左到右某个 bit 为 1 代表该位置下标对应的整数出现。 10011 转换为十进制就是 25。列表映射
ListMap
:将Map
表示为一个由键值对构成的链表。一般而言,对ListMap
的操作需要遍历整个链表,因此对于ListMap
的操作耗时为 $ O(n) $ 。事实上
Scala
对于ListMap
用得很少,因为标准的不可变Map
几乎总是比ListMap
更快。唯一可能有区别的场景是:因为某种原因,需要经常访问List
的首个元素的频率远高于访问其它元素时。xxxxxxxxxx
val map = collection.immutable.ListMap(1 -> "a", 2 -> "b") map(1) // 返回 "a"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论