美文网首页
unit9 相亲匹配判别

unit9 相亲匹配判别

作者: 巴拉巴拉_9515 | 来源:发表于2018-05-22 14:04 被阅读0次

    《集体智慧编程》第九单元“高阶分类”主要亮点是相亲人员的匹配判断。是有监督的分析,基于一定量的有结果的试验数据,从中获得规律实现预测。使用高阶分类:核方法与支持向量机(SVM)训练模型并对配对进行判断。

    01数据集介绍

    假设某网站的相亲记录如下:每一行代表一个配对试验,记录女性和男性的年龄、是否吸烟、是否有孩子、兴趣、住址,以及是否配对成功(0表示失败,1表示成功)。

    单提取男女年龄一项,看看相亲市场上年龄的配对情况。散点分布如下图。

    横轴为female年龄:年轻的姑娘(<25)和40岁以上男性基本配对失败;
    25-40岁的女性在配对上,对象的年龄并没有那么大限制,40岁的女性和20几岁的男性成功配对数也比较多。
    40-50岁的女性和25岁以下的男性配对成功的概率较低

    02 数据预处理

    (1)数值化
    将原始数据转换为数值型,可以方便模型的使用。

    是否吸烟?是否有孩子:是1;否-1,模糊或确实或不清楚的为0
    兴趣爱好:显示男女相同爱好的个数
    地址显示男女间地址距离

    预处理后数据集变量为:女性年龄,是否吸烟,是否有孩子,男性年龄,是否吸烟,是否有孩子,相同爱好,地址距离。

    [39.0, 1, -1, 43.0, -1, 1, 0, 105.66516194012885]
    [23.0, -1, -1, 30.0, -1, -1, 0, 1.319127371884788]
    [50.0, -1, -1, 49.0, 1, 1, 2, 106.48245828168044]
    [46.0, -1, 1, 19.0, -1, -1, 0, 110.56632686422407]

    (2)标准化
    由于不同变量的数值范围不同,需要做标准化处理,使数据范围在同一水平,便于比较。标准化处理后,每个变量范围在0-1之间,数据集如下所示:

    [0.65625, 1.0, 0.0, 0.78125, 0.0, 1.0, 0.0, 0.9556721737702848]
    [0.15625, 0.0, 0.0, 0.375, 0.0, 0.0, 0.0, 0.011930642984140028]
    [1.0, 0.0, 0.0, 0.96875, 1.0, 1.0, 1.0, 0.9630640838095432]
    [0.875, 0.0, 1.0, 0.03125, 0.0, 0.0, 0.0, 1.0]

    03 核方法

    核方法kernel methods (KMs)是一类模式识别的算法,是解决非线性模式分析问题的一种有效途径。
    径向基

    def rbf(v1, v2, gamma=10):
        dv = [v1[i] - v2[i] for i in range(len(v1))]#点与点间的差
        l = veclength(dv)
        return math.e ** (-gamma * l)
    

    偏移量
    转换空间以后会发生改变。

    def getoffset(rows, gamma=10):
        l0 = []
        l1 = []
        #匹配成功的都提出来放在L1中,失败的都放在L0中.
        for row in rows:
            if row.match == 0:
                l0.append(row.data)
            else:
                l1.append(row.data)
        #向量V1、V2偏移量计算
        sum0 = sum(sum([rbf(v1, v2, gamma) for v1 in l0]) for v2 in l0)
        sum1 = sum(sum([rbf(v1, v2, gamma) for v1 in l1]) for v2 in l1)
        return (1.0 / (len(l1) ** 2)) * sum1 - (1.0 / (len(l0) ** 2)) * sum0
    ssoffset=getoffset(scaledset)#结果为0.05915809687556309
    

    核方法
    模型建立,基于径向量和偏移量,建立决策判断模型。

    #输入:point(目标判断点), rows(数据集),offset(偏移量)
    def nlclassify(point, rows, offset, gamma=10):
        sum0 = 0.0
        sum1 = 0.0
        count0 = 0
        count1 = 0
        #配对成功/失败两个数据集径向基计算
        for row in rows:
            if row.match == 0:
                sum0 += rbf(point, row.data, gamma)
                count0 += 1
            else:
                sum1 += rbf(point, row.data, gamma)
                count1 += 1
        #核方法判断方程
        y = (1.0 / count0) * sum0 - (1.0 / count1) * sum1 + offset
        if y > 0:
            return 0#配对失败
        else:
            return 1#配对成功
    #判断[0.65625, 1.0, 0.0, 0.78125, 0.0, 1.0, 0.0, 0.9556721737702848]
    nlclassify(scalef(numericalset[0].data),scaledset,ssoffset)#0;#scalef基于数据集的缩放函数
    

    预测判断
    例如有一组数据newrow=[23.0,-1,-1,30.0,-1,-1,0,1.3]。

    女性23岁,不吸烟,无小孩;
    男性30岁,不吸烟,无小孩;
    无共同兴趣爱好,住址相距1.3

    核方法判断结果为:配对成功(结果为:1)

    nlclassify(scalef(newrow),scaledset,ssoffset)#1
    

    04 SVM支持向量机

    代码实现SVM很方便

    from sklearn import svm
    clf_linear = svm.SVC(kernel='linear').fit(inputs,answers)
    clf_rbf = svm.SVC(kernel='rbf').fit(inputs,answers)
    clf_sigmoid = svm.SVC(kernel='sigmoid').fit(inputs,answers)
    

    训练号SVM模型以后,实现对未知分类的数据集预判。

    a=scalef([23.0,-1,-1,30.0,-1,-1,0,1.3])
    newrow=np.array([a])
    clf_linear.predict(newrow)#array([0])
    

    05 困难及问题

    在对原始数据“地址”做处理计算两地间距离时,yahoo!map一直调试不出来无法获得地址的经纬度。数据集中的地址都是美国地址686 Avenue of the Americas New York NY,经过多次尝试最后使用geopy包实现。

    from geopy.geocoders import Nominatim
    def geocodeN(address):
        gps=Nominatim()
        location=gps.geocode(address)
        return location.longitude,location.latitude
    geocodeN("220 W 42nd St New York NY")
    #(-73.987958, 40.7563095),成功了
    

    但问题是计算每一对距离都很耗时,实际操作中我只计算了20组数据的距离,造成核方法、SVM的训练数据太少,所以以上判断并不考虑准确性。

    总之,模型实现其实还好,数据预处理花了很久折腾。

    相关文章

      网友评论

          本文标题:unit9 相亲匹配判别

          本文链接:https://www.haomeiwen.com/subject/rblhjftx.html