zoukankan      html  css  js  c++  java
  • 机器学习之SVM多分类

    实验要求
    数据说明 :数据集data4train.mat是一个2*150的矩阵,代表了150个样本,每个样本具有两维特征,其类标在truelabel.mat文件中,trainning sample 图展示了理想的分类类结果;
    方案选择:
    选择并实现一种两分类方法(如感知机方法,SVM等);在此基础上设计使用该二分类器实现三分类问题的策略,并程序实现,画出分类结果
    直接采用现成的可实现多分类的方法(如多类SVM,BP网络等)进行问题求解。画出分类结果。我选择第二种,时间不够,只能使用sklearn中的svc实现

    实现思想
    一对一:
    其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。
    优点:不需要重新训练所有的SVM,只需要重新训练和增加语音样本相关的分类器。在训练单个模型时,速度较快。
    缺点:所需构造和测试的二值分类器的数量关于k成二次函数增长,总训练时间和测试时间相对较慢。

    一对多
    训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。
    **优点:**训练k个分类器,个数较少,其分类速度相对较快。
    缺点:
    ①每个分类器的训练都是将全部的样本作为训练样本,这样在求解二次规划问题时,训练速度会随着训练样本的数量的增加而急剧减慢;
    ②同时由于负类样本的数据要远远大于正类样本的数据,从而出现了样本不对称的情况,且这种情况随着训练数据的增加而趋向严重。解决不对称的问题可以引入不同的惩罚因子,对样本点来说较少的正类采用较大的惩罚因子C;
    ③还有就是当有新的类别加进来时,需要对所有的模型进行重新训练

    层次树:
    首先将所有类别分为两个类别,再将子类进一步划分为两个次级子类,如此循环下去,直到所有的节点都只包含一个单独的类别为止,此节点也是二叉树树种的叶子。该分类将原有的分类问题同样分解成了一系列的两类分类问题,其中两个子类间的分类函数采用SVM。

    我这里选择一对多,因为只有三类

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2019/7/2 23:25
    # @Author : 朱红喜
    # @File : Multi-classify.py
    # @Software: PyCharm

    # 引入必要的库
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import svm
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import label_binarize
    from sklearn.multiclass import OneVsRestClassifier

    from FileUtil import FileUtil

    # 加载数据
    # 1.训练模型的数据
    X = FileUtil.open_matfile("data4train.mat").T # 数据集
    y = FileUtil.open_matfile("truelabel.mat") # 真实标签
    print(X)
    print(y[0])
    print(y.shape)


    # 2.测试模型的数据
    X_2 = FileUtil.open_matfile("data4test.mat").T
    y_2 = FileUtil.open_matfile("testtruelabel.mat")
    print(X_2)
    print(y_2[0])
    print(y_2.shape)


    # 标签二值化
    y = label_binarize(y[0], classes=[1, 2, 3])
    # print(y)


    # 划分训练集和测试集
    # 设置种类
    n_classes = y.shape[1]
    # print(y.shape[1])


    # 训练模型并预测
    random_state = np.random.RandomState(0)
    n_samples, n_features = X.shape
    # 随机化数据,并划分训练数据和测试数据
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5, random_state=0)

    # 训练模型
    # Learn to predict each class against the other
    model = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True, random_state=random_state))
    clt = model.fit(X_train, y_train)


    # 性能评估
    # 1.在训练集上的得分
    clt.score(X_train, y_train)
    print(clt.score(X_train, y_train))

    # 2.在测试集上的评分
    clt.score(X_test, y_test)
    print(clt.score(X_test, y_test))

    # 查看各类别的预测情况
    y_predict_scores = clt.decision_function(X_test)
    print(y_predict_scores[:149])

    # 转化为原始标签模式
    result = np.argmax(clt.decision_function(X_test), axis=1)[:149]
    # print(result)
    # 转化为老师需要的 1,2,3类标
    for i in range(result.__len__()):
    result[i] = result[i]+1

    print(result)


    print("++++++++++++++++++++++data4train数据集++++++++++++++++++")
    result_2 = np.argmax(clt.decision_function(X), axis=1)[:149]
    # print(result_2)
    # 转化为老师需要的 1,2,3类标
    for i in range(result_2.__len__()):
    result_2[i] = result_2[i]+1
    print(result_2)


    print("++++++++++++++++++++++data4test测试集++++++++++++++++++")
    result_2 = np.argmax(clt.decision_function(X_2), axis=1)[:59]
    # print(result_2)
    # 转化为老师需要的 1,2,3类标
    for i in range(result_2.__len__()):
    result_2[i] = result_2[i]+1
    print(result_2)

    分类结果


  • 相关阅读:
    简单工厂模式
    单例模式
    Quartz.NET总结(三)Quartz 配置
    Quartz.NET总结(二)CronTrigger和Cron表达式
    ORACLE跨数据库查询的方法
    github使用个人总结
    ffmpeg 下载安装和简单应用
    Python 安装与环境变量配置
    Sublime text 3 汉化教程
    给大家分享两套WordPress收费主题
  • 原文地址:https://www.cnblogs.com/liuys635/p/11183827.html
Copyright © 2011-2022 走看看