推荐系统概述(二)
如何在没有大量用户数据的情况下设计个性化推荐系统并且让用户对推荐结果满意从而愿意使用推荐系统,就是冷启动的问题。
冷启动问题(cold start)主要分3类。
用户冷启动
物品冷启动
系统冷启动
1)用户冷启动可以利用用户注册信息,也可以选择合适的物品启动用户的兴趣(基于NLP方向的推荐)
2)物品冷启动可以利用物品的内容信息
3)系统冷启动可以发挥专家的作用
本文重点介绍文本处理(基于用户冷启动的NLP推荐算法)。
算法涉及到了:
- 文本相似度 (COS相似度;Jaccard相似度)
- 文本距离 (欧式距离;曼哈顿距离;闵科夫斯基距离,马氏距离)
- NFM (基于内容的协同过滤 + 基于人物的协同过滤)
- 主题模型推荐 (PLSA模型,LDA模型,ATM模型)
- 知识图谱 (知识关联,知识推理)
- 后台热门统计 (分时,分天,分周,分月分别进行统计结果输出)
1.针对于非结构化的数据(文本类)
- 非标准字符的去掉(标点符号)
(标点符号认为是无用的,选择python的re工具包即可) - 分词 (仅中文需要)
(中文的问题是所有词都是挨着的,分开才有效,选择jieba工 具包) - 词干化和统一化(仅英文需要)
(英文的单词是由过去,将来,现在进行时的,所以词干化,这部分选择NLTK处理) - 去除停用词(中英文都需要)
(比如常用的“的”“得”“了”......"the""in""too"......等词,无论是经过one-hot,TF-IDF,word2vec处理,都是一些相关性很低的词,这些词的加入很引起特征值不必要的增大和运算时候的难度和时间,但是并没有效果提升) - 向量化
(计算机只能处理矩阵,所以变化为矩阵是必经之路,Bag ofword,TF-IDF法,Word2vec法,工具包是基本每个ML和DL框架平台都提供API)
文本预处理流程:
- re正则表达式去除标点符号,HTML无用信息,表情符号........
re正则表达式学习教程地址:http://www.runoob.com/regexp/regexp-tutorial.html
re正则表达式练习地址:http://tool.oschina.net/regex/ - jieba 分词API:https://github.com/fxsjy/jieba
- nltk工具包: http://www.nltk.org/
- 去除停用词:各种计算框架均有stopword
- 词的向量化方法: bag of word, N-Grame, TF-IDF, word2vec
词的向量化表示:bag of word, N-Gram, TF-IDF, word2vec.
- bag of word:
词频统计技术默认出现频率越高的词权重越大。
API:
sklearn.feature_extraction.text import CountVectorizer
问题:1.基于统计的,维度会非常大,计算会出现维度灾难
2.默认为各个词之间独立不相关的,无关联的,没有语义关联,实际中应用无法提升,只能适用于小语料计算。 - N-Gram:
通过N-gram 方式在把前后关联的词进行了组合,增加了前后此的语义关联性,同时增大了数据集,但是这也就造成了两个影响:
1.数据维度瞬间增大,通常情况下,我们最多使用到4-Gram组合即可,因为分词后再前后语义关联,造成的维度太大,计算不仅影响了速度。
注:因为关联词的n-gram的方法,思维启发,后面针对于时间序列的关联和推算的算法有HMM-隐马尔科夫模型 / RNN-循环神经网络模型, HMM模型常用来自然语言的分词,jieba分词API就是用HMM模型做的算法
2.数据维度瞬间增大的同时,不仅增加了新词的发现能力,造就了新词,增加了特征的数据量,同时也造成了一个不可避免的事实就是句子中那些关键的比较重要的词,在词袋作用下,比例会非常小,本身是关键语义,但是却成了不关键的语义了,大大损失了句子的真实性,二破坏了本来的特征重要性,这样就到了我们数据处理常用的“数据平滑技术”
数据平滑是对频率为0的n元对进行估计,典型的平滑算法有加法平滑、Good-Turing平滑、Katz平滑、插值平滑,等等。
n-gram模型的解码算法
为什么n-gram模型需要解码算法呢?举个例子来说,对于音字转换问题,输入拼音nixianzaiganshenme,可能对应着很多转换结果,对于这个例子,可能的转换结果如下图所示(只画出部分的词语节点),各节点之间构成了复杂的网络结构,从开始到结束的任意一条路径都是可能的转换结果,从诸多转换结果中选择最合适的结果的过程就需要解码算法。
常用的解码算法是viterbi算法,它采用动态规划的原理能够很快地确定最合适的路径。这里就不详细介绍该算法了。
sklearn.feature_extraction.text import CountVectorizer(ngram_range =(1,1))
问题:1.基于统计的,维度会非常大,计算会出现维度灾难
2.默认为各个词之间设置了N相关的,实际中最多N=3,维度会非常大,计算会出现维度灾难
-
TF-IDF:
TF-IDF是“词频-逆文本频率”。由两部分组成,TF和IDF。
TF标表示的是“词频”,句子向量化就是做了文本中各个词的出现频率统计,并作为文本特征关键
IDF即“逆文本频率”。IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。 IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,反之,如果一个词在比较少的文本中出现,那么它的IDF值应该高。
API:
sklearn.feature_extraction.text.TfidfTransformer
sklearn.feature_extraction.text.TfidfVectorizer
问题:1.基于统计的,维度减小,语义表达轻量化,训练计算快
2.依旧是基于统计类型的,依旧是条件独立假设,不过思维方式变化成了跟总文档做对比,增加了可靠性,依旧没有语义推断性,依旧没有考录基于序列的准确性。 -
word2vec:
word2vec来解决句子中词的先后语义关联和减低维度,来提升“特征”的表达能力
一般分为CBOW(Continuous Bag-of-Words)与Skip-Gram两种模型。
- 霍夫曼树(Hierarchical Softmax):
优点:降低了基于DNN的网络难度,提升使用效率,更直观易懂,适合了大语料计算
缺点:生僻词求解需要寻根更久,花费时间过长,霍夫曼树模型深度和叶子数量更庞大。 - 负例采样(Negative Sampling):
优点:购置虚假样本,梯度求解,求解更快
缺点:
霍夫曼树:
首先,对于从输入层到隐藏层的映射,没有采取神经网络的线性变换加激活函数的方法,而是采用简单的对所有输入词向量求和并取平均的方法
第二个改进就是从隐藏层到输出的softmax层这里的计算量个改进。为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。
在word2vec中,采用二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid激活函数。注意:Skip-Gram模型并没有和CBOW模型一样对输入进行迭代更新,而是对2c个输出进行迭代更新。
首先,由于是二叉树,之前计算量为V,现在变成了log2V
第二,由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。
负例采样:
如果词汇表的大小为V,那么我们就将一段长度为1的线段分成V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。在采样前,我们将这段长度为1的线段划分成M等份,这里M>>V,这样可以保证每个词对应的线段都会划分成对应的小块。而M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从M个位置中采样出neg个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。
问题:1.基于统计的,维度减小,语义表达轻量化,训练计算快
2.依旧是基于统计类型的,依旧是条件独立假设,不过思维方式变化成了跟总文档做对比,增加了可靠性,依旧没有语义推断性,依旧没有考录基于序列的准确性。
2.针对于结构化数据(用户行为数据)
- 数据的表达
(连续数值的分段处理;离散数据的哑变量处理) - 数据的处理
(重复数据的去重;
缺失值数据的处理:连续值取中位数,离散数据 取众数;
数据的归一化:均值归一化,最大最小值归一化,Log归一化。
异常值数据的处理:聚类。
数据倾斜:上 / 下采样+算法权重法) - 特征的选择
(过滤法:方差,信息增益,卡方,互信息,相关系数。
嵌入法:GBDT, RF。
特征组合:人工组合,自动组合)