MLE和MAP

  • MLE最大化$P(Y|X,\theta)$
  • MAP最大化$P(\theta|X,Y) \propto P(Y|X,\theta)P(\theta)$

特殊情况:

  • 如果$\theta$是均匀分布,两者等效
  • 如果$P(\theta)$是高斯分布,等同于L2正则
  • 如果$P(\theta)$是拉普拉斯分布,等同于L1正则

负采样纠偏

训练时纠偏,训练输出就是无偏结果,inference时不需要纠偏。

用采样后的样本,预测输出的logit为$f’$,无偏的结果为$f$,$p’=\frac{1}{1+e^{-f’}}$,$p$同理。

$$
p=\frac{p’}{p’+\frac{1-p’}{r}}
$$

这里$r$是负样本采样率,把$p$都替换成$f$,可以得到:

$$
f=f’+ln(r)
$$

注:模型auc需要用这种纠偏之后,才能对比。

Weighted LR

YouTube-DNN 时长建模,
参考:Deep Neural Networks for YouTube Recommendations

$$
-\sum_i [t_i y_i log(p_i) + (1-y_i) log(1-p_i)] \
p_i = \frac{1}{1+e^{-wz}} \
odds = \frac{P}{1-P} = e^{wz}=\frac{E(t)}{1-P}
$$

因为$P$比较小,所以$E(t)=e^{wz}$

如果把所有的样本都作为负例,对正样本加权,就不会有近似了,直接是无偏的。

LR概率模型分析

  • 常见的LR:假设数据服从伯努利分布,发生概率为$p$,不发生为$1-p$,$odds=p/(1-p)$为几率比
  • weighted LR:假设数据服从几何分布,假设用户看单位时长的概率为p,期望为$\frac{1}{1-p}-1=e^{wz}$(-1是因为几何概率一般是从1开始,我们这里是从0开始)

回归转分类

把连续值分桶,softmax预测在每个桶的概率,不需要对label有啥分布的假设。

可以对label做软化,默认分桶是01 hard label,可以类似知识蒸馏,对标签做软化,但实际上我们没有teacher model,可以依赖一些先验假设,比如高斯分布。

TPM

可以有级联的loss:softmax loss,每个桶内的连续loss。参考KDD23快手的TPM,Tree based Progressive Regression Model。

每个叶子节点是最后的分类,也对应了一条路径,每个叶子节点的概率是多层概率的乘积。

img

Ordinal regression

把学习目标送PDF改为CDF,也是把连续值分成$K$个桶。预测的不是属于某个桶的概率,而是小于等于某个桶的概率。
$$
F(k)=P(f(x_i)\le t_k)=\sigma(t_k-f(x_i))
$$

$$
f(k)=F(k)-F(k-1)
$$

但这里对分布有假设,$\sigma$是一个CDF,可以是sigmoid函数,或者高斯分布的CDF$\Phi$。

还有一种方法,是变成$K$个二分类。

ZILN loss

参考:ZILN论文(zero-inflated lognormal)

The ZILN loss can be similarly derived as the negative log-likelihood of a ZILN distributed random variable with p as the probability of being nonzero:

$$
L_{ZILN}(x; p, \mu, \sigma) = −1_{x=0} log(1 − p) − 1_{x>0}(log p − L_{Lognormal}(x; \mu, \sigma))
$$

where 1 denotes the indicator function.

The loss can be decomposed into two terms:

  1. 分类loss:判断客户是否为回头客
  2. 回归loss:预测重复购买客户的LTV

$$
L_{ZILN}(x; p, \mu, \sigma) = L_{CrossEntropy}(1_{x>0}; p) + 1_{x>0}L_{Lognormal}(x; \mu, \sigma)
$$

模型输出3个值,分别对应:$p$,$\mu$,$\sigma$

预估的LTV为:$p e^{\mu+\sigma^2/2}$

多目标建模

双塔近似计算

参考:Efficient Training on Very Large Corpora via Gramian Estimation

数据来源,geekbench官网搜的,geekbench6,怀疑新cpu本身就占优

我这两天把老电脑又拿出来了,装了win11,然后想起来极客湾做的高通855刷win11,说有类似4代i5水平,还是挺出乎意料的,于是把我有的几个设别的geekbench分数查了一下

1749975940509

三星 q470bt04,2012

Mobile DualCore Intel Core i5-3210M

Single-Core Score 523 Multi-Core Score 1116,TDP35w

TDP(Thermal Design Power)是“热设计功耗”的缩写,主要用于描述处理器或芯片在满负荷运行时产生的热量指标,单位为瓦特(W)

nVIDIA GeForce GT 650M 1GB

MacBook Pro(13 英寸,2017,两个 Thunderbolt 3 端口)

Intel Core i5-7360U 2300 MHz (2 cores)

Single-Core Score 1195 Multi-Core Score 2569,TDP15w

小米 mi8,2018

Snapdragon 845 2649 MHz (8 cores)

Single-Core Score 474 Multi-Core Score 1921

ipad mini5,2019

Apple A12 Bionic 2490 MHz (6 cores)

Single-Core Score 1294 Multi-Core Score 2662

iphone14,2022

Apple A15 Bionic 3230 MHz (6 cores)

Single-Core Score 2222 Multi-Core Score 5538

在浮躁的LLM时代,仍然坚持古法建模,致敬xgb匠人

单棵树

  • ID3 算法中根据特征选择和信息增益评估,每次选择信息增益最大的特征作为分支标准
  • C4.5 使用“增益率”(gain ratio)来选择最优的分支标准
  • CART 的分支标准建立在 GINI 指数上,GINI 值越大表明样本集合的类别越杂乱

GBDT

  • 先有BT(boosting tree)(相比随机森林是stacking)
  • 随后有了GBT,gradient boosting tree,又可分为GBDT和GBRT,分类数和回归树
  • 核心思想是利用损失函数的负梯度在当前模型的值作为残差的近似值,本质上是对损失函数进行一阶泰勒展开,从而拟合一个回归树

$$
L(y,f_t) = L(y,f_{t-1}+h_t)=L(y,f_{t-1})+\frac{\partial L(y, f_{t-1})}{\partial f_{t-1}}h_t
$$

  • 对于mse loss,$\Delta L=L(y,f_t)-L(y,f_{t-1})=\frac{\partial L(y, f_{t-1})}{\partial f_{t-1}}h_k$ ,所以$h_k=-\frac{\partial L(y, f_{t-1})}{\partial f_{t-1}}$,负梯度也就是残差
  • 对于log loss,我没看懂

xgboost

主要参考这里原论文

然后才进化出了xgb,有几个改进点

  • 加了正则项,包含树的节点数,权重
  • 一阶泰勒变成了二阶
  • 一些实现上的优化,缺失值、分裂点

损失函数定位为:
$$
L = \sum_il(f_i,y_i)+\sum\Omega(f) \
\Omega(f)= \gamma T+\frac{1}{2}\lambda \lVert \omega \rVert ^2
$$
$\Omega$中,$T$表示节点个数,$\omega$表示叶子节点的值,loss里直接包含了正则想,相比GBDT更不同意过拟合

对$L$进行二阶展开,
$$
L=\sum_i[l(y_i,f_i^{t-1})+g_if_i^t+\frac{1}{2}h_i(f_i^t)^2]+\sum\Omega(f)
$$
这里$g_i=\frac{\partial l(y_i,f_i^{t-1})}{\partial f_i^{t-1}}$,$h_i=\frac{\partial ^2 l(y_i,f_i^{t-1})}{\partial ^2 f_i^{t-1}}$,即$l(y_i,f_i^{t-1})$对$ f_i^{t-1}$的一阶导数和二阶导数。利用泰勒展开式,这里将损失函数转化成了一个二次函数,而且这里二次项的系数为正,可以很方便的求得函数的最小值

简单一点,相对于$ f^{t}$是常数项的部分去掉
$$
L=\sum_i[g_if_i^t+\frac{1}{2}h_i(f_i^t)^2]+\sum\Omega(f^t)
$$
决定$ f^{t}$的主要是两个纬度,一是这颗树的形态,二是树的叶子节点的权重。这里用数学表达式来表示就是
$$
\sum_if_i^t=\sum_{j=1}^T\sum _{i\in I_j} \omega_j
$$
等式左边的意义很明显,就是所有样本在第$t$棵树上输出的和,等式右边用另一种方式表达了这个值,第一个求和符号表示所有的叶子节点,第二个求和符号表示被分到每个叶子节点的样本集合,$i\in I_j$表示被分到第$j$个叶子节点的样本集合。$\omega_j$代表第$j$个叶子节点的权重。可以这么理解,样本分到哪一个叶子节点上表示了树的结构。

把这个细化的表达式带入到泰勒展开近似的损失函数中得到,
$$
L=\sum_{j=1}^T[(\sum _{i\in I_j} g_i)\omega_j+\frac{1}{2}(\sum _{i\in I_j}h_i+\lambda)\omega_j^2]+\gamma T
$$
给定树的结构下
$$
\omega_j^*=\frac{\sum _{i\in I_j} g_i}{\sum _{i\in I_j}h_i+\lambda}
$$

怎么确定树的结构

答案是枚举,在一个节点那里想要做分裂节点的操作,哪些样本要分到左边,哪些节点要分到右边,XGBoost就把所有的样本按某个特征排序,然后切分,以此确定树的结构,枚举下来算出最小损失值,就作为最优结构。

  • 当新引入的一次分裂所带来的增益Gain<0时,放弃当前的分裂。这是训练损失和模型结构复杂度的博弈过程。

  • 当树达到最大深度时,停止建树,因为树的深度太深容易出现过拟合,这里需要设置一个超参数max_depth。

  • 当引入一次分裂后,重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值,也会放弃此次分裂。这涉及到一个超参数:最小样本权重和,是指如果一个叶子节点包含的样本数量太少也会放弃分裂,防止树分的太细。

实现上的一些优化(xgb为什么快):

  • 对每个特征的分割决策使用并行策略:首先把每个特征都排序,因为对特征在不同的位置进行分割是独立的,所以可以使用并行的线程进行计算,从而加速训练的速度。

  • 梯度数据缓存策略:会把需要的梯度数据放到一个额外的内存里,使用预取和缓存的方式来提高缓存的命中率,从而提升数据IO的速度。

  • 去中心化内存策略:为了实现去中心化的计算,将数据分割成不同的块,然后将所有块存储在磁盘上。在计算过程中,利用一个单独的线程来预取磁盘中的数据,保证运算和取数据可以同时发生。

怎么方式过拟合

  • 正则项:叶子节点个数+叶子节点权重的L2正则化
  • 列抽样:训练的时候只用一部分特征(只考虑一个block,不考虑剩余的Block块即可)
  • 子采样:每轮计算可以不使用全部样本,随机抽取部分样本,因此算法鲁棒性更强
  • 系数衰减:学习率/步长,为了给后面的训练留出更多的学习空间。

和GBDT的差别

  • 基分类器:传统GBDT以CART树作为基分类器,xgboost还支持线性分类器。
  • 导数:传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。同时xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
  • 正则项/列抽样/系数衰减的防止过拟合方法
  • 并行:xgboost的并行不是树粒度的并行,而是在特征粒度上的。决策树的学习最耗时步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
  • 可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。

为什么有时候不如LR

  • 在高维稀疏特征的时候,线性模型会比非线性模型好:带正则化的线性模型比较不容易对稀疏特征过拟合。

模型发布时间层数头数词向量长度参数量预训练数据量
GPT-120181212768117M约 5GB
GPT-2201948-16001.5B40GB
GPT-32020969612888175B45TB
instructGPT2022969612888175B
阅读全文 »

推荐水哥的这个系列

我这记一点里面需要注意的知识

AUC/GAUC

阿里提出了一个新的评价指标 Group AUC,是用户维度加权的auc

$$
GAUC = \frac{\sum w_u AUC_u}{\sum w_u}
$$

这里的w代表权重,可以是曝光数、点击数,更倾向于高活用户。

AUC这篇写挺好的

  • auc曲线横坐标是$FPR=\frac{FP}{FP+TN}$,假阳率,预测为阴性里有多少是阳的,越小越好

  • 纵坐标是$FPR=\frac{TP}{TP+FN}$,真阳率,召回率,预测为阳性的里面有多少是真阳性,越大越好

  • AUC可以看做随机从正负样本中选取一对正负样本,其中正样本的得分大于负样本的概率

  • 可以使用sql来计算AUC

    假设我们将测试集的正负样本按照模型预测得分从小到大排序,对于第j
    个正样本,假设它的排序为 rj, 那么说明排在这个正样本前面的总样本有 rj−1
    个,其中正样本有 j−1 个(因为这个正样本在所有的正样本里面排第j), 所以排在第j个正样本前面(得分比它小)的负样本个数为 rj−j个。也就是说,对于第j个正样本来说,其得分比随机取的一个负样本大(排序比它靠后)的概率是 (rj−j)/N−,其中N−是总的负样本数目。所以,平均下来,随机取的正样本得分比负样本大的概率为

    $$
    AUC = \frac{1}{N_+} \sum_{j=1}^{N_+}(r_j - j)/N_- \
    = \frac{\sum_{j=1}^{N_+}r_j - N_+(N_+ + 1)/2}{N_+N_-}
    $$

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    select
    (ry - 0.5*n1*(n1+1))/n0/n1 as auc
    from(
    select
    sum(if(y=0, 1, 0)) as n0,
    sum(if(y=1, 1, 0)) as n1,
    sum(if(y=1, r, 0)) as ry
    from(
    select y, row_number() over(order by score asc) as r
    from(
    select y, score
    from some.table
    )A
    )B
    )C

NDGC

Normalized Discounted Cumulative Gain,是衡量排序效果的指标。

还是这位😡老哥说得清楚

理清楚顺序,GC->DGC->NDGC

$$
DCG@K = \sum_{k=1}^{K} \frac{rel_k}{\log_2(k + 1)}
$$

$$
IDCG@K = \sum_{k=1}^{|REL|} \frac{rel_k}{\log_2(k + 1)} = max DGC@K
$$

$$
NDCG@K = \frac{DCG@K}{IDCG_K}
$$

reg-AUG

我理解是没办法画ROC曲线出来,还是沿用了AUC的物理含义,任选两个样本,pred和label单调的概率。
可以用逆序对来计算(mergesort)。

DCN DCNv2

dcn,不是很经得起推敲,$x_l^TW_l$相当于一个常数了,作用在$x_0$上,没有起到交叉的作用,本质原因还是因为$W_l$只是一个向量。
$$
x_{l+1} = x_0x_l^TW_l+b_l+x_l
$$
img

dcn-v2,最大的变化是$W_l$从向量变矩阵了,但因为是bit-wise的交叉,所以参数量比较大,可以做低秩分解。
$$
x_{l+1}=x_0\odot(W_lx_l + b_l)+x_l
=x_0\odot(U_lV_l^Tx_l + b_l)+x_l
$$
img

起因

事情是这样的,最近面试有些多,看别人简历会有些附带博客,让我也想起来我有这么个事实上废弃了的博客

博客写多一点,一个是说明这人有积累,一个还能引导面试官的面试方向,于是就决定去捡起我的博客来

写博客最密集的是18、19这两年,那时候我还在帮hxf做网站,刚刚艰难毕业,刚刚开始工作,是我对未来充满憧憬,求知欲最旺盛的时候,肯分享肯折腾

啊,想起来真的美好啊

不像现在老太龙钟,上班在sql和xgb中消磨人生,下班边玩边骂原神

这简直都不是博客不博客的问题了,这是要找回青春找回自我

一地鸡毛

原本设想是美好的,我在本地调通hexo,然后部署到github的action里,这样我直接在网页端写博客就行

是啊,2023年了,本来写博客就够变态了,更不要说在本地部署写了

第一步给我的小mac充电,它现在不插电只能续航一个小时了,都是岁月的痕迹

找到博客的路径,hexo命令我忘了,但是terminal都记得,我直接hexo deploy

不出意外地,push不上去了,好像是github不支持https这种方式了,问题不大,就是重新ssh-keygen,我很熟

就是从登录github开始,事情起变化了,我登不上去了,github强制两步验证?这是啥?为什么手机验证码不支持+86?

github解决之后,又发现hexo generate出来的网页是空的,版本问题,hexo和node版本不兼容,node太新,hexo太老,这种问题一般有两个选项,降级node,后者更新hexo,但我现在是个有经验的程序员了,升级风险不可控,我选择苟在老版本

当时已经过了一点了,我现在想不起来昨天一点我是怎么折腾的,但最后我妥协用了新版本

其实就是把hexo再重新部署一遍,但老项目里有我很多配置项,不能完整迁移过来,我没办法完全复原我的老博客

新版本的hexo也太破了,配置项完全改了不说,一个语言设置选项都没法用,博客语言在阿拉伯和泰中来回切换,我最终的结局方法是啥,把语言配置文件删到只剩中文

hexo的搜索插件也是,很多文章搜不出来,我记得老版本没这些问题的,还有mathjax也不对

总之就是博客回来了,但没完全回来,回来了,但好像没那个味道了

但写到这里我确实想知道昨天为啥没有降级成功,我决定再去降级一次

应该是npm install很慢,然后我决定用cnpm,但cnpm直接不给下老版本的依赖,导致我最终放弃

本来我想描述一下昨天的一地鸡毛的,变成了现场表演一地鸡毛

npm就是卡在这里,可能因为我镜像配的还是淘宝的?

1
2
⸨    ░░░░░░░░░░░░░░⸩ ⠇ fetchMetadata: sill mapToRegistry uri https://registry.npm.taobao.org/repeat-string
(node:22980) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit

留不住

这次我要耐心等npm,我还有一个下午,应该不至于再搞到很晚了。

降级还是未遂,那一个个报错就像拼多多的砍一刀,“再搞定这个报错,就能彻底找回你原来的博客了哦”

确实没必要强求了,虽然代码和三年前的一模一样,但好像真的不好回来了

但搞不成也无所谓,用新版本的hexo也是可以用的,老文章也是在的,我现在都在继续写了。要是我哪天真的想看老博客git的历史还在,北极还保存着一份呢

这里才是我想和自己说的,留不住就不要强留了,可以怀念但不要沉湎,现在也有好多事要做呢

耽误太多时间,事情可就做不完了!

嗯?

我现在咋这么矫情,根本原因是我不懂node,不懂hexo,咋说出这么多话来?

我又想不通了

我先记一下hexo的一些命令,都是history里的,等等再删

1
2
3
4
5
6
7
8
9
10
11
12
10299  git push origin main:hexo2
10300 hexo deploy
10301 npm install hexo-deployer-git --save
10302 hexo clean
10303 hexo deploy
10304 hexo server
10323 hexo server
10327 hexo server
10333 hexo clean
10334 hexo generate
10335 hexo deploy
10367 hexo new "写写GBDT吧"

哦哦,我以为我配了github action,其实没有,都是pages的action

  • 文档列表页

screencapture-192-168-1-104-8088-onlyoffice-2020-05-11-22_27_51

  • 文档编辑页

screencapture-192-168-1-104-8088-onlyoffice-1-2020-05-11-22_28_35

是什么

  • 一个文档在线编辑平台,部署在局域网,可以用作组内日报/周报系统
  • 其实是从3xxx/engineercms fork来的,只保留了文档编辑的功能

怎么用

  • docker启动onlyoffice docker run -i -t -d -p 9000:80 onlyoffice/documentserver
  • 修改conf/app.conf中的ip配置,注意不能写localhost,不然局域网的其他用户访问不到
    1
    2
    documentserverip = http://192.168.1.107:9000
    entryserverip = http://192.168.1.107:8088
  • 解压main.rar,运行exe,浏览器端访问entryserverip

代码结构

  • onlyoffice负责文档编辑的功能,onlyoffice的api可以参考这里
  • 本项目负责文档的上传、删除、用户管理等,采用beego MVC架构

相比3xxx/engineercms做了哪些修改

修改主要是为了更适合做日报系统

删除了文档编辑以外的功能

文档自动上传

  • 日报中包含日期,如“总裁办公室20200331.xlsx”,会自动复制日期最新的一份日报,并对日报做清空后自动上传

  • 那些内容清空?

    只保留第一个sheet,sheet命名为日期(MMdd)

    conf/app.conf中,设置那些行和列以内保留,≤rowkeep和colkeep的内容保留

1
2
3
#####日报清空,前多少行和列保留,固定只保留第一个sheet
rowkeep = 1
colkeep = 4
  • 什么时候上传?

    每次打开文档列表也都判断是否有今天的日报,没有就自动上传

    节假日没有人访问,所以避免了逻辑判断是否上传

文档自动保存

  • 原来文档不会自动保存吗?

    编辑后的文档都暂时存在onlyoffice的docker中

    只有在所有人关闭文档的情况下,才会将文档内容保存到本地

    做不到全部用户及时关闭文档,而如果docker崩了,文档内容就丢失了

  • 如何解决?

    在没有用户使用的情况下强制保存。conf/app.conf中设置了定时保存,默认设置是晚上10点,每10分钟保存一次

1
2
3
#####文档保存本地
forcesavecron = "0 */10 22 * * *"
### 秒 分 时 日 月 周

登录权限

  • 内网用户比较可靠,不做权限限制,不需要注册账户
  • 可以不登录用ip作为用户名
  • 可以“假登录”,直接登录,不检查用户是否存在,不检查密码

  • 目前我知道有两个地方能薅到免费的GPU,一个是google的colab,一个是百度的aistudio

colab

  • colab是tesla p100,一次可以运行12h,只能以jupyter notebook的形式运行,没有shell真的很难受啊,
  • 文件可以挂载在google driver
  • 有人做了ssh访问colab,看这里,使用Ngrok做了个反向的代理

aistudio

  • 百度最友好的是提供命令行,同时也有个work路径,持久存储,比谷歌舒服多了
  • 给的还是Tesla V100啊
  • 理论上只能支持paddlepaddle,但亲测可以pytorch,需要自己安装
1
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2019.10-Linux-x86_64.sh
  • 安装之后需要修改conda的镜像,否则下载很慢,修改~/.condarc

  • 这个是我的.condarc,基本上是conda install的时候,如果下载的url不是清华的镜像,就需要添加相应的镜像了

1
2
3
4
5
6
7
channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
show_channel_urls: true
  • 安装pytorch
1
conda install --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ pytorch torchvision cudatoolkit=9.2 -c pytorch

  • 肖克利在贝尔实验室发明了三极管,后来离开贝尔,创办肖克利半导体公司

  • 肖克利独断专行,出现了”八叛徒“叛逃,八叛徒包括摩尔、诺伊斯等人,后创立了仙童半导体

  • 在仙童,诺伊斯发明了集成电路。摩尔、诺伊斯等人继续叛逃仙童,创办了英特尔

  • 霍夫,我不想写了,看这里

0%