主题《图片主题模型在推荐系统的应用实践》
主要会分下面几个部分,首先我简单介绍一下推荐系统和内容理解方面相关知识,然后介绍两个我们的应用实例:一个是基于目标检测的图片主题模型,另一个是基于特征提取的图片主题模型。那我们首先简单过一下推荐系统与内容理解。
首先我们知道推荐系统主要分两大部分:一个是协同过滤,协同过滤分为基于用户的和基于产品的;另一个是基于内容理解的内容推荐。
我们看协同过滤,基于用户的协同过滤就是先使用统计技术来寻找与目标用户有相同喜好的邻居,然后根据目标用户的邻居的喜好产生对于目标用户的推荐。也就是说,我们看左边这张图,它首先是根据了用户对物品的一个行为日志,通过这个行为日志来找到用户跟用户之间的相似,再用这些相似的日志进行推荐。比如说我们认为用户A和用户C比较相似,用户A只访问了物品A和C,而用户C访问了物品A、C、D,那我们就可以对用户A推荐物品D。这是一个基于行为日志的基于用户的协同过滤。
那么基于物品的协同过滤也是相似的,也是根据这些行为日志来发现物品间的相似度,然后根据目标用户的历史偏好信息将这些类似的物品推荐给用户。比如我们认为物品A被用户A、用户B、用户C都喜欢,物品C被用户A、B喜欢,物品A和物品C相似,那么我们就把物品C推荐给了用户C,这是基于物品的协同过滤。
那么协同过滤有什么优点呢?首先它并不要求物品本身是可以描述的,我们只要理解了物品和人之间的关系就可以了;然后它的推荐也是开放式的,它基于全体用户的经验来进行推荐;它还可以发现用户的潜在兴趣。
协同过滤的缺点也比较明显。它是基于历史数据的,必然会有一些冷启动的问题;而且它也比较依赖于历史行为数据的多少和准确性,历史数据越多越准确,那我推荐肯定越好;第三个呢就是小众领域的推荐效果比较差,因为小众领域的历史行为数据肯定很少,那效果就不好,而且它也很稀疏,比如说有一万个用户、一百万个物品,这肯定是一个稀疏矩阵,那推荐效果就会比较差。
我们再看内容理解的推荐,内容理解实际是在推荐引擎出现之初应用最为广泛的一个推荐机制,它其实是比较老的。内容理解的核心思想是根据推荐物品的元数据或者描述内容来发现物品间的关联性,然后基于用户以往的喜好记录来进行推荐。它看起来和基于物品的协同过滤很相似,但实际上它对于物品进行相似度计算的时候并不是根据历史日志,而是根据一些元数据内容。比如说电影,我们可以把电影分成不同的类,电影A是爱情和浪漫的、电影B是恐怖惊悚、电影C是爱情和浪漫,我们就认为电影A和电影C是相似的。如果一个人喜欢电影A,那么我们也会认为他会喜欢电影C,因为A和C是同一类别的。
基于内容理解的优点是它能够很好的建模用户的口味,我能够很明显看出来他是喜欢什么样的东西,就像刚才那个电影的例子;第二个是能解决物品的冷启动问题,一个新的物品来了,它没有被很多人看过它就没有历史日志,没有历史日志的话我们就不能用协同过滤,但是我们可以用内容理解,因为我只要很好的标注了这个物品是什么,通过它的元数据和描述计算相似度,就能进行推荐;第三是对于小众领域也能有比较好的推荐效果。
它的缺点也很明显。它首先要求你对物品进行分析和理解,而且理解的完整性和全面性会严重的影响推荐效果;而且它没有考虑人对物品的态度,它只考虑了物品的相似度;它对于新用户也是有冷启动的问题。
上面我们介绍了两种主要的推荐算法,那么我们看看为什么要做基于内容理解的推荐。
在实践中,基于协同过滤的推荐,它的展示和点击率肯定是更好的,因为它推荐的是比较热的,但是基于内容理解的优势是它的覆盖度比较高。比如你来了物品,这个物品它即使不热,也就是说它没有什么历史记录,没有历史记录的话它的协同过滤可能出不来,但是基于内容理解的话它就可以推荐出来了,所以说覆盖度比较高,这是一点。
第二点是优质的内容推荐可以产生纯度高、覆盖率高、规律强的用户行为,从而提升协同推荐的效果,所以我们认为内容理解对于推荐系统是至关重要的。
如何做好基于内容理解的推荐?我们认为内容推荐包括两部分:第一部分是内容理解,也就是内容结构化;第二部分是热度排序。
这个排序很简单,我们主要来看一下怎么做内容结构化。上图是一个例子,内容结构化我们有很多方式。
比如说我们可以通过关键词:关键词是我们对内容理解的一个方式,关键词比较依赖于成熟的分词技术。
第二个就是分类:一级类二级类三级类。分类实际上是相当于我们把传统人工运营里面的知识来带到自动化运营中。
第三个是知识图谱。知识图谱就是我们对实体,对物品建立图,然后根据图来知道实体之间的联系和关系,也可以是主题模型,也就是本次分享主要要说的。
这些内容结构化的方法也是基于内容理解推荐的核心。
上图是我个人对于视频的内容理解的看法。我认为视频内容理解可以分成以下几个大块:第一个就是标题和描述,这是比较原始的数据;第二个是关键词;第三个是视频本身的内容;第四个是封面图片。
我们看标题和描述以及关键字实际上都是NLP问题(自然语言处理问题),视频也能拆成两部分,一个是它的音频,音频也能转化成文字进而归纳为自然语言处理问题;视频里面还有关键帧,我们提取关键帧和封面图片都能归纳成图像处理问题。所以我个人认为视频内容理解主要能归纳为NLP问题和图像处理问题,我本次分享主要是分享图像处理问题。
那么如何归纳图片的主题呢?我这次介绍两种我们做的方法:一种是基于目标检测的,另一种是基于特征提取的。
下面我们先对目标检测方法进行一个分享。
首先,什么是目标检测方法呢?目标检测方法就是我们先检测出图中的实体并根据实体信息将图像分类至不同话题。多标签分类和目标检测是两种类似的方法,我们来看一下它们的区别是什么。
左右是两张相同的图,左边这张图通过多标签分类可以看出来它有狗、有桥,但是多标签分类只能看出来它是否具有某种物品。那么目标检测呢不仅可以看到是否具有某种物品,还能看到有几个物品,这个物品它会拿框框出来,也就知道了它所占图片的面积比以及所在的位置,这些都是一些更详细的信息来帮助我们理解这个图片。
比较常用的目标检测方法包括图上几类,我们主要使用了Yolo9000和SSD两种方法。
下面我主要以SSD方法为例子来介绍一下。
左边是一张图,我们要从图中找到有哪些物品以及这些物品在哪。它就分为两个问题:第一个问题就是类似多标签分类问题,它有什么?第二个问题就是我要画一个框,把这个物品在哪框出来。理论上它是这样做的:
它先经过一个卷积模型,任何卷积模型都可以,比如说VGG16或者说你能想到的方法都是可以的,这时候会得到一个feature map,在这个feature map上呢用两个损失函数:第一个损失函数呢是这个box用来拟合矩形位置的,用的是一个L1的Smooth函数;第二个相当于是一个多标签的分类模型,是一个Softmax损失。将两个损失加起来,我们就得到了SSD的总损失。
现在讲一下这个框是怎么框出来的。举一个例子,SSD是一个多层的,它要在不同的粒度上来对这个框进行选取,比如说我现在有一个8×8的框,一共64个格子。那么在SSD中,每个格子都有一个候选的样子,比如说我们能看出来它一共有4个格,然后我们就能看出来现在就有8×8×4个格子,然后计算每个格子和这个GT的损失,找到与它最相似的,我们就能在feature map中找到最相似的一个格子。然后我们在另外一个4×4尺度的图上,用相同的方法也能算出哪个格子和GT格子最接近。也就是说在feature map上,对于每一个物品我们都能得到两个数:一个是位置的损失,一个是多标签的损失。
然后这个就是SSD的一个实例,它前面是VGG16,然后在后面加上一些多层的feature map。
这张图可以看的更明显一些。首先是一个输入,然后经过一层VGG得到一个38×38的图,对这张图我们找到它的位置,用分类器找它属于哪个类,得到一个结果。再走一层VGG,拿到一个19×19的图,也是一个位置和分类的结果,一直到最后也是一个位置和分类的结果。这时我们就有了6个位置和分类的结果,然后对这6个结果进行非最大抑制,就能找到最合适的那个位置及多标签分类结果。
这是我们一个目标检测实例。我们可以看到图中用框把狗框出来了,我们要理解一下SSD能框出什么物体来是要预先训练的。
右上角的图写着17 | 0.917,这个17代表了预先定义的一个分类,0.917代表了它分到这个类的可能性。
目标检测的一个最大特点是只能检测出训练集中已有的类别,比如说训练集中一共有9000个类别,那它只能检测出这9000个类别。
那我们如何把目标检测应用到图片检测主题中呢?
我们首先可以将原始视频拆成关键帧,这个关键帧有很多拆法,比如说固定间隔时间、剧烈抖动时等都是可以的,然后将每个关键帧提取它的SSD特征。比如说有9000个类,这就是9000列,有几个物品就是这个数再乘上这个物品那个框的面积再除以整张图片的面积,就得到了在这一帧中这个物品占这幅图的重要性。我们可以对每一个关键帧得到一个向量,然后对这些向量进行含权累加即可得到整个视频在每一类上的信息。比如说9000类,我们得到了9000类的一个向量,这个向量可以代表这个视频对于这9000类的一个主题分布,然后就可以在向量上做相似度计算了。
这是我们相似度计算的一个Demo,上面是查询图,下面是我们查出来最相似的TOP1,我们可以看到效果还是不错的。
在整个训练过程中我们发现目标检测方法有个缺点,就是说它只能预先识别训练的物品,比如训练集有9000个类,那么它只能从这9000个里寻找。
那我们有没有方法可以启发式的在图片集中找到相似的但是没有训练过的方法呢?我们选择了特征检测方法。
特征检测方法我们想这么做。首先我们通过检测图片集中每张图的特征,然后把图片特征点提取出来,将特征点聚类到关键词,有了关键词以后我们就可以把它们理解为普通的文本的主题模型了,进而可以应用经典的词袋模型、倒排索引、LDA、欧氏距离等。
这是我们整个模型的思路,我们首先有一个图片集,把这些图片集特征点提取,让它们聚类形成特征也就是它的视觉关键词,将相似的关键点放到一起,以关键词计算相似度,最后得到话题聚类。
特征点提取算法有很多种,我们这里使用了适度不变特征变换(SIFT),在我们实践过程中SIFT的效果是最好的。SIFT的特点是对旋转、尺度缩放、亮度变化保持不变形,而且信息量丰富、量大、可扩展性也比较强。
SIFT实质是在不同尺度空间查找特征点,然后计算出方向,尺度空间是通过高斯模糊来获得的。我们看到I是原始图,G(σ)是高斯函数。高斯函数的σ越大,图像越模糊,如果k2=2的话也就相当于是在清晰度不变的情况下缩小了一半。
基于此我们可以构建出来一个金字塔。金字塔的每一层内部是逐渐模糊的,也就是前面说的通过k2、k3来逐渐模糊的,但它们尺度是一致的。当它们kx=2的时候,就相当于是隔点扫描,尺度缩小了一半,每层内部是逐渐模糊的,层跟层之间是隔点扫描,是逐渐变小的。我们在这个例子中是有五组,每组内部在做高斯差分,SIFT认为重要的点都是在模糊的差别那部分。比如说每个金字塔内有S个尺度,做完差分后就变成S-1了,对于差分中的每一个点再取局部极值,保留其作为特征点。
我们找到了特征点,再计算特征点的方向。取到周围8×8的特征点,上面式子是方向的模,下面式子是方向的角度。我们把这些方向放到一起,相加得到八维的实数向量,这个八维的实数向量即可表征特征点的方向。
那么如何计算关键点的特征向量呢?首先我们将特征点旋转坐标系,这样就能保持旋转不变性。比如要计算某个点的方向,就把数轴旋转到跟它一样的方向,再在周围找4×4的格子,每个格子是3倍的σ,就是当前的高斯尺度。对落到每个格子的其它的周围的点再计算它们的方向,中间是我们要计算的特诊点,周围是其它点的方向,这个方向我们刚才说过是一个八维的实数向量。此时我们对特征点得到一个4×4×8,也就是128维向量。
这个就是基于特性提取的图像主题模型。
我们首先将视频拆成关键帧,对于每个关键帧,我们提取出每一个它后面的描述符,就是我们之前那个128维的向量,这个128维的向量是两两不同的。我们理解在文本处理中,如果每一个字都是不重复的,那我们实际上无法计算出它们的相似度,我们认为两篇文章相似是因为它们有词的共现。所以我们将这些描述符进行聚类,得到视觉关键词,再将这些关键词回带回来,从而得到一个图片对于关键词的矩阵,再对这个关键词应用TF-IDF模型,即可得到每张图片的词袋模型,这样我们就可以在每张图片的词袋模型上计算相似度。
那我们为什么可以做到这么快呢?这个框架叫FAISS,它是Facebook开发的一个用于稠密向量的相似性搜索和聚类的高效运算库;它包含了任何大小的向量集合里进行搜索的算法,包括无法被完全读入内容空间的向量集合;它使用C++编写,而且可以被Python调用。
这是主题聚类的一个示例。最后一张图是查询图,前面5个分别是TOP1、2、3、4、5,我们可以看到它通过每张查询图找到的都是很相似的图片。拿第一个举例,目标图和每个结果图中都有涂磊这个人,这个用目标检测方法是不可能做到的,因为目标检测中不可能有涂磊这个类,它只会有人这个类;最后一个查询图是一个老师在讲课,查询出来的结果TOP1、4、5都是讲课的图,所以我们认为这个主题聚类效果还是很不错的。