算法简介:
该算法是阿里的盖坤大神力作:Learning Piece-wise Linear Models from Large Scale Data for Ad Click Prediction,介绍了阿里广告的一个主要ctr预估模型Large Scale Piece-wise Linear Model (LS-PLM),在2012年就开始使用,据说早期叫做Mixture of LR(MLR)。

代码地址在:  https://github.com/CastellanZhang/alphaPLM

算法介绍:http://castellanzhang.github.io/2017/06/01/mlr_plm/
以上git和博客对mlr 做出详细的介绍,本文主要介绍在学习和实践中的一些领悟,能力一般,水平有限,望路过大神多多指教.
在使用中发现,使用该算法生成模型,会产生大量的训练参数,造成实际生产中资源使用不足的问题,以个人使用的数据训练,每天训练集的特征数据大约8kw(已经经过特征筛选过滤),训练piece_num=12(训练参数,影响参数数量),模型40-50G,(这对于我等小集群,完全扛不住),怎么办呢???
就在此时,一小胖从旁走过,手拿鸡翅,汉堡,如此之人不瘦怎行!!!感叹至此,令我不禁怀想,如此之模型,不瘦身让我如何部署?想到此处,模型瘦身之念顿起。那如何瘦身嗫?
业内大佬有云“模型瘦身,首看普瑞狄特(predict),在看权零”。此话不虚,见mlr 之 predict 如下:

在#ifndef FTRL_MODEL_H_
#define FTRL_MODEL_H_#include <unordered_map>
#include <string>
#include <vector>
#include <mutex>
#include <iostream>
#include <cmath>
#include "../Utils/utils.h"using namespace std;//每一个特征维度的模型单元
class ftrl_model_unit
{
public:vector<double> u;vector<double> u_n;vector<double> u_z;vector<double> w;vector<double> w_n;vector<double> w_z;mutex mtx;
public:ftrl_model_unit(int piece_num, double u_mean, double u_stdev, double w_mean, double w_stdev){u.resize(piece_num);u_n.resize(piece_num);u_z.resize(piece_num);for(int f = 0; f < piece_num; ++f){u[f] = utils::gaussian(u_mean, u_stdev);u_n[f] = 0.0;u_z[f] = 0.0;}w.resize(piece_num);w_n.resize(piece_num);w_z.resize(piece_num);for(int f = 0; f < piece_num; ++f){w[f] = utils::gaussian(w_mean, w_stdev);w_n[f] = 0.0;w_z[f] = 0.0;}}ftrl_model_unit(int piece_num, const vector<string>& modelLineSeg){u.resize(piece_num);u_n.resize(piece_num);u_z.resize(piece_num);w.resize(piece_num);w_n.resize(piece_num);w_z.resize(piece_num);for(int f = 0; f < piece_num; ++f){u[f] = stod(modelLineSeg[1 + f]);w[f] = stod(modelLineSeg[piece_num + 1 + f]);u_n[f] = stod(modelLineSeg[2 * piece_num + 1 + f]);w_n[f] = stod(modelLineSeg[3 * piece_num + 1 + f]);u_z[f] = stod(modelLineSeg[4 * piece_num + 1 + f]);w_z[f] = stod(modelLineSeg[5 * piece_num + 1 + f]);}}void reinit_u(double u_mean, double u_stdev){int size = u.size();for(int f = 0; f < size; ++f){u[f] = utils::gaussian(u_mean, u_stdev);}}void reinit_w(double w_mean, double w_stdev){int size = w.size();for(int f = 0; f < size; ++f){w[f] = utils::gaussian(w_mean, w_stdev);}}friend inline ostream& operator <<(ostream& os, const ftrl_model_unit& mu){if(mu.u.size() > 0){os << mu.u[0];}for(int f = 1; f < mu.u.size(); ++f){os << " " << mu.u[f];}for(int f = 0; f < mu.w.size(); ++f){os << " " << mu.w[f];}for(int f = 0; f < mu.u_n.size(); ++f){os << " " << mu.u_n[f];}for(int f = 0; f < mu.w_n.size(); ++f){os << " " << mu.w_n[f];}for(int f = 0; f < mu.u_z.size(); ++f){os << " " << mu.u_z[f];}for(int f = 0; f < mu.w_z.size(); ++f){os << " " << mu.w_z[f];}return os;}
};class ftrl_model
{
public:ftrl_model_unit* muBias;unordered_map<string, ftrl_model_unit*> muMap;int piece_num;double u_stdev;double u_mean;double w_stdev;double w_mean;public:ftrl_model(double _piece_num);ftrl_model(double _piece_num, double _u_mean, double _u_stdev, double _w_mean, double _w_stdev);ftrl_model_unit* getOrInitModelUnit(string index);ftrl_model_unit* getOrInitModelUnitBias();double get_uTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, vector<ftrl_model_unit*>& theta, int f);double get_wTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, vector<ftrl_model_unit*>& theta, int f);double get_uTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta, int f);double get_wTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta, int f);double getScore(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta);void outputModel(ofstream& out);bool loadModel(ifstream& in);void debugPrintModel();private:double get_uif(unordered_map<string, ftrl_model_unit*>& theta, const string& index, int f);double get_wif(unordered_map<string, ftrl_model_unit*>& theta, const string& index, int f);
private:mutex mtx;mutex mtx_bias;
};ftrl_model::ftrl_model(double _piece_num)
{piece_num = _piece_num;u_mean = 0.0;u_stdev = 0.0;w_mean = 0.0;w_stdev = 0.0;muBias = NULL;
}ftrl_model::ftrl_model(double _piece_num, double _u_mean, double _u_stdev, double _w_mean, double _w_stdev)
{piece_num = _piece_num;u_mean = _u_mean;u_stdev = _u_stdev;w_mean = _w_mean;w_stdev = _w_stdev;muBias = NULL;
}ftrl_model_unit* ftrl_model::getOrInitModelUnit(string index)
{unordered_map<string, ftrl_model_unit*>::iterator iter = muMap.find(index);if(iter == muMap.end()){mtx.lock();ftrl_model_unit* pMU = new ftrl_model_unit(piece_num, u_mean, u_stdev, w_mean, w_stdev);muMap.insert(make_pair(index, pMU));mtx.unlock();return pMU;}else{return iter->second;}
}ftrl_model_unit* ftrl_model::getOrInitModelUnitBias()
{if(NULL == muBias){mtx_bias.lock();muBias = new ftrl_model_unit(piece_num, 0, 0, 0, 0);mtx_bias.unlock();}return muBias;
}double ftrl_model::get_uTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, vector<ftrl_model_unit*>& theta, int f)
{double result = 0;result += muBias.u[f];for(int i = 0; i < x.size(); ++i){result += theta[i]->u[f] * x[i].second;}return result;
}double ftrl_model::get_wTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, vector<ftrl_model_unit*>& theta, int f)
{double result = 0;result += muBias.w[f];for(int i = 0; i < x.size(); ++i){result += theta[i]->w[f] * x[i].second;}return result;
}double ftrl_model::get_uTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta, int f)
{double result = 0;result += muBias.u[f];for(int i = 0; i < x.size(); ++i){result += get_uif(theta, x[i].first, f) * x[i].second;}return result;
}double ftrl_model::get_wTx(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta, int f)
{double result = 0;result += muBias.w[f];for(int i = 0; i < x.size(); ++i){result += get_wif(theta, x[i].first, f) * x[i].second;}return result;
}**// 计算得分**
double ftrl_model::getScore(const vector<pair<string, double> >& x, ftrl_model_unit& muBias, unordered_map<string, ftrl_model_unit*>& theta)
{double result = 0;vector<double> uTx(piece_num);double max_uTx = numeric_limits<double>::lowest();for(int f = 0; f < piece_num; ++f){uTx[f] = get_uTx(x, muBias, theta, f);if(uTx[f] > max_uTx) max_uTx = uTx[f];}double numerator = 0.0;double denominator = 0.0;for(int f = 0; f < piece_num; ++f){uTx[f] -= max_uTx;uTx[f] = exp(uTx[f]);double wTx = get_wTx(x, muBias, theta, f);double s_wx = utils::sigmoid(wTx);numerator += uTx[f] * s_wx;denominator += uTx[f];}return numerator / denominator;
}double ftrl_model::get_uif(unordered_map<string, ftrl_model_unit*>& theta, const string& index, int f)
{unordered_map<string, ftrl_model_unit*>::iterator iter = theta.find(index);if(iter == theta.end()){return 0.0;}else{return iter->second->u[f];}
}double ftrl_model::get_wif(unordered_map<string, ftrl_model_unit*>& theta, const string& index, int f)
{unordered_map<string, ftrl_model_unit*>::iterator iter = theta.find(index);if(iter == theta.end()){return 0.0;}else{return iter->second->w[f];}
}void ftrl_model::outputModel(ofstream& out)
{out << "bias " << *muBias << endl;for(unordered_map<string, ftrl_model_unit*>::iterator iter = muMap.begin(); iter != muMap.end(); ++iter){out << iter->first << " " << *(iter->second) << endl;}
}void ftrl_model::debugPrintModel()
{cout << "bias " << *muBias << endl;for(unordered_map<string, ftrl_model_unit*>::iterator iter = muMap.begin(); iter != muMap.end(); ++iter){cout << iter->first << " " << *(iter->second) << endl;}
}bool ftrl_model::loadModel(ifstream& in)
{string line;if(!getline(in, line)){return false;}vector<string> strVec;utils::splitString(line, ' ', &strVec);if(strVec.size() != 6 * piece_num + 1){return false;}muBias = new ftrl_model_unit(piece_num, strVec);while(getline(in, line)){strVec.clear();utils::splitString(line, ' ', &strVec);if(strVec.size() != 6 * piece_num + 1){return false;}string& index = strVec[0];ftrl_model_unit* pMU = new ftrl_model_unit(piece_num, strVec);muMap[index] = pMU;}return true;
}
#endif /*FTRL_MODEL_H_*/

仔细阅读getScore发现predict 很简单,就是实现了一下mlr 的公式:

从公式可以看出,数据predict 时仅使用uf, wf 权重,实例截图如下:

根据以上分析,得出过滤条件uf, wf 均不为零是特征为有效特征。因此模型瘦身实现如下:

# -*- coding: utf-8 -*-
# load model and predict mlr
from __future__ import unicode_literals
#!/usr/bin/python
import sys
piece_num = int(sys.argv[3])
lite_model = open(sys.argv[2], 'w')
line_count = 0
for line in open(sys.argv[1], 'r'):if not line:breakelse:if piece_num == 1:if line.split('\t')[2] != '0':lite_model.write(line)else :line_sp = line.split()filter = Truefeature = line_sp[0]for i in xrange(piece_num):if line_sp[1+i] != '0' or line_sp[1+piece_num+i] != '0':lite_model.write(feature+"\t"+str(i)+"\t"+line_sp[1+i]+"\t"+line_sp[1+piece_num+i]+"\n")line_count+=1if line_count % 1000000 == 0:print "finishede line count:%d"%line_count# break
lite_model.close()

测试预测文件(即实现加载lite model,的predict):

# -*- coding: utf-8 -*-
# load model and predict mlr
from __future__ import unicode_literals
#!/usr/bin/python
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import numpy as np
import math
print len(sys.argv)
if len(sys.argv)< 3:print "please input full model file name and save result file name at least!!!"exit(0)piece_num = 12
if len(sys.argv) == 4:piece_num = int(sys.argv[3])
result = open(sys.argv[2], 'w')
line_count = 0
model = {}
for line in open(sys.argv[1], 'r'):if not line:breakelse:line_sp = line.split()feature = line_sp[0]index = int(line_sp[1])u_v = float(line_sp[2])w_v = float(line_sp[3])if feature in model:model[feature][index] = [u_v, w_v]else:model[feature] = {}model[feature][index] = [u_v, w_v]line_count+=1if line_count % 1000000 == 0:print "finished line count:%d"%line_count# breakdef sigmode(x):return 1 / (1 + np.exp(-x))def get_uw_T_x(features, model):u_T_x = np.zeros(piece_num)w_T_x = np.zeros(piece_num)features.append("bias")for feature in features:u_zeros = np.zeros(piece_num)w_zeros = np.zeros(piece_num)if feature in model:for v in model[feature]:u_zeros[v] = model[feature][v][0]w_zeros[v] = model[feature][v][1]# print u_zerosu_T_x += u_zerosw_T_x += w_zerosprint u_T_xprint w_T_xu_T_x = u_T_x - np.max(u_T_x)return np.exp(u_T_x), sigmode(w_T_x)def predict(features, model):features_cal = [feature.split(":")[0] for feature in features]uTx, wTx = get_uw_T_x(features_cal, model)dim = 0.0re = 0.0for x, y in zip(uTx, wTx):re += x*ydim += xreturn re/dimfor line in sys.stdin:if not line:breakelse:# print modelline_sp = line.split("\t")line_news = "\t".join(line_sp[1:-1])label = line_sp[0]feature_line = line_sp[-1]# print feature_linefeatures = feature_line.split()# print features# breakscore = predict(features, model)print label+"\t"+str(score)+"\t"+line_newsresult.write(label+"\t"+str(score)+"\t"+line_news)break

满篇code实在难受,如若不想关心如何实现,直接使用,请关注git:
https://github.com/liguoyu1/alphaPLM/tree/master/src/scripts

推荐广告之-MLR学习相关推荐

  1. 【推荐实践】强化学习算法在京东广告序列推荐场景的应用

    猜你喜欢 0.搜狗信息流推荐系统架构及推荐算法实践1.如何搭建一套个性化推荐系统?2.京东推荐算法精排技术实践3.[万字长文]某视频APP推荐算法及策略详解4.微博推荐算法实践与机器学习平台演进5.腾 ...

  2. 「DLP-KDD 2021征文」及上届论文全集,包含深度学习推荐/广告系统、多目标、模型服务等

    「DLP-KDD 2021征文」及上届论文全集,包含深度学习推荐/广告系统.多目标.模型服务等 在DLP-KDD 2021征稿之际,为大家准备了DLP-KDD2020的全部文章和资源列表,内容涵盖了几 ...

  3. 掏空老底,值得推荐的10个学习神器,总有一个用得上!

    推荐10个免费学习的APP和网站,非常强大. 1.大学资源网 大学资源网是一个非常实用的在线学习网站,里面有小学课程,初中课程,高中课程,大学课程. 还有一些细分领域课程,比如计算机课程,考研课程,讲 ...

  4. 百度计算广告学沙龙学习笔记 - 内容匹配广告

    百度计算广告学沙龙学习笔记 - 内容匹配广告 时间 2014-02-05 18:53:55 CSDN博客 原文  http://blog.csdn.net/three_body/article/det ...

  5. DeepMatch :用于推荐广告的深度召回匹配算法库

    今天介绍一下我们的一个开源项目DeepMatch,提供了若干主流的深度召回匹配算法的实现,并支持快速导出用户和物品向量进行ANN检索.非常适合同学们进行快速实验和学习,解放算法工程师的双手! 目前支持 ...

  6. nsoutlineview 搜索_阿里巴巴搜索推荐广告三位一体的在线服务体系

    最近在工作中大量使用到了淘系的在线分发服务体系,可以快速高效的实现个性化内容分发,其技术架构的概览在这里分享给大家. AI·OS(Artificial Intelligence Online Serv ...

  7. 大规模异构图召回在美团到店推荐广告的应用

    美团到店推荐广告团队在图神经网络的长期落地实践中,思考分析了场景的特点与挑战,针对性地进行了模型设计,并通过大规模训练工具及线上部署优化多次成功落地,带来了线上收入提升.本文主要介绍了大规模图召回技术 ...

  8. 推荐/广告算法社招生存指南(浅梦)

    推荐/广告算法社招生存指南 转自公众号--浅梦学习笔记,仅做博客笔记学习使用,侵删 " Choose life. Choose a job. Choose a career. Choose ...

  9. 【推荐实践】大规模异构图召回在美团到店推荐广告的应用

    省时查报告-专业.及时.全面的行研报告库 省时查方案-专业.及时.全面的营销策划方案库 [免费下载]2022年10月份热门报告盘点 知识图谱在美团推荐场景中的应用实践.pdf 清华大学256页PPT元 ...

  10. 推荐常用的排序学习算法——BPR(贝叶斯个性化排序)

    文章目录 1. 排序学习 1.1 优势 1.2 排序学习在推荐领域的作用 1.3 排序学习设计思路 1.3.1 单点法(Pointwise) 1.3.2 配对法(Pairwise) 1.3.3 列表法 ...

最新文章

  1. Codeforces Round #506 (Div. 3)
  2. Java并行程序基础
  3. c#中计算三角形面积公式_看着有点迷的三角形面积计算
  4. 维护win10注册表
  5. Python的lambda, filter, reduce 和 map简介
  6. Applet与NoClassDefFoundError那不为人知的故事[转]
  7. 模糊规则优化matlab,遗传算法优化模糊pid控制规则
  8. ARM开发板编译----MYS-6ULX
  9. 非常规手段免疫U盘病毒(Autorun.inf)
  10. 利用urdf及RobCoGen生成运动学及动力学代码
  11. 我的融资咨询FA之路——资料篇
  12. 解决显存不足:Out of video memory trying to allocate a rendering resource
  13. 前端工程师的 2018 年总结
  14. 零基础语法入门第第二十三讲 动词的用法总结
  15. 知了猴的营养成分和作用
  16. 新型海上风电机组及压缩空气储能系统的建模与控制(Matlab代码实现)
  17. cmd批量打开网页和关闭网页的批处理代码
  18. 主动降噪将成为TWS耳机的必备
  19. android bitmap图片下载三级缓存
  20. 怎么用vue自动更新页面数据

热门文章

  1. 3d 视频切换到全屏播放
  2. 全球一共有多少个搜索引擎?
  3. inverse java_Hibernate中的inverse的用法
  4. 【JavaProject】经典图书管理系统
  5. 极客日报:iPhone 13系列新增苍岭绿:7999元起;腾讯文档崩了;Android 12L命名为Android 12.1|极客头条
  6. jQuery笔记综合
  7. python字符串strip的作用_Python字符串函数strip()原理及用法详解
  8. python 字符串方法大全
  9. 第三方JavaScript的用法
  10. iOS Touches事件传递