0.前言

  • 详细介绍逻辑回归,并给出参数迭代更新公式【非常基础,非常重要】
  • 使用逻辑回归的方法实现电影推荐
  • 项目地址见github

1.主要思想

  • 逻辑回归
  • 数据向量化

2.逻辑回归

2.1 逻辑回归是什么?

  • 逻辑回归是监督学习中的 分类 算法。

什么是监督学习?
带标签的学习,即给出的数据用标签标注,有明显的正确答案。

什么是分类算法?与分类对应的回归算法又是什么?
简单的说,分类算法用于分类;回归算法用于计算具体的值。
比如:预测明天青浦区的天气问题【雨,晴,多云】。其值是确定的(数学里面说就是离散的),那就是分类问题;预测明天的股价这就是回归问题。其值不确定,但是其值连续,任何一个数值点都有可能取到,这就是回归问题。

2.2 逻辑回归能干什么?

进行分类预测。
在推荐系统中,可以将是否点击一个商品看成一个概率事件,被推荐的商品无非只有两种可能性:被点击;不被点击。那么就可以将这个推荐问题转换成一个分类问题。哪些商品会被点击,哪些商品不会被点击?所以可以使用逻辑回归来进行一个分类预测。

逻辑回归算法可以用在很多问题上,下面就聊聊其在电影推荐上的使用。

3. 逻辑回归实现电影推荐?

  • 协同过滤模型仅利用用户与物品的相互行为信息进行推荐【单一特征】。

  • 逻辑回归模型能够综合利用用户,物品,上下文等多种不同的特征生成较全面的推荐结果【多特征融合】。融合体现在将所有的特征放到同一个向量【称之为特征向量】中。

3.1 具体步骤

  • (1)将用户年龄、性别、物品属性、物品描述、当前时间、当前地点等特征转换成数值型特征向量;
  • (2)确定逻辑回归模型的优化目标(以优化点击率为例),利用已有样本数据对逻辑回归模型进行训练,确定逻辑回归模型的内部参数
  • (3)在模型服务阶段,将特征向量输入逻辑回归模型,经过逻辑回归模型的推断,得到用户“点击”物品的概率
  • (4)利用“点击概率”对所有候选物品进行排序,得到推荐列表

3.2 可疑之处

上述描述中的问题:

  • 得到用户点击的概率,那么这个概率肯定是个连续值,为啥要用“逻辑回归”这么一个 分类器 来做?

3.3 数学形式

  • (1)将特征向量:X=(x1,x2,....xn)TX = ({x_1,x_2,....x_n})^TX=(x1​,x2​,....xn​)T 作为模型的输入
  • (2)通过为个特征赋予相应的权重:w=(w1,w2,....wn)w=({w_1,w_2,....w_n})w=(w1​,w2​,....wn​) 来表示各特征的重要性差异,将各特征进行加权求和,得到xTwx^TwxTw
  • (3)将xTwx^TwxTw 输入到 sigomid 函数中,使之映射到0~1 的区间,最终得到“点击率”

简单说一下sigmoid函数:

  • 函数公式
    f(z)=11+e−zf(z) = \frac{1}{1+e^{-z}}f(z)=1+e−z1​

  • 函数图像

4.训练过程

前提:
(1)使用逻辑回归完成二分类
那么具体是怎么训练的?怎么样才能找到一个合适的w?

  • step1.初始化w
    初始化可以随意进行,但是也是有讲究的,这里不再涉及。我们就以最简单的初始化方式,将其全部取成0。即w=[0,0,...,0]

  • step2.确定损失函数
    损失函数该是什么样子呢?因为是二分类,那也就是说:每个物品都有点(记为y=1)、不点(记为y=0)两种选择。在电影评分这个系统中,虽然电影评分有高低之分,但是我们将其简化处理为 看过、没看过 两种状态【这种状态就是监督学习中所说的标签】。根据这个标签,那么就可以由 极大似然估计思想 得到一个损失函数。极大似然估计我们后面再补充。
    {p(y=1∣x;w)=fw(x)p(y=0∣x;w)=1−fw(x)\left \{ \begin{aligned} &p(y=1|x;w)=f_w(x)\\ &p(y=0|x;w)=1-f_w(x) \end{aligned} \right. {​p(y=1∣x;w)=fw​(x)p(y=0∣x;w)=1−fw​(x)​
    这里的fw(x)f_w(x)fw​(x)就是判断x被分类为1的概率。相应的,1−fw(x)1-f_w(x)1−fw​(x)就是被分类为0的概率。将上式综合起来【为啥要统一形式呢?为了更加方便的表达】 ,可以得到式:
    p(y∣x;w)=[fw(x)]y[1−fw(x)]1−yp(y|x;w) = [f_w(x)]^y [1-f_w(x)]^{1-y}p(y∣x;w)=[fw​(x)]y[1−fw​(x)]1−y
    如果再用极大似然估计去估计这个参数,那么就得到了如下的目标函数:
    MLE(w)=∏i=1mp(yi∣x;w)=[fw(x)]y[1−fw(x)]1−yMLE(w) = \prod_{i=1}^m p(y_i|x;w) = [f_w(x)]^y [1-f_w(x)]^{1-y} MLE(w)=i=1∏m​p(yi​∣x;w)=[fw​(x)]y[1−fw​(x)]1−y
    为了计算方便,将其取对数后,再乘以系数−1m-\frac{1}{m}−m1​,得到的目标函数:
    J(w)=−1mlog[L(w)]=log{∏i=1mp(y∣x;w)}=−1m{∑i=1m[yilogfw(xi)+(1−yi)log(1−fw(xi))]}J(w) =-\frac{1}{m} log[L(w)] =log\{ \prod_{i=1}^m p(y|x;w) \} = -\frac{1}{m} \{ \sum_{i=1}^m[ \space y^ilogf_w(x^i)+(1-y^i)log(1-f_w(x^i))] \space \} J(w)=−m1​log[L(w)]=log{i=1∏m​p(y∣x;w)}=−m1​{i=1∑m​[ yilogfw​(xi)+(1−yi)log(1−fw​(xi))] }
    注:
    (1)取完log后,阶数变成了系数。所以上面这个公式有系数yiy^iyi 和 系数(1−yi)(1-y^i)(1−yi)
    (2)这个损失函数也就是处理分类问题中最常用且著名的函数——交叉熵函数

二分类的交叉熵损失函数
L=−[ylogy^+(1−y)log(1−y^)]L=-[ylog\hat y + (1-y)log(1-\hat y)]L=−[ylogy^​+(1−y)log(1−y^​)] 其中y是真实值,y^\hat yy^​是预测值。因为是二分类,所以它们的取值集合是{0,1}。

  • step3.优化方法
    得到这个损失函数之后,就可以开始采用传统的梯度下降方法进行训练,并得到最终的结果。对参数wjw_jwj​求偏导的结果如下:
    ∂J(w)∂wj=1m∑i=1m(fw(xi)−yi)xji\frac{\partial J(w)}{\partial w_j} = \frac{1}{m} \sum_{i=1}^m (f_w(x^i)-y^i)x_j^i ∂wj​∂J(w)​=m1​i=1∑m​(fw​(xi)−yi)xji​
    在得到梯度之后,即可得到模型的参数更新公式,如下所示:
    wj=wj−γ1m∑i=1m(fw(xi)−yi)xjiw_j = w_j - \gamma \frac{1}{m} \sum_{i=1}^m (f_w(x^i)-y^i)x_j^i wj​=wj​−γm1​i=1∑m​(fw​(xi)−yi)xji​
    至此,便完成了逻辑回归模型的推导过程【下面补充一下导数的求解过程】。

5.电影推荐如何实现?

针对上面的叙述,我来结合电影数据和我的代码来讲解如何完成一次推荐过程。

5.0 说明

5.0.1 数据

-rw-r-----@  1 gamidev  staff   1.5M  3  9  2001 u1.base
-rw-r-----@  1 gamidev  staff   383K  3  9  2001 u1.test
-rw-r-----@  1 gamidev  staff   1.5M  3  9  2001 u2.base
-rw-r-----@  1 gamidev  staff   386K  3  9  2001 u2.test
-rw-r-----@  1 gamidev  staff   1.5M  3  9  2001 u3.base
-rw-r-----@  1 gamidev  staff   387K  3  9  2001 u3.test
-rw-r-----@  1 gamidev  staff   1.5M  3  9  2001 u4.base
-rw-r-----@  1 gamidev  staff   388K  3  9  2001 u4.test
-rw-r-----@  1 gamidev  staff   1.5M  3  9  2001 u5.base
-rw-r-----@  1 gamidev  staff   388K  3  9  2001 u5.test
  • base是基础训练数据;test是测试数据
  • 使用到模型训练工具 pytorch

5.1主要步骤

5.1.1 获取特征向量

在公式y = wx + b 中,需要确定各个向量中的数据是什么。这一般会结合实际的数据映映射+抽象得到。例如:结合用户信息、电影信息得到如下特征向量的格式:x=【用户id,用户年龄,性别,职业,电影id,电影类别】
其中电影类别不是一个值,是一个1*18的向量,其每个维度代表的信息是:

unknown | Action | Adventure | Animation |Children’s | Comedy
| Crime | Documentary | Drama | Fantasy |Film-Noir
| Horror | Musical | Mystery | Romance | Sci-Fi |Thriller | War | Western

例如有如下数据:
u.user => 19|40|M|librarian|02138
数据说的是:userid=19,年龄是40,性别是Male=>0, librarian => 1[统一映射]
因为需要针对这个人推荐,所以我这里找出他看过的电影以及评分记录:
19 274 2 879539794也就是说,看过的电影id是274,那么得到的特征向量就是 x = [19,40,0,1,274,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0]。下面给出一个得到的特征向量的例子:
featureDs 是类FeatureDataset的实例。我们主要用到其 feature 和 label 这两个属性。如下图所示:

同时,在 featureDs 这个实例中下的feature有80000条数据,每条数据都是一个特征向量,如下图所示:
我们接下来就会用这些特征向量去训练模型。
y表示的是正样本【推荐看的电影1】亦或是负样本【不推荐看的电影0】。这里有几个地方需要注意:

  • 训练部分
    我们训练的时候是按照y=1,y=0这个标签来训练的,利用MLE方法进行模型的训练(所以需要分类,即有正负样本之分),得到一个最终的预测模型。
  • 预测部分
    根据训练好的模型预测时,输入特征向量x,会得到一个概率值【而不是一个特征值】,这个概率值表示的则是这个电影被推荐的概率大小【是个连续值】。

5.1.2 模型训练

简单回顾一下整个模型简图:
上图中的逻辑回归主要会做如下几件事儿:

  • x1−x3x_1 - x_3x1​−x3​ 是特征向量中的个体数据
  • 执行一个线性变换操作
  • 执行激活函数操作
  • 最后可设定一个阈值,对激活函数的值做一个分类,便得出最后的结果

再对应来看我的代码:

  • 这里的x1,x2,x3x_1,x_2,x_3x1​,x2​,x3​ 就对应我们特征向量中的每个数据。只不过我们这里是x0−x23x_0 - x_{23}x0​−x23​。
  • 线性变换和激活函数操作怎么来?
    由我们事先定义的类 LogR(nn.Module) 实现这个部分,具体如下图所示:
  • __init__() 函数是用于定义模型会具体使用什么包,比如说:这里的 self.linR = nn.Linear(in_features,out_features) 说明linR是pytorch 包下Linear(...)的实例。我们指定输入数据的特征,它就会在这个数据上执行线性变换操作。self.sg = nn.Sigmoid()同理。
  • forward()函数是模型真正训练时执行的。它强调的是 模型的调用顺序,比如说,由上图显示可知,我们这里是先执行线性变换,然后执行激活操作 (sigmoid) 。

现在模型已经有了输入,输出,但是还不知道模型的好坏,所以我们得搞个东西来衡量模型的好坏,这个东西就是 损失函数,同时,我们还需要将损失函数的损失降到最小,所以就需要 优化器 来优化模型。

5.1.3 模型优化


上面方框中的分别就是我们使用的逻辑回归模型的损失函数和优化器。通常为了加速训练,可以将数条【”数条“的值=BATCH_SIZE】特征向量拼接成一个矩阵的形式,然后得到一个mini-batch。在pytorch中,为了方便将数据搞成mini-batch 和并行加载数据。搞出来一个Dataset类和DataLoader类。

上面四个框,分别对应的是:

  • 01.从DataLoader 的实例中得到训练数据。其包括两个部分:【特征向量,和标签】
  • 02.把数据放入我们的模型中,得到结果数据
  • 03.将结果数据同label 进行比较,得到损失值
  • 04.通过优化器降低损失值

5.1.4 模型效果

可以看到训练的正确率 在94% 上下,但是测试模型效果在 93% 左右。

6.问题

本节提出逻辑回归中的系列可疑之处,供大家参考

6.1 为什么训练的时候是用 y=1/0,而预测得到的值却是一个概率值?

  • 训练和预测本来就没有关系
  • 逻辑回归做的目的就是分类。所以需要使用y=1/0去表示是属于1类【正样本】还是0类【负样本类】,损失函数用的是适合处理分类问题的交叉熵算法(cross entropy

6.2 为什么用交叉熵算法而不用别的算法【如均方误差算法(mse)】?

这个涉及到梯度下降时参数更新的问题。在mse算法的梯度计算公式中,因为 sigmoid 导数的性质会导致参数无法更新,所以使用了交叉熵算法而不是均方误差。

6.3 单纯使用点击率是否不妥?

在商品广告的推荐里,使用点击率无可厚非。但是在推荐电影的这个系统中,仅仅使用点击率来衡量问题是否欠妥?

7.补充

7.1 极大似然估计

  • 已知:某个随机样本满足某种概率分布,但是其中具体的参数不清楚
  • 参数估计:就是通过若干次试验,观察其结果,利用结果推出参数的最大概率的取值

常用MLE方法去估计一个参数的取值。求极大似然估计值的一般步骤如下:

  • step 1.通过分布函数确定每种情况的概率取值PiP_{i}Pi​ 1<=i<=n
  • step 2.将上述的概率做一个乘积,这个乘式就是似然函数
  • step 3.将似然函数取对数,并化简整理
  • step 4.求偏导数,然后令其值为0,得出相关参数的解析解。这个解析解就是参数估计值。

【算法工程师面试题40】基于逻辑回归算法实现电影推荐相关推荐

  1. 基于逻辑回归算法模型搭建思路

    在真实工作场景中,有多种算法依据借贷数据集建立模型,主要使用的算法有逻辑回归.神经网络.决策树.贝叶斯信念网.GBDT算法等,本系列文章旨在为刚入门和对模型感兴趣的同学介绍传统风控模型算法之一--逻辑 ...

  2. 基于逻辑回归算法的心脏病不平衡数据分类代码实现

    1.数据说明 数据来源Kaggle网站中引用的CDC数据,原数据大概有300个变量,这里大约使用20个,严重不平衡数据,约为1:9.该代码通过对进行清洗,标准化,欠采样(Undersampling)进 ...

  3. 基于逻辑回归算法癌症症状预测分析

    本文后面附有数据集 逻辑回归介绍 逻辑回归(Logistic Regression)是机器学习中的一种分类模型,虽然名字中带有回归, 就是因为它与回归之间有一定的联系.由于算法的简单和高效,在实际中应 ...

  4. 大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型

  5. 深度学习原理-----逻辑回归算法

    系列文章目录 深度学习原理-----线性回归+梯度下降法 深度学习原理-----逻辑回归算法 深度学习原理-----全连接神经网络 深度学习原理-----卷积神经网络 深度学习原理-----循环神经网 ...

  6. 机器学习算法平台alink_机器学习-逻辑回归算法

    1-逻辑回归算法原理推导 逻辑回归算法其实是一个分类算法,是非常经典,优秀的算法.一般我们不知道用哪个分类算法的时候,首先用逻辑回归算法试一试:它不仅可以实现二分类算法,还可以解决多分类问题 逻辑回归 ...

  7. ML之LoR:基于信用卡数据集利用LoR逻辑回归算法实现如何开发通用信用风险评分卡模型之以toad框架全流程讲解

    ML之LoR:基于信用卡数据集利用LoR逻辑回归算法实现如何开发通用信用风险评分卡模型之以toad框架全流程讲解 目录 基于信用卡数据集利用LoR逻辑回归算法实现如何开发通用信用风险评分卡模型之以to ...

  8. ML之LoR:基于LoR(逻辑回归)算法对乳腺癌肿瘤(9+1)进行二分类预测(良/恶性)

    ML之LoR:基于LoR(逻辑回归)算法对乳腺癌肿瘤(9+1)进行二分类预测(良/恶性) 目录 输出结果 设计思路 数据集 核心代码 输出结果 Testing accuracy (10 trainin ...

  9. 验证基于逻辑回归的隐马尔可夫模型的心音信号切分算法(literature study)

    这篇文章展示的是基于逻辑回归的隐马尔可夫模型(Logistic regression based hidden semi-Markovmodel (HSMM))心音信号切分方法. 参考文章可以到文末查 ...

  10. ML机器学习算法(一): 基于逻辑回归的分类预测

    机器学习算法(一): 基于逻辑回归的分类预测 1 逻辑回归的介绍和应用 1.1 逻辑回归的介绍 逻辑回归(Logistic regression,简称LR)虽然其中带有"回归"两个 ...

最新文章

  1. 如何使用OpenCppCoverage检查单元测试的行覆盖率
  2. 每日一九度之 题目1030:毕业bg
  3. 【转】AI-900认证考试攻略
  4. 2.1基本算法之枚举_1749数字方格
  5. 操作系统之I/O管理:3、设备的分配与回收(设备控制表DCT、控制器控制表COCT、通道控制表CHCT、系统设备表SDT、逻辑设备表LUT)
  6. java输入一串字符串反转_反转Java中的字符串
  7. linux下mysql日志管理及mysql备份还原
  8. guido发布python版本的年份_Guido van Rossum
  9. table内容保存到Excel中
  10. 基于beautifulSoup进行电影网站排名的获取与格式化输出
  11. 测量学7_地形图的基本知识
  12. 基于Spark的电商用户行为分析系统的设计与实现
  13. 胜利大逃亡(BFS)
  14. 支持DoH的DNS服务器,谷歌公共DNS正式支持DoH加密 更安全并且不影响速度
  15. ZZULIOJ1096-1100Python解法
  16. 面向对象的程序设计C++课堂复盘总结 C语言复习+C++基础语法
  17. 数据结构pintia_如何学好数据结构,去哪里刷题?
  18. Patches Are All You Need?
  19. Python制作基础学生信息管理系统
  20. PHP云招聘系统H5(源码+数据库脚本)

热门文章

  1. Labview 气体/温度检测系统
  2. Xposed安装与使用
  3. 如何驱动直流电机H桥驱动笔记
  4. dhtmlx技术使用总结与介绍中文手册
  5. STM32芯片包下载教程
  6. flyme禁止系统更新_彻底关闭魅族flyme系统自动更新的方法分享
  7. mvvm框架 android,mvvm框架原理 android 怎么使用mvvm框架
  8. 微信订阅号改回列表显示
  9. 在线抽奖、限时秒杀、拼团抢购,别的商城有的功能你也可以轻松拥有!
  10. 专业的WiFi检测工具有哪些?如何解决wifi信号不好?