用python实现支持向量机对婚介数据的用户配对预测

网上有人用libsvm2.89在Python2.6成功。(一定要libsvm2.89搭配python2.6,其他版本都不能成功,我就是浪费了大量时间在这里!)

python 搭建libsvm方法。python版本和libsvm版本匹配很重要!

两步:

1.将libsvm-2.89\windows\python目录下的svmc.pyd文件复制到C:\Python26\DLLs;

2.将libsvm-2.89\python目录下的svm.py放到C:\Python26\Lib目录里。

from svm import * 成功

(附上libsvm2.89的下载地址:http://ishare.iask.sina.com.cn/f/6344231.html)

from svm import *
prob  = svm_problem([1,-1] ,[[1,0,1] , [-1,0,-1]] ) 
param = svm_parameter(kernel_type = LINEAR , C = 10)

## training the model

m = svm_model(prob ,param)
 
#testing the model

m.predict( [1, 1 , 1] )

本案例分类前具备的数据集:

(训练集):agesonly.csv和matchmaker.csv。

agesonly.csv 格式是: 男年龄,女年龄,是否匹配成功

matchmaker.csv数据格式是: 年龄,是否抽烟,想要孩子,兴趣列表,地址 , 年龄,是否抽烟,想要孩子,兴趣列表,地址 , 是否匹配成功。

数据每一行是两个人的个人信息和最终是否匹配。

46,no,yes,skiing:reading:knitting:writing:shopping,154 7th Ave New York NY,19,no,no,dancing:opera:travel,1560 Broadway New York NY,0

36,yes,yes,skiing:knitting:camping:writing:cooking,151 W 34th St New York NY,29,no,yes,art:movies:cooking:scrabble,966 3rd Ave New York NY,1

27,no,no,snowboarding:knitting:fashion:camping:cooking,27 3rd Ave New York NY,19,yes,yes,football:computers:writing,14 E 47th St New York NY,0

我们要做的分类是:给出任何两个人是否匹配成功 0 或1 的结果

分类步骤:

一、加载数据,将excel形式数据 加载成 行格式

二、用matplotlib 图示化 刚刚加载的数据

三、 实现一个线性分类器:并预测

四、将两个婚介数据集 全部转换成数值数据

五、 对数据进行缩放处理

六、非线性分类,引入核函数

七、把svm应用到婚介数据集中

下面具体细说步骤:

一、加载数据,将exceld形式数据 加载成 数据结构 行格式

    将婚介数据每一行都定义成一个类,类具备profiledata 和 ismatch 两个属性:profiledata表示人物信息,ismatch表示两个人是否匹配成成功。

以后处理上面两个数据集ageonly.csv和matchmaker.csv 或新来的预测行,都说先转成行,行再转成类格式。

二、图示化刚刚加载的数据

将第一步从excel转换而来的行数据,进行可视化 ,以图显示出数据。显示出男女媒介匹配情况。

用到matplotlib第三方库,可对某些变量可视化。
最后返回一张图。
matplotlib(是取代matlab的工具)安装步骤如下:
先装numpy,再装matplotlab.
去官方网站下载matplotlab与python相对的exe,点击运行即可。一步搞掂 

将agesonly.csv图示化:

三、 在用svm分类器之前,先实现一个线性分类器:并用这个线性分类器 预测 试验

完成一个线性分类器:
工作原理:  (关键词: 每个类的均值点 )
寻找每个分类中所有数据的平均值,并构造一个代表该分类中心位置的点。(凡是有涉及到代表点的,一定是要用字典,字典的key表示类别,value表示均值点。 分类一定要经常用字典),然后判断距离哪个中心点位置最近 来对新的坐标点进行分类.(用点积距离作比较距离)
问题:
1.这个线性分类器用哪个数据集呢? 
     答:用agesonly. 因为matchmaker.csv 很多属性还没量化。agesonly是纯数值数据,所以先用它作试验
2.怎样构造每个类的代表点呢?
  答:代表点即是均值点。凡是有涉及到代表点的,一定是要用字典,字典的key表示类别,value表示均值点。 分类一定要经常用字典
步骤(1):得到agesonly数据集所有坐标的分类(一个坐标就是数据集一行) 
    (2):计算每个分类包含的坐标总个数
  (3):计算坐标总和除以坐标个数 即等于 均值点
3.如何判断新的坐标 与均值点的距离(见dpclassify函数)
  用向量点积作为距离衡量。而不用欧式距离或pearson距离。  
4.  向量点积怎么做衡量的?? 

实现代码时,注意“=”赋值符号是否要用切片[:]!!!

运行结果是:

  线性分类训练,得到各分类对应的均值点是:(字典key表示是否匹配分类,value表示各类对应的均值):
  
{0: [26.914529914529915, 35.888888888888886], 1: [35.480417754569189, 33.015665796344649]}

输入如下新的预测点,根据点积结果,来预测分类结果:

1
0
1

四、将两个婚介数据集 全部转换成数值数据

matchmaker.csv数据文本包含了数值数据和分类数据,应该全部数值量化它

补充:决策树可以处理数值数据和分类数据(yes,no)。但其他分类器只能处理数值型分类器。所以其他分类器如svm,一定要将数据转成数值类型!!!

  分类数据举例:
 1.如”是否“问题这类数据,转换成数值类型 见yesnodata函数
  2.将兴趣字符数据转换成数值类型interestmatchcount 函数:传入参数是两个人的兴趣列表,返回的是相同兴趣个数。
    在数据集里记录人们的兴趣爱好,最简单方法是将每一种可能的兴趣爱好都视单独的数值变量,如果人们具备某一项兴趣,则设为1,否则为0.
    假设对一个人一个人单独处理,这样做最合理。
    但在媒介数据集中,要处理的是一对一对的人,
    所以更直观方法是将具备共同兴趣爱好的数据视为变量 

 3. 计算两个人的地址距离,用yahoo map的API来计算 两个人居住地址距离(计算居住地址的经度和纬度)

五、 对数据进行缩放处理

把所有数据缩放到一个尺度,从而使每个变量上的差值具有可比性。
通过确定每个变量的最大最小值,对数据进行缩放,使最小值为0,最大值为1。缩放具体方法: 

先找出所有变量各自对应的最小值,并从该变量所有数值中减去这个最小值,从而将值域范围
调到0起点,函数随后将调整后的结果除以最大最小值之差,从而将所有数据转换成0到1之间的值。
 对对matchmaker.cscv文件数值数据集缩放处理之后的均值点是:
{0: [0.44512959866220736, 0.1705685618729097, 0.0, 0.0, 0.0, 0.0, 0.0], 1: [0.5475746268656716, 0.17910447761194029, 0.0, 0.0, 0.0, 0.0, 0.0]}
 
没缩放之前的数值数据第一行数据是:
[39.0, 1, -1, 43.0, -1, 1, 0]
 
缩放之后的数值数据第一行数据:
[0.65625, 1.0, 0.0, 0.78125, 0.0, 1.0, 0.0]

 dpclassify点积函数传入参数:newpoint表示将要分类的点的坐标(x,y),avgs表示当前所有分类的均值点1

六、进入非线性分类,引入核函数

  从此步开始 ,才开始处理matchmaker.csv转换后的数值数据集,将个人profiledata信息进行预测了
 核函数的思想同样也是利用点积运算,它用一个新的函数来取代原来的点积函数,当借助某个映射函数,将数据 第一次 变换到更高纬度的坐标空间时,新函数将返回高纬度坐标内的点积结果。

  这里写径向基函数Radial-basis function:   rbf函数与点积类似,它接受两个向量作为输入参数和一个gamma参数,返回一个标量值。  (调整gamma参数可得到一个针对给定数据集的最佳线性分离)
 
   与点积不同的是,rbf函数式非线性的,所以它能将数据映射到更复杂的空间。
  因为线性分类器要求我们需要一个新的函数求坐标变换后的空间与均值点的距离
  但无法直接这样计算,前人发现规律: 先对一组向量 求均值,再计算 均值与向量A 的点积结果 ,与先对向量A  与 该组向量中的每个向量 求点积 ,再计算均值,效果是等效的。
 
  所以不需对尝试分类的两个坐标点求点积来计算某个分类的均值点,而是计算某个坐标点与分类中其他每个坐标点之间的点积或径向基函数的结果,再对他们求均值。见nonlinearclassify函数。

核函数预测结果是:

调用matchmaker.csv训练数据集,使用其缩放处理过后的数值数据集scaledset:

建立新预测数据:男士不想要小孩,女士想要:预测分类是:
0
建立新预测数据:男士想要小孩,女士想要:预测分类是:1

七、把svm应用到婚介数据集中

安装libsvm2.89 +Python2.6

  步骤:
  1. 先将数据集scaledset转换成svm_model所要求的列表元组:格式是:前面是分类,后面是数据
  2.  选用RBF核函数,模型训练,预测。 
  3. 预测可以自动写预测数据,也可以用libsvm自带的cros_validation功能自动计算训练集的准确率

  用svm自带的交叉验证会将 据集自动划分成训练集和测试集,训练集自动构造出训练模型,测试集对模型进行测试。 

  该函数接受一个参数n,将数据集拆分成n个子集,函数每次将一个子集作为测试集,并利用所有其他子集对模型进行训练,最后返回一个分类结果列表,我们可以将该分类结果列表和最初的列表对比。

运行结果是:

 建立新预测数据:男士不想要小孩,女士想要:预测分类是:0.0
 建立新预测数据:男士想要小孩,女士想要:预测分类是:1.0 
 
 交叉验证自动生成的数据预测结果是:
[0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,  ........ ]
数据的行数一共是有:500

预测正确的个数有:417

预测错误的个数有:83.0

所以svm准确率是:   83.4 %

不同核函数对比结果:最终用RBF核函数 svm结果只有83.4%准确率
最终用POLY多项式核函数 svm结果只有73.6%准确率
最终用PRECOMPUTED核函数或SIGMOID核函数, svm结果都是只有59.8%准确率

综上,核函数最好效果的还是RBF,准确率为83.5%

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2016-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏赵俊的Java专栏

从源码上分析 ArrayList

1161
来自专栏计算机视觉与深度学习基础

Leetcode 114 Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place. For example, Given...

1928
来自专栏alexqdjay

HashMap 多线程下死循环分析及JDK8修复

1K4
来自专栏后端之路

LinkedList源码解读

List中除了ArrayList我们最常用的就是LinkedList了。 LInkedList与ArrayList的最大区别在于元素的插入效率和随机访问效率 ...

19010
来自专栏Hongten

ArrayList VS Vector(ArrayList和Vector的区别)_面试的时候经常出现

1642
来自专栏拭心的安卓进阶之路

Java 集合深入理解(12):古老的 Vector

今天刮台风,躲屋里看看 Vector ! 都说 Vector 是线程安全的 ArrayList,今天来根据源码看看是不是这么相...

2437
来自专栏学海无涯

Android开发之奇怪的Fragment

说起Android中的Fragment,在使用的时候稍加注意,就会发现存在以下两种: v4包中的兼容Fragment,android.support.v4.ap...

3155
来自专栏项勇

笔记68 | 切换fragmengt的replace和add方法笔记

1434
来自专栏xingoo, 一个梦想做发明家的程序员

Spark踩坑——java.lang.AbstractMethodError

百度了一下说是版本不一致导致的。于是重新检查各个jar包,发现spark-sql-kafka的版本是2.2,而spark的版本是2.3,修改spark-sql-...

1190
来自专栏xingoo, 一个梦想做发明家的程序员

AOE关键路径

这个算法来求关键路径,其实就是利用拓扑排序,首先求出,每个节点最晚开始时间,再倒退求每个最早开始的时间。 从而算出活动最早开始的时间和最晚开始的时间,如果这两个...

2507

扫码关注云+社区