查看: 46|回复: 0

[分享] 让机器学习回归传统SVM番外篇

[复制链接]
  • TA的每日心情
    开心
    2020-12-18 12:56
  • 签到天数: 55 天

    [LV.5]常住居民I

    75

    主题

    225

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    1632
    最后登录
    2024-4-26
    发表于 2024-4-25 11:15:44 | 显示全部楼层 |阅读模式
    老树发新芽SVM的增量式训练
    大家是不是以为我们的SVM篇就这样结束了?nonono,对于这样一位资深的老前辈来说,寥寥几篇怎能叙说尽,换句话来说,历经几十年的历练,还能屹立于ML之巅,必定拥有卓越的技术实力和深厚的专业底蕴。
    不过,大家在用SVM时一定也注意到过SVM本身只支持单次训练,要怎么解释呢?意思就是说我们在训练一个SVM模型前,要事先指定好想要识别的类别或是任务,这样训练好之后,模型就只能针对所指定的任务了。如果想要再添加新的需求,那不好意思了,需要再重新制定任务,并且这个任务必须包含老任务,不然SVM就会喜新厌旧了,只能完成新任务。
    这样一来是不是有点麻烦?有伙伴要问了,我们CNN就能支持增量学习,你这SVM看起来还是不太行啊。那么为了给我们的SVM大佬正名,今天小编就给大家带来一篇番外,利用一些小技巧实现SVM的增量式训练。直接上代码!!
    继续使用我们的鸢尾花数据集,不过这次我们做点特殊的。我们将其作为一个单分类的数据集来使用,具体怎么做呢?让我们一步步来看:
    鸢尾花数据集一共有150组样本,我们先选取前50组出来,训练一个单分类模型,目的是让其只能够识别一种样本,代码片段:
    from sklearn import datasets
    from  sklearn.model_selection import  train_test_split
    from  sklearn.preprocessing import  StandardScaler
    from sklearn.svm import OneClassSVM
    from  sklearn.metrics import  accuracy_score


    import numpy as np
    # 加载数据集
    iris =  datasets.load_iris()
    X = iris.data
    y =  iris.target
    data_each = 50
    X0 =  X[:data_each]
    y0 =  y[:data_each]
    # 构建支持向量机分类器
    svm =  OneClassSVM(kernel='rbf', nu=0.1)
    # 在训练集上训练模型,选取前30组作为训练样本
    svm.fit(X_train[:30])
    # 在测试集上进行预测,选取后20组数据作为测试集
    y_pred =  svm.predict(X_train[30:])
    print("ACC:  ", (y_pred == 1).sum() /  len(y_pred))
    测试结果打印:

    测试结果打印:

    测试结果打印:
    好的,接下来就是至关重要的一步了,我们知道SVM全称是支持向量机,那么其原理就是在训练样本重抽取一部分当作支持向量,即挑选出能够代表全体数据的灵魂数据。换句话说,这些支持向量本身就能代表当前类别的所有数据,通过和支持向量间的对比即可认定新数据是否属于同一类别。那么好,我们要做的就是将这些支持向量提取出来,并将其与新数据拼接在一起作为新的训练数据:
    support_vector = svm.support_vectors_
    # 拼接数据,将前一类别的支持向量与新数据结合
    new_train_x =  np.vstack([support_vector, X[data_each:2*data_each][:30]])
    这里提前看一下支持向量,针对于第一个类别,支持向量有4个:

    支持向量有4个

    支持向量有4个
    继续训练,并测试:
    # 构建支持向量机分类器
    svm =  OneClassSVM(kernel='rbf', nu=0.1)
    svm.fit(new_train_x)
    # 在测试集上进行预测,拼接之前的数据集
    y_pred = svm.predict(np.vstack([X0[30:],  X[data_each:2*data_each][30:]]))
    print("ACC:  ", (y_pred == 1).sum() /  len(y_pred))
    测试结果:

    测试结果:

    测试结果:


    再来看下新的支持向量:

    新的支持向量

    新的支持向量
    可以看到,在第一次支持向量的基础上,又增加了针对第二个类别的。同时根据测试精度,可以看出,通过添加第一次训练多得到的支持向量,而非将全体数据进行二次训练,能够达到同样的效果。也验证了我们的猜测:支持向量本身其实就是数据集的代表,只将其作为训练样本,完全能够替代全部数据。并以此为基础实现SVM模型的增量式训练。

    签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-6 00:32 , Processed in 0.110112 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表