1、基于Spark的大数据精准营销中搜狗搜索引擎的用户画像挖掘基于Spark的大数据精准营销中搜狗搜索引擎的用户画像挖掘近期参加了CCF举办的“大数据精准营销中搜狗用户画像挖掘”竞赛,最终得到复赛第32名。正好这学期机器学习与数据挖掘课程需要一个实验报告的大作业,于是就那它来写了。本博文会在这几周不断的完善更新ing1. 选题背景与意义1.1 用户画像与精准营销“用户画像”是近几年诞生的名词。很多营销项目或很多广告主,在打算投放广告前,都要求媒体提供其用户画像。在以前,大多媒体会针对自身用户做一个分类,但是有了大数据后,企业及消费者行为带来一系列改变与重塑,通过用户画像可以更加拟人化的描述用户特点
2、。 用户画像,即用户信息标签化,就是企业通过收集与分析消费者社会属性、生活习惯、消费行为等主要信息的数据之后,完美地抽象出一个用户的商业全貌,可以看作是企业应用大数据技术的基本方式。用户画像为企业提供了足够的信息基础,能够帮助企业快速找到精准用户群体以及用户需求等更为广泛的反馈信息。 消费方式的改变促使用户迫切希望尽快获取自己想要了解的信息,所以说,基于用户画像上的精准营销不管对企业还是对用户来说,都是有需求的,这会给双方交易带来极大便捷,也为双方平等沟通搭建了一个畅通平台。1.2 搜索引擎下用户画像的挑战在搜索引擎下,由于搜索引擎本身使用方式的特殊性、用户的流动性、查询的实时性等,带来了与企
3、业传统的对用户信息进行收集与分析有着巨大的不同、更加艰巨的挑战。 例如,我们实时获取到的是用户的查询语句,而由于用户的流动性,并不能直接获取到如年龄、性别、学历等用户的标签信息。这么一来,也就无法根据用户属性对用户进行分群处理,而后再通过推荐系统进行产品上的优化1.3 本文内容概要本文内容概要如下:第1章:简介用户画像与搜索引擎下用户画像的精准营销的挑战。第2章:说明实验集群、数据与课题研究目标。第3章:介绍使用分词工具对用户的搜索词列进行分词,以及相关的优化方案。第4章:介绍在分词的基础上,对文本进行特征的抽取与转换,以及相关的优化方案。第5章:介绍在原始特征向量上,进行聚类与降维。第6章:
4、介绍实验中试验过各分类模型第7章:介绍模型参数调优第8章:总结本课题研究中不足与展望后续的优化方案第9章:参考文献2. 课题实验准备2.1 Spark集群节点 备注cdh01 8核,32G内存,角色:Spark Master,HDFS NameNode,Spark Worker,HDFS DataNodecdh02 8核,12G内存,角色:Spark Worker,HDFS DataNodecdh03 8核,12G内存,角色:Spark Worker,HDFS DataNodecdh04 8核,12G内存,角色:Spark Worker,HDFS DataNode2.2 数据集数据文件 备注T
5、rain.csv 带标注的训练集Test.csv 测试集2.3 数据介绍本数据来源于搜狗搜索数据,ID经过加密,训练集中人口属性数据存在部分未知的情况(需要解决方案能够考虑数据缺失对算法性能的影响)。数据所有字段如下表所示:字段 说明ID 加密后的IDage 0:未知年龄; 1:0-18岁; 2:19-23岁; 3:24-30岁; 4:31-40岁; 5:41-50岁; 6: 51-999岁Gender 0:未知1:男性2:女性Education 0:未知学历; 1:博士; 2:硕士; 3:大学生; 4:高中; 5:初中; 6:小学Query List 搜索词列表2.4 数据示例对于train
6、.csv中的数据记录:00627779E16E7C09B975B2CE13C088CB 4 2 0 钢琴曲欣赏100首 一个月的宝宝眼睫毛那么是黄色 宝宝右眼有眼屎 小儿抽搐怎么办 剖腹产后刀口上有线头 属羊和属鸡的配吗2.5 课题任务描述根据提供的用户历史一个月的查询词与用户的人口属性标签(包括性别、年龄、学历)做为训练数据,通过机器学习、数据挖掘技术构建分类算法来对新增用户的人口属性进行判定。3. 查询词分词3.1 NLPIRNLPIR汉语分词系统(又名ICTCLAS2013),主要功能包括中文分词;词性标注;命名实体识别;用户词典功能;支持GBK编码、UTF8编码、BIG5编码。新增微博
7、分词、新词发现与关键词提取;张华平博士先后倾力打造十余年,内核升级10次。 全球用户突破20万,先后获得了2010年钱伟长中文信息处理科学技术奖一等奖,2003年国际SIGHAN分词大赛综合第一名,2002年国内973评测综合第一名。 我们传入每个用户的搜索词列,表经过NLPIR分词工具得到的分词。之后,我们做个进一步的优化策略:3.1.1 去停用词我们根据分词后词语所带的词性,对一些特征代表性不够强的词语进行过滤: for (int i = 0; i sbtmp.length(); +i) char cc = sbtmp.charAt(i); if (cc = ) sbtmp.deleteC
8、harAt(i); -i; else if (cc = /) / 去词条件 Boolean isdel = / 1. 去标点 (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = w) / 2. 疑问词 | (i + 2 sbtmp.length() & sbtmp.charAt(i + 1) = r & sbtmp.charAt(i + 2) = y) / 3. 数字 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = m) / 4. 连词 | (i + 1 sbtmp.length() & sbtmp.cha
9、rAt(i + 1) = c) / 5. 副词 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = d) / 6. 叹词 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = e) / 7. 拟声词 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = o) / 8. 介词 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = p) / 9. 量词 | (i + 1 sbtmp.length() & sbtmp.charAt(
10、i + 1) = q) / 10. 助词 | (i + 1 sbtmp.length() & sbtmp.charAt(i + 1) = u) / 11. 纯动词 | (i + 2 sbtmp.length() & sbtmp.charAt(i + 1) = v & sbtmp.charAt(i + 2) = ); / 去词 if (sbtmp.charAt(i + 1) != n & sbtmp.charAt(i + 1) != i & sbtmp.charAt(i + 1) != j & sbtmp.charAt(i + 1) != h & !(i + 2 sbtmp.length() &
11、 sbtmp.charAt(i + 2) = n) while (i + 1 = 0 & sbtmp.charAt(i) != ,) sbtmp.deleteCharAt(i); -i; / 若无需去词,把/转为,并去除随后的词性标志 else sbtmp.setCharAt(i, ,); while (sbtmp.charAt(i + 1) != ) sbtmp.deleteCharAt(i + 1); for (int i = 1; i sbtmp.length() - 1; +i) if (sbtmp.charAt(i) = , & (sbtmp.charAt(i - 1) = , |
12、sbtmp.charAt(i + 1) = ,) sbtmp.deleteCharAt(i); -i; / 去中间单个字 else if (sbtmp.charAt(i - 1) = , & sbtmp.charAt(i + 1) = ,) sbtmp.deleteCharAt(i); sbtmp.deleteCharAt(i); -i; / 去首个单个字 else if (sbtmp.charAt(i) = , & i = 1) sbtmp.deleteCharAt(i - 1); sbtmp.deleteCharAt(i - 1); -i; 3.1.2 提取关键词分词并不能很好的将常用的短
13、语提取出来,如词语“用户画像”,使用分词工具更倾向于将其分成“用户”和“画像”,而失去了词语本身的含义。NLPIR还提供了提取一段话的关键词的功能,我们可以使用它:int numofIm = 1000;String nativeByte = CLibrary.Instance.NLPIR_GetKeyWords(sInput, numofIm, false); 经过分词后,平均每位用户搜索词列所得到的词量在600个左右,这里我们设置提取1000个关键词,但实际上一个用户的关键词提取的数量在60200左右。由于关键词的很强的特征性,并且提取出的数量又少,若后续我们直接使用如词语的词频作为用户的特
14、征属性进行分类的话,很可能各个用户特征属性有巨大的差异,即用户之间拥有的相同关键词过少。3.1.3 混合提取在用户搜索词列分词基础上,在增加N次对其进行M个关键词提取的结果。3.2 “结巴”分词jieba,即“结巴”中文分词,一个优秀的开源的分词工具,一直致力于做最好的 Python 中文分词组件。我们直接使用它对用户搜索词列进行1000个关键词的提取,所能提取到的关键词比NLPIR数量有所提高。显然,关键词提取的数量增加,每个关键词的代表性就有所减弱。但在后续的分类实验中证明了,使用该分词方案,对比上节的各个分词方案,在模型相同的情况下,会有2%5%的准确率的提升。 关键词抽取可基于以下两种
15、算法,后续实验实践证明基于 TF-IDF 算法的关键词的抽取,在该数据集和我们后续所选择的模型中会得到更好的效果。3.2.1 基于 TF-IDF 算法的关键词抽取import jieba.analysejieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=()sentence 为待提取的文本topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20withWeight 为是否一并返回关键词权重值,默认值为 FalseallowPOS 仅包括指定词性的词,默认值为空,即不筛选jieba.anal
16、yse.TFIDF(idf_path=None) 新建 TFIDF 实例,idf_path 为 IDF 频率文件代码示例 (关键词提取)import syssys.path.append(./)import jiebaimport jieba.analysefrom optparse import OptionParserUSAGE = usage: python extract_tags.py file name -k top kparser = OptionParser(USAGE)parser.add_option(-k, dest=topK)opt, args = parser.par
17、se_args()if len(args) val temp = line.split(t) if (temp.length = 5) temp(4) else val diffTest = Testdata.map line = val temp = line.split(t) if (temp.length = 5) temp(1) else val diffAll = diffTrain.union(diffTest).flatMap(_.split(,).map(_, 1).reduceByKey(_ + _).collect.filter(line = line._1 != & li
18、ne._2 14).map(line = line._1)val cvm = new CountVectorizerModel(diffAll).setInputCol(tokenizer.getOutCol).setOutputCol(features) 4.3 StopWordsRemover在上一章中,我们提到了分词时,根据分词结果所带的词性,对其进行去停用词。而后,我们发现使用”结巴”分词进行TF-IDF算法对用户搜索词列进行1000个关键词的提取对于后续的分类模型效果会更好。但是,我们在“结巴”关键词提取的结果却发现了类似于“什么”“即使”等不具有代表性的词语。于是我们1119个停用
19、词,使用Spark的StopWordsRemover,对分词结果进行去停用词:val Stopdata = sc.textFile(hdfs:/cdh01:8020/user/data/sogou2/stop,128).collect()val remover = new StopWordsRemover().setInputCol(words).setOutputCol(filtered).setStopWords(Stopdata)4.4 权值规范化设想两个不同的用户A和用户B,用户A的搜索词列中只有1句查询语句,分词后得到了3个词语W和总共10个词。而用户B的搜索词列中有10句查询语句,
20、分词后得到了10个词语W和总共100个词。很显然,B中W的TF远高于A中的W的TF,但我们知道词语W在A中比在B中更具有代表性。 为了解决上述问题,我们使用了最大-最小规范化:将所有特征向量线性变换到用户指定最大-最小值之间。但注意在计算时还是一个一个特征向量分开计算的。通常将最大,最小值设置为1和0,这样就归一化到0,1。Spark中可以对min和max进行设置,默认就是0,1。 这里写图片描述在后续,当我们对特征矩阵进行聚类后,得到的特征值可能为负值,可是很多分类器模型需要特征值为非负值。使用以上方法也可以解决这个问题。4.5 同义词替换设想当一个用户的搜索词列的分词结果中出现了一些意思相
21、近的词语,如“恋爱”与“爱情”、“菠萝”与“凤梨”。而我们的模型将其辨别为不同的特征属性,这无疑大量的增加了特征向量的维度和平分了同一意思的词语具有的代表性。 为了解决上述问题,我们搜集了近4万条同义词词典,将意思相近的词语由1个词语来替换掉。该优化帮助原本的特征向量减少了3万以上的维度,降低了后续训练模型时所需的内存,而且凝聚了属性的代表性,增加了预测的准确度: val sqlContext = new org.apache.spark.sql.SQLContext(sc) import sqlContext.implicits._ val train = sc.textFile(hdfs:
22、/cdh01:8020/user/data/sogou2/JBtrain, 400) val test = sc.textFile(hdfs:/cdh01:8020/user/data/sogou2/JBtest, 400) val same = sc.textFile(hdfs:/cdh01:8020/user/data/sogou2/same, 400) same.filter x = !x.contains(=) .count() val sameWord = same.map line = val valuekey = line.split(=) (valuekey(1), valuekey(0) .collect() val broadcastVar = sc.broadcast(sameWord) val diffTrain = train.map line = val broad = bro
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1