机器学习技术(九)——支持向量机算法实操(基于SVM的模型对潜在运营商客户进行分类)

news2025/1/13 13:31:24

机器学习技术(九)——支持向量机算法实操

在这里插入图片描述

文章目录

  • 机器学习技术(九)——支持向量机算法实操
    • 一、引言
    • 二、数据集介绍
    • 三、导入相关依赖库
    • 四、读取数据
    • 五、数据可视化分析
      • 1、是否为潜在客户与不同用户主叫时长对比
      • 2、是否为潜在合约客户与被叫时长对比
      • 3、是否为潜在合约用户与业务类型对比
      • 4、是否为潜在合约用户与主叫时长以及免费流量使用情况对比
    • 六、数据预处理
      • 1、划分数据
      • 步骤2 类别特征编码
      • 3、数据归一化
    • 七、 训练SVM模型
      • 1、训练简单模型:SVM
      • 2、训练核函数=rbf的SVM算法:调参
      • 3、使用最优超参再次进行训练
    • 八、模型评估
    • 九、总结

一、引言

本文主要包含基于python的SVM的代码实现及调用。基于SVM的模型探索该运营商用户业务类型以及每月使用数据来区分是否为给运营商潜在合约用户。

在这里插入图片描述

二、数据集介绍

数据样本为10000名用户的手机业务使用信息,其中包含每个样本的ID,业务类型,主叫时长,被叫时长,免费流量,几万消费,月均上网时长,入网时长,最近一次消费金额,总缴费金额,缴费次数,余额以及是否为潜在合约客户共13个特征。其中我们选择的自变量为除用户ID以外的11个特征。应变量为是否为潜在合约用户,并以0表示不是潜在合约客户,1表示是潜在合约客户。

数据集:https://download.csdn.net/download/tianhai12/88275733

以下为原始数据的字段信息,后续将会以说明作为特征名。

名称说明类型备注
user_id用户标识int
service_kind业务类型string2G\3G\4G
call_duration主叫时长(分)
called_duration被叫时长(分)
in_package_flux免费流量
out_package_flux计费流量
月均上网时长(分)
net_duration入网时长(天)long
last_recharge_value最近一次缴费金额(元)
total_recharge_value总缴费金额(元)
total_recharge_count缴费次数
contractuser_flag是否潜在合约用户
silent_serv_flag是否三无用户int0:否, 1:是, 三无:无月租费,无最低消费,无来电显示
pay_type付费类型int0:预付费, 1:后付费

三、导入相关依赖库

将所需与处理数据,所需模型以及可视化依赖包导入。

#导入基础数据处理以及数据可视化依赖包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn import datasets
#导入构建模型所需包
from sklearn import svm,metrics
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV
from sklearn.preprocessing import OneHotEncoder

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

四、读取数据

将10000名用户数据导入,并将其中年龄和估计工资数据命名为x,将是否购买该产品设置为y。

输入:

data= pd.read_csv('./ml/data_carrier_svm.csv',encoding ='utf8')
#查看前五行数据集
data.head()

前五位用户结果显示如下,每位用户共有13组特征,其中我们主要关注除用户标识外其他特征。
在这里插入图片描述

五、数据可视化分析

1、是否为潜在客户与不同用户主叫时长对比

#不同用户的主叫时长分布情况对比
cond = data['是否潜在合约用户']==1
data[cond]['主叫时长(分)'].hist(alpha =0.5,label='potential_contract_user(潜在合约用户)')
data[~cond]['主叫时长(分)'].hist(color='y',alpha = 0.5,label='no_potential_contract_user(非潜在合约用户)')
plt.legend()

输出:
在这里插入图片描述

由图可得在主叫时长超过80分钟的用户中目前在合约用户明显要多于费钱在合约用户,且主叫时长在100分钟至120分钟的潜在用户人数最多。

2、是否为潜在合约客户与被叫时长对比

#不同用户的被叫时长分布情况对比
cond = data['是否潜在合约用户']==1
data[cond]['被叫时长(分)'].hist(alpha =0.5,label='潜在合约用户')
data[~cond]['被叫时长(分)'].hist(color='y',alpha = 0.5,label='非潜在合约用户')
plt.legend()

输出结果如下所示,潜在客户和非潜在客户人数都在被叫时长为100分钟左右到达峰值,随后慢慢下降。
在这里插入图片描述

3、是否为潜在合约用户与业务类型对比

探索是否为潜在合约用户与业务类型之间关系。

#不同用户的业务类型情况对比
grouped =data.groupby(['是否潜在合约用户','业务类型'])['用户标识'].count().unstack()
grouped.plot(kind= 'bar',alpha =1.0,rot = 0)

输出结果如下所示,可以看出潜在合约客户并没有使用2G业务的,而使用3G,4G业务人数相差不多。反观非潜在用户,使用2G,3G,4G业务用户人数差不多。
在这里插入图片描述

#统计两类用户具体人数。
data['是否潜在合约用户'].value_counts()

得到

1    5003
0    4997
Name: 是否潜在合约用户, dtype: int64

4、是否为潜在合约用户与主叫时长以及免费流量使用情况对比

将是否为潜在合约用户与主叫时长以及免费流量使用情况分布情况进行数据可视化。

输入:

#生成数据可视化
y = data.loc[:,'是否潜在合约用户']
plt.scatter(data.loc[:,'主叫时长(分)'],data.loc[:,'免费流量'],c=y,alpha=0.5)

结果如下,其中X轴表示主叫时长(分),Y轴表示免费流量,黄点代表潜在合约客户,紫点表示非潜在合约客户,由图可得,两者虽然区分较为明显,但有少量区域重合。
在这里插入图片描述

六、数据预处理

1、划分数据

首先将自变量(除用户标识外11个特征)与应变量(是否为潜在合约客户)划分并定义。

#分割特征数据集和便签数据集
X = data.loc[:,'业务类型':'余额']
y= data.loc[:,'是否潜在合约用户']
print('The shape of X is {0}'.format(X.shape))
print('The shape of y is {0}'.format(y.shape))

输出结果为X,Y结构如下。

The shape of X is (10000, 11)
The shape of y is (10000,)

步骤2 类别特征编码

因为业务类别三类为字符形式,为后续数据分析及建模,将其用One-hot编码。

# 使用One-hot编码
service_df = pd.get_dummies(X['业务类型'])
X_enc = pd.concat([X,service_df],axis = 1).drop('业务类型',axis=1)
X_enc.head()

在这里插入图片描述

3、数据归一化

因各个特征维度相差较大,训练之前先进行归一化处理

#导入方法
from sklearn.preprocessing import normalize
X_normalized = normalize(X_enc)

#分割训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X_normalized,y,test_size = 0.2, random_state=112)
print('The shape of X_train is {0}'.format(X_train.shape))
print('The shape of X_test is {0}'.format(X_test.shape))

训练集与测试集比例为4:1.

输出:

The shape of X_train is (8000, 13)
The shape of X_test is (2000, 13)

将归一化后训练集数据进行可视化。

#生成数据可视化
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)

经过归一化后,数据更加收敛。
在这里插入图片描述

七、 训练SVM模型

1、训练简单模型:SVM

#模型实例化
linear_clf = svm.LinearSVC()
#在训练集上训练模型
linear_clf.fit(X_train,y_train)

#在测试集上预测
y_pred = linear_clf.predict(X_test)

#计算准备;率
score = metrics.accuracy_score(y_test,y_pred)
print('The accuracy score of the model is: {0}'.format(score))

#查看混淆举证
metrics.confusion_matrix(y_test,y_pred)

输出结果为测试集混淆矩阵以及模型预测准确率。由结果可知,测试集中2000样本预测对了1728个,模型预测准确率为0.864.

The accuracy score of the model is: 0.864
array([[935, 103],
       [169, 793]], dtype=int64)

2、训练核函数=rbf的SVM算法:调参

训练参数得到最优解。

# 设置调试参数的范围
C_range = np.logspace(-5,5,5)
gamma_range = np.logspace(-9,2,10)

clf = svm.SVC(kernel='rbf',cache_size=1000,random_state=117)
param_grid = {'C':C_range,
             'gamma':gamma_range}

# GridSearch作用在训练集上
grid = GridSearchCV(clf,param_grid=param_grid,scoring= 'accuracy',n_jobs=2,cv =5)
grid.fit(X_train,y_train)

通过交叉检验寻找最优参数,其中参数解释如下,这里给出的定义仅供参考,具体看你电脑上包的版本。

#estimator:所使用的分类器,或者pipeline
  #param_grid:值为字典或者列表,即需要最优化的参数的取值
  #scoring:准确度评价标准,默认None,这时需要使用score函数;或者如scoring='roc_auc',根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。
  #n_jobs:并行数,int:个数,-1:跟CPU核数一致, 1:默认值。
  #pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次
  #iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。
  #cv:交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。
  #refit:默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。
  #verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
Attributes:
  #best_estimator_:效果最好的分类器
  #best_score_:成员提供优化过程期间观察到的最好的评分
  #best_params_:描述了已取得最佳结果的参数的组合
  #best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)。
#Methods:
  #decision_function:使用找到的参数最好的分类器调用decision_function。
  #fit(X, y=None, groups=None, **fit_params):训练
  #get_params(deep=True):获取这个估计器的参数。
  #predict(X):用找到的最佳参数调用预估器。(直接预测每个样本属于哪一个类别)
  #predict_log_proda(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分取log情况)
  #predict_proba(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分情况)
  #score(X, y=None):返回给定数据上的得分,如果预估器已经选出最优的分类器。
  #transform(X):调用最优分类器进行对X的转换。

注意:会跑一段时间,看电脑配置
在这里插入图片描述

GridSearchCV(cv=5, estimator=SVC(cache_size=1000, random_state=117), n_jobs=2,
             param_grid={'C': array([1.00000000e-05, 3.16227766e-03, 1.00000000e+00, 3.16227766e+02,
       1.00000000e+05]),
                         'gamma': array([1.00000000e-09, 1.66810054e-08, 2.78255940e-07, 4.64158883e-06,
       7.74263683e-05, 1.29154967e-03, 2.15443469e-02, 3.59381366e-01,
       5.99484250e+00, 1.00000000e+02])},
             scoring='accuracy')

输出最优参数得到最优模型。

# 获得最佳model
print(grid.best_score_)
print(grid.best_params_)
print(grid.best_estimator_)

有输出结果可知,最优c=100000,gamma=5.994842503189421

输出:

0.966625
{'C': 100000.0, 'gamma': 5.994842503189421}
SVC(C=100000.0, cache_size=1000, gamma=5.994842503189421, random_state=117)

3、使用最优超参再次进行训练

有上述训练所得参数构建模型,并在训练数据上训练以及测试数据集上进行测试。

也需要跑一会儿

# 建立最好参数示例
clf_best = svm.SVC(kernel="rbf",C=grid.best_params_['C'],
                   gamma = grid.best_params_['gamma'],probability=True)

# 使用训练数据训练
clf_best.fit(X_train,y_train)

# 使用测试数据测试
y2_pred = clf_best.predict(X_test)

看一下测试数据结构

y2_pred
array([0, 1, 0, ..., 1, 1, 1], dtype=int64)

八、模型评估

# 计算测试集准确率
accuracy = metrics.accuracy_score(y_test,y2_pred)
print("The accuracy is %f"%accuracy)

# 显示混淆矩阵
metrics.confusion_matrix(y_test,y2_pred)

输出结果为混淆矩阵以及准确率,可以发现准确率为0.968比之前简单模型准确率0.864高很多。

The accuracy is 0.968000
array([[1019,   19],
       [  45,  917]], dtype=int64)

通过上述所得混淆矩阵生成ROC曲线

# 获取类别1的预测概率分布的分数
y2_pred_prob = clf_best.predict_proba(X_test)[:, 1]


# 获取ROC曲线
fpr, tpr, thresholds = metrics.roc_curve(y_test, y2_pred_prob)
plt.plot(fpr, tpr)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.title('ROC curve for diabetes classifier')
plt.xlabel('False Positive Rate (1 - Specificity)')
plt.ylabel('True Positive Rate (Sensitivity)')
plt.grid(True)

ROC曲线越陡,模型表现越好,由下ROC曲线曲线可得模型表现良好。
在这里插入图片描述

九、总结

在这里插入图片描述

通过SVM模型基于10000名用户的每月运营商业务业务使用情况对是否为该运营商潜在客户进行分类以及预测,实验当中对数据进行可视化来体现数据结构,并通过训练集构建经过调参后SVM模型来预测测试集数据,并以ROC图像显示分类效果。与其他实验不一样的地方,此处实验先训练简单模型,并得出预测准确率大约在0.864,再通过调参优化模型将模型预测准确率提升至0.968,表现良好!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1016801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

绘图(一)弹球小游戏

AWT编程 语雀 仓库:Java图形化界面: Java图形化界面学习demo与资料 (gitee.com) 很多程序如各种小游戏都需要在窗口中绘制各种图形,除此之外,即使在开发JavaEE项目时, 有 时候也必须"动态"地向客户 端生成各种图形、…

C语言进阶指针(3) ——qsort的实现

大家好&#xff0c;我们今天来学习回调函数qsort的实现。 首先让我们打开cplusplus.com找到qsort函数。 我们看到这个函数就可以看到它的头文件和参数信息。 #include<stdlib.h> void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const voi…

前后端跨域请求问题解决方法

如图&#xff1a; 1.在config配置包中创建一个CorsConfig配置类 2.将下面代码复制到这个类中即可 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfigurati…

[字符串和内存函数]strcmp和strncmp以及memcmp的区别

CPlus中对strcmp的介绍 #include <stdio.h> #include <string.h>int main () {char key[] "apple";char buffer[80];do {printf ("Guess my favorite fruit? ");fflush (stdout);scanf ("%79s",buffer);} while (strcmp (key,buf…

MySQL 约束与复杂查询

当涉及到数据库管理系统&#xff08;DBMS&#xff09;的高级主题时&#xff0c;包括数据库的约束、表的设计以及各种类型的查询&#xff0c;特别是聚合查询、联合查询和合并查询&#xff0c;是非常重要的。这些主题可以帮助我们更好地理解数据库的内部工作机制以及如何有效地操…

[maven] 创建 spring boot 项目及使用 Jenkins 运行 maven

[maven] 创建 spring boot 项目及使用 Jenkins 运行 maven 本篇笔记走一下用 maven 创建 spring boot 项目和利用 Jenkins 管理 maven 流程 使用 maven 创建 spring boot 项目 根据官方文档说&#xff0c;现在使用 boot 需要 java 17&#xff0c;Gradle 7.5/Maven 3.5 spri…

idea无法通过vpn 连接到数据库或者kafka

本地navicate 等sql客户端 &#xff0c;通过vpn&#xff0c;可以连接到数据库&#xff0c;&#xff0c;xshell也可以通过vpn连接到远程机器&#xff0c;但是&#xff0c;idea开发时&#xff0c;报连接超时错误&#xff0c;解决方法&#xff1a; 项目中 VM这一栏加上-Djava.net…

区块链:去中心化革命下的创新与发展!

区块链作为一项重要的技术实验&#xff0c;确实具有重大的影响力。它代表了一场去中心化的运动&#xff0c;吸引了许多研究人员、工程师、建设者和用户的参与&#xff0c;创造了我们目前所见到的一些最有趣的技术。 区块链的透明特性赋予了用户对于数据和交易的控制权&#xff…

来看看Python __all__变量的用法

​ 事实上&#xff0c;当我们向文件导入某个模块时&#xff0c;导入的是该模块中那些名称不以下划线&#xff08;单下划线“_”或者双下划线“__”&#xff09;开头的变量、函数和类。因此&#xff0c;如果我们不想模块文件中的某个成员被引入到其它文件中使用&#xff0c;可以…

展示日志log4.properties

log4.properties 1.log4.properties 此时文件主要用于展示日志的输出的级别的信息。 # Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategoryINFO, CONSOLE debug info warn error fatal log4j.rootCategoryinfo, CONSO…

本地事务与分布式事务

目录 一、本地事务 1、事务的基本性质 2、事务的隔离级别 3、事务的传播行为 4、SpringBoot 事务关键点 二、分布式事务 1、为什么有分布式事务 2、CAP 定理与 BASE 理论 3、分布式事务几种方案 一、本地事务 1、事务的基本性质 数据库事务的几个特性&#xff1a;原…

PhpStorm 2023年下载、安装教程和好用插件,保姆级教程

PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程 文章目录 PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程前言一、安装PhpStorm二、好用的插件简体中文包Chinese(Simplified)Language Pack 三、卸载插件CTRLN 查找类CTRLSHIFTN 全局搜索文件…

Scala编程语言

Scala编程语言 一、Scala引入1、学习Scala的目的2、Scala的基本概念 二、Scala环境搭建1、安装步骤2、配置环境变量3、测试Scala4、Scala与idea的集成5、关联源码6、 class 和 object 说明 三、常用语法、变量和数据类型1、 注释2、变量和常量3 、标识符的命名规范4、字符串输出…

一阶低通滤波器滞后补偿算法

一阶低通滤波器的推导过程和双线性变换算法请查看下面文章链接: PLC算法系列之数字低通滤波器(离散化方法:双线性变换)_双线性离散化_RXXW_Dor的博客-CSDN博客PLC信号处理系列之一阶低通(RC)滤波器算法_RXXW_Dor的博客-CSDN博客_rc滤波电路的优缺点1、先看看RC滤波的优缺点…

matlab EL image绘制

利用光谱仪测试的结果可以得到image&#xff0c;输出为csv文件&#xff0c;包括640X512的矩阵&#xff0c;这个矩阵将会反映器件发光的位置和强度&#xff0c;算是一个灰度图。 在matlab中&#xff0c;可以用imagesc函数来进行绘图。 imagesc函数的用法 clear; clc; close a…

Linux从root账号切换到普通账号并执行shell脚本

背景&#xff1a;最近自己在用的中间件只能运行在 普通账号下&#xff0c;现在每次重启之后都要切换到 普通账号 然后去执行启动脚本。一次两次还能接受……反正现在接受不了了…… 写一个脚本让它帮我起吧 先贴目录 新建文件 start_es.sh, 用于root账号下调用 #!/bin/bash e…

计算机组成原理——基础入门总结(一)

本帖更新一些关于计算机组成原理的重点内容。由于博主考研时并不会考这门课&#xff0c;但是考虑到操作系统中又很多重要晦涩的概念涉及很多诸如内存、存储器、磁盘、cpu乃至各种寄存器的知识&#xff0c;此处挑选一些核心的内容总结复盘一遍——实现声明&#xff1a;本帖的内容…

【CCF】第30次csp认证——202305-1重复局面

202305-1重复局面&#xff1a; 问题描述 国际象棋每一个局面可以用大小为 88 的字符数组来表示&#xff0c;其中每一位对应棋盘上的一个格子。六种棋子王、后、车、象、马、兵分别用字母 k、q、r、b、n、p 表示&#xff0c;其中大写字母对应白方、小写字母对应黑方。棋盘上无…

[ESP32 IDF+Vscode]蓝牙配网后采用上传温湿度数据至阿里云(MQTT协议)

阿里云平台的设置 参考文章&#xff1a; http://t.csdn.cn/RzLGqhttp://t.csdn.cn/RzLGq Blufi配网 1.简介 BluFi 是一款基于蓝牙通道的 Wi-Fi 网络配置功能&#xff0c;适用于 ESP32。它通过安全协议将 Wi-Fi 配置和证书传输到 ESP32&#xff0c;然后 ESP32 可基于这些信…

OpenGL超级宝典(第五版)疑难点汇总解析

《OpenGL超级宝典(第五版&#xff09;》如下&#xff1a; 1. 在该书的第1章的Block例子中用到了平面阴影投射矩阵&#xff0c;关于该矩阵的推导&#xff0c;参见&#xff1a; OpenGL: 平面阴影投射矩阵的推导 2. 在该书的第8章的pix_buffs例子中用到了正交投影矩阵的推导过程…