广电用户画像分析之使用SVM预测用户是否挽留
在本篇博客中,将介绍如何使用支持向量机(SVM)模型来预测用户是否挽留。我们将使用Spark的ML库来实现这一目标,并通过构建和训练SVM模型,以及对测试集进行预测和评估,来解决这个分类问题。
建议先查看之前的系列博客:
广电用户画像分析之根据用户行为数据进行筛选与标签添加
筛选数据
首先我们将介绍如何根据用户的收视行为数据中的地区和语言偏好,筛选数据并为支持向量机(SVM)模型训练做准备。我们将通过对用户消费数据、用户信息数据和媒体指数数据的处理和特征提取,构建一个用于分类模型训练的数据集。这个数据集将用于训练SVM模型,以对用户进行分类和预测,例如判断用户是否属于正常用户类别。核心目的是通过数据处理和特征构建,为后续的分类模型训练提供数据基础。
首先,我们需要创建一个SparkSession对象,并设置应用程序的名称为"MediaAnalyse"。接着,将SparkContext的日志级别设置为"WARN",以减少日志输出。
接下来,导入所需的依赖库,包括Spark SQL的函数库和窗口函数。
然后,我们从表"processData.mmconsume_billevents"和"processData.mediamatch_usermsg"中加载相应的数据。这些数据包括用户的消费数据和用户信息数据。
接着,我们进行数据处理和特征提取。首先,计算每个用户近三个月的月均消费,将结果保存到"monthUseCost"表中。其次,计算每个用户的电视入网时长,并将结果保存到"usermsg"表中。最后,计算每个用户的电视依赖度,并将结果保存到"TVNeed"表中。
在数据处理和特征提取完成后,我们需要构建标签列。根据一系列条件筛选出活跃用户,并将其与高电视依赖度的用户进行交集操作,为结果添加一个标签列。
接下来,我们将前面处理得到的数据表进行关联操作,将各个特征列和标签列整合到一张数据表中,并将结果保存到"ProcessData.modelData"表中。这样,我们就为后续的模型训练准备好了数据。
需要注意的是,上述代码中并没有直接进行模型训练,而是为后续的模型训练步骤提供了准备工作,包括数据的准备和特征构建。
完整代码:
package code.SVMModle
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.expressions.Window
object SVMProcess {
def main(args: Array[String]): Unit = {
System.setProperty("HADOOP_USER_NAME", "root")
val spark = SparkSession.builder().appName("MediaAnalyse")
.master("local[*]")
.enableHiveSupport()
.getOrCreate()
//
spark.sparkContext.setLogLevel("WARN")
import org.apache.spark.sql.functions._
val billevent = spark.table("processData.mmconsume_billevents").filter("year_month>'2018-04-01'")
// 用户近三个月的月均消费
val monthUseCost = billevent.groupBy("phone_no").agg(sum("should_pay")/3 as "avgPay")
//用户的入网时长
val usermsg = spark.table("processData.mediamatch_usermsg").select(col("phone_no"),col("run_time"),
row_number().over(Window.partitionBy("phone_no").orderBy("run_time")) as "rn")
.filter("rn = 1").select(col("phone_no"),col("run_time"))
.withColumn("tvNetTime",months_between(from_unixtime(unix_timestamp(),"yyyy-MM-dd HH:mm:ss"),col("run_time"))/12)
// 电视依赖度
val TVNeed = spark.table("processData.media_index").filter("sm_name != '珠江宽频'").filter("end_time > '2018-04-30'")
.groupBy("phone_no").agg(sum("duration")/1000/60/60/90 as "tvNeed" )
/**
* 构建标签列
*/
val activeUser1 = spark.table("processData.order_index").filter("run_name = '正常'")
.filter("offername not like '%废%' and offername not like '%空包%'" +
"and offername not like '%赠送%' and offername not like '%免费体验%' and offername not like '%提速%'" +
"and offername not like '%提价%' and offername not like '%转网优惠%'" +
"and offername not like '%测试%' and offername not like '%虚拟%'").select("phone_no").distinct()
val everyDay2 = TVNeed.filter("tvNeed>0.5").select("phone_no")
val activeUser = activeUser1.intersect(everyDay2).withColumn("label",lit(1))
// run_name
val labelUdf = udf((x:String)=>label(x))
val runUser = spark.table("processData.mediamatch_usermsg").join(activeUser,Seq("phone_no"),"leftouter")
.withColumn("label",labelUdf(col("run_name"))).select("phone_no","label")
// 数据整合
runUser.join(monthUseCost,"phone_no").join(usermsg,"phone_no").join(TVNeed,"phone_no")
.drop("run_time").write.mode("overwrite").saveAsTable("ProcessData.modelData")
// .show()
// .groupBy("label").count().show()
}
def label(run_name:String): Int ={
if (run_name == "正常"){
1
}else{
0
}
}
}
# 使用数据训练模型并测试评估准确度
本部分介绍了如何使用Spark的ML库来训练模型并评估其准确度,具体是通过实现支持向量机(SVM)分类模型来完成的。下面是主要思路和核心代码的总结:
首先,创建一个SparkSession对象,并设置应用程序名称、运行模式以及对Hive的支持。
然后,使用spark.table
方法加载数据表ProcessData.modelData
,得到一个DataFrame对象。
进行特征工程,使用VectorAssembler
将选定的特征列tvNeed
、tvNetTime
和avgPay
合并成一个名为features
的向量列。
接下来,使用randomSplit
方法将数据集划分为80%的训练集和20%的测试集,返回两个DataFrame对象train
和test
。
创建一个LinearSVC
对象,设置迭代次数、特征列名和标签列名等参数,构建SVM模型。
使用训练集数据调用fit
方法来拟合SVM模型,得到一个训练好的模型对象model
。
使用训练好的模型对测试集数据进行预测,将预测结果保存在一个新的DataFrame对象predictions
中。
使用MulticlassClassificationEvaluator
计算模型的准确度。
最后,输出模型的准确度。
通过合理的特征工程和模型训练,我们可以得到一个准确度较高的SVM分类模型,用于解决分类问题。在实际应用中,准确度的评估可以帮助我们了解模型的性能,并做出相应的优化和改进。
完整代码
package code.SVMModle
import org.apache.spark.ml.classification.LinearSVC
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.sql.SparkSession
object SvmModel {
def main(args: Array[String]): Unit = {
System.setProperty("HADOOP_USER_NAME", "root")
val spark = SparkSession.builder().appName("MediaAnalyse")
.master("local[*]")
.enableHiveSupport()
.getOrCreate()
//
spark.sparkContext.setLogLevel("WARN")
import org.apache.spark.sql.functions._
val data = spark.table("ProcessData.modelData")
val features = new VectorAssembler().setInputCols(Array("tvNeed","tvNetTime","avgPay"))
.setOutputCol("features").transform(data)
//切分测试集和训练集
val Array(train,test) = features.randomSplit(Array(0.8,0.2))
val svm = new LinearSVC()
.setMaxIter(5)
.setFeaturesCol("features")
.setLabelCol("label")
.setStandardization(true)
val model = svm.fit(train)
val pre = model.transform(test)
//准确度计算
val evaluator = new MulticlassClassificationEvaluator()
.setLabelCol("label")
.setPredictionCol("prediction")
.setMetricName("accuracy")
val accuracy = evaluator.evaluate(pre)
print("模型准确度:"+accuracy)
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)