基于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名称countsystem
alipays13370011ios
alipayshare13369783ios
天气12284068android
微信11062865android
QQ10659983android
Pico TTS10636702android
手机淘宝10627003android
支付宝10596229android
网络位置10516984android
指南针10187484android
相册9516585android
tenvideo9307299ios
腾讯视频9204797android
爱奇艺9039991android
抖音短视频8957105android
云服务8838426android
.........

二、模型更新

为了避免国民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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部