基于K-均值的app列表聚类分析优化
目录
一、过滤词表筛选
二、模型更新
三、app类型处理
1. 统计app类型占比
2. 新增app类型特征
在基于K-均值的app列表聚类分析中,初步完成用户app列表特征聚类。我们在评估中发现以下几个问题:
- 某些同类用户app列表出现大量相同的国民app(如支付宝、微信、QQ、腾讯视频等)和系统app(如日志和备份、相机等);
- 部分app属性对应有app类别,这部分信息没有利用起来;
针对以上问题,主要做了一下优化:
- 统计app名称词表,挑选top N作为过滤词表;
- 统计具有app类别占比,如果占比较高(60%以上),则将app名称和app类别均提取为稀疏向量,作为K-均值模型特征,否则还是以app名称作为输入特征;
一、过滤词表筛选
hive(odps/spark) sql统计app名称词表
SELECT t2.app_name,t2.cnt,t2.updated_client
FROM (SELECT app_name,COUNT(1) cnt,t1.updated_clientFROM (SELECT app_list_json,updated_clientFROM user_app_list_all_parsedWHERE dt = '${dt}') t1LATERAL VIEW EXPLODE(SPLIT(t1.app_list_json, ';')) appTable AS app_nameGROUP BY app_name,t1.updated_client) t2
ORDER BY t2.cnt DESC
LIMIT 100
;
筛选出app词表如下
| app名称 | count | system |
| alipays | 13370011 | ios |
| alipayshare | 13369783 | ios |
| 天气 | 12284068 | android |
| 微信 | 11062865 | android |
| 10659983 | android | |
| Pico TTS | 10636702 | android |
| 手机淘宝 | 10627003 | android |
| 支付宝 | 10596229 | android |
| 网络位置 | 10516984 | android |
| 指南针 | 10187484 | android |
| 相册 | 9516585 | android |
| tenvideo | 9307299 | ios |
| 腾讯视频 | 9204797 | android |
| 爱奇艺 | 9039991 | android |
| 抖音短视频 | 8957105 | android |
| 云服务 | 8838426 | android |
| ... | ... | ... |
二、模型更新
为了避免国民app和系统app导致用户趋于大同,需要对样本进行过滤处理,如下
import spark.implicits._// 加载textFileval df = spark.read.textFile(Constants.SAMPLE).map(row=>{val rows = row.split(",")AppList(rows(0).toLong,rows(1).split(";").filter(!Constants.APP_FILTER_VOCABULARY.split(",").contains(_)))}).toDF("uid","app_list").repartition(numPartitions)
其他过程保持不变。
重新迭代模型,得到ssd随k均值变化趋势,如下

采用手肘法,选取最佳k=26。
三、app类型处理
1. 统计app类型占比
同样采用hive(odps/spark) sql统计app类型占比
SELECT COUNT(1) cnt,COUNT(DISTINCT t3.app_name) cdnt
FROM (SELECT t1.app_name,t2.app_name app_name1,t1.app_categoryFROM (SELECT *FROM dw_user_app_list_androidWHERE dt = '${dt}') t1LEFT OUTER JOIN (SELECT *FROM app_vocabularyWHERE dt = '${dt}'AND updated_client = 3) t2ON t1.app_name = t2.app_name) t3
WHERE t3.app_name1 IS NOT NULL;
发现,具有app类型占比仅有1/6,大量数据缺失,不太适合作为聚类特征。
2. 新增app类型特征
假如具有app类型占比在60%以上,可以新增app类型特征处理。如下
// app_list和app_category_list列转化为稀疏特征向量val vectorizerWords = Array("app_list","app_category_list")var flag = falseval cvm = if(!fs.exists(new Path(Constants.COUNTVECTOR))){flag = trueval vectorizers = vectorizerWords.map(col=>{new CountVectorizer().setInputCol(col).setOutputCol(col + "_cv").setMinDF(1).fit(df)})val cvms = new Pipeline().setStages(vectorizers)cvms.fit(df)}else{CountVectorizerModel.load(Constants.COUNTVECTOR)}if(flag){cvm.write.overwrite().save(Constants.COUNTVECTOR)}val result = cvm.transform(df).select("uid","app_list_cv","app_category_cv")result.cache()println("countVectorizer处理后分区数量:" + result.rdd.getNumPartitions)result.show(10,false)// result在Kmeans迭代寻优多次用到,因此加载内存val map = new util.HashMap[Int,Double]()// k-means聚类val ks = Range(minSeq, maxSeq)var minSsd = 0.0ks.foreach(cluster => {val ks = vectorizerWords.map(col=>{new KMeans().setK(cluster).setMaxIter(maxIter).setFeaturesCol(col).setPredictionCol(col + "_cv")})val kmeans = new Pipeline().setStages(ks)val kmm = kmeans.fit(result)
参考资料
https://blog.csdn.net/baymax_007/article/details/87986743
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
