SVM分类算法实现与比较

基于SMO方法的SVM分类器实现,具体见上一篇博客:
这里主要是将自己写的SVM算法(my_SVM)与sklearnSVM算法进行比较。
代码的实现主要是基于:sklearn官方教程

遇到的主要问题:

  1. 分类模型拟合与预测的评估
  2. 生成器列表
  3. 模型训练与预测的疑惑

下面分别对遇到的问题展开说明

1 分类模型评估方法

关于二分类模型的评价指标,主要有 混淆矩阵ROCAUC等指标。
详细可以介绍可以见:
分类问题的评价指标
二分类问题评价指标
分类问题的评估指标一览

实际上,sklearn中提供的各种算法模型,其一般自带的都有score方法可以用于对模型进行评估。这里为了控制变量,统一采用sklearn.metrics提供的评估方法。
详细资料点这里

适用于二分类问题的方法:

调用功能
precision_recall_curve(y_true, probas_pred)Compute precision-recall pairs for different probability thresholds
roc_curve(y_true, y_score[, pos_label, …])Compute Receiver operating characteristic (ROC)

2 生成器无法进行查看

sklearn中提供的例子有一行代码如下:

models_ori = (svm.SVC(kernel='linear', C = C),
              svm.LinearSVC(C=C, max_iter=10000),
              svm.SVC(kernel='rbf', gamma=0.7, C=C),
              svm.SVC(kernel='poly', degree=3, gamma='auto', C=C))
# SVC与linearSVC的区别:https://www.cnblogs.com/zealousness/p/7757603.html
models_ori_fit = (clf.fit(X_train, y_train) for clf in models_ori)
# 创建的是生成器,这里将其改为列表。
# https://www.jianshu.com/p/6868cb724ba7

这里创建的models_ori_fit实际上为一个generator类型数据,在实际适用中会发现
无法直接调用moels_ori_fit[0].predict(),而且在变量栏中也无法直接查看。
具体的解决方法通过采用list()的方法进行访问,具体见解决can’t pickle generator objects问题。这里,我直接通过将代码改为```models_ori_fit = [lf.fit(X_train, y_train) for clf in models_ori]``,这样返回值就是一个列表,从而可以进行访问。

3 模型训练与预测的问题

在sklearn中,以SVM举例。通过调用clf=svm.SVC()即可以实例化一个SVM分类器,进一步可以调用其中的方法fit,即clf.fit(X,y)进行训练,在训练完成后,实际上其返回值是self,即更新了clf。因此,在进行预测的时候同样可以调用clf.predict(X_test)即可实现预测。其他的算法是一样的。
在训练完成后,可以调用属性fit_status_查看训练是否正确,正确则返回值为0,否则为1(将报错)。

4 代码实现

"""
该脚本基于sklearn官方文档,实现对breast_cancer的二分类
其中,my_SVM是基于SMO自己实现的SVM分类器,ori_SVM是sklearn自带的SVM
这里仅选取 sepal length 和 sepal width 两个特征
分别采用 linear、RBF、poly三种核函数进行两种SVM算法的比较
"""
import mysvm as my
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import svm
import matplotlib.pyplot as plt
from sklearn.metrics import (precision_recall_curve, roc_curve, plot_roc_curve,
                             confusion_matrix, f1_score, accuracy_score, precision_score,
                             classification_report)
import pandas as pd
import numpy as np

def create_data():
    """
    创建基于iris dataset的数据集
    Returns
    -------
    X_train : TYPE
        DESCRIPTION.
    X_test : TYPE
        DESCRIPTION.
    y_train : TYPE
        DESCRIPTION.
    y_test : TYPE
        DESCRIPTION.
    """
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns = iris.feature_names)
    df['label'] = iris.target
    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
    data = np.array(df.iloc[:100, [0, 1, -1]]) # 通过行号提取数据
    # https://blog.csdn.net/w_weiying/article/details/81411257

    for i in range(len(data)):
        if data[i, -1] == 0:
            data[i, -1] == -1
    X_train, X_test, y_train, y_test = train_test_split(
        data[:,:2], data[:, -1], test_size = 0.25, random_state=2020)# 数据打乱及划分        
    return X_train, X_test, y_train, y_test 
# =============================================================================
# 模型训练与预测
# 模型再进行拟合后,就可以用来预测新的值
# 如:clf = svm.SVC(); clf.fit(X_train, y_train);clf.predict(X_test)
# 即当clf.fit执行完之后会返回一个新的训练完成的clf
# 可以调用clf.fit_status_查看是否正确训练,0则为correctly fitting
X_train, X_test, y_train, y_test  = create_data()

C = 2.0 # 设置惩罚项系数,设置为1时,自己编写的SVM会报错

models_ori = (svm.SVC(kernel='linear', C = C),
              svm.LinearSVC(C=C, max_iter=1000),
              svm.SVC(kernel='rbf', gamma=0.7, C=C),
              svm.SVC(kernel='poly', degree=3, gamma='auto', C=C))
# SVC与linearSVC的区别:https://www.cnblogs.com/zealousness/p/7757603.html
models_ori = [clf.fit(X_train, y_train) for clf in models_ori]
# 创建的是生成器,这里将其改为列表。
# https://www.jianshu.com/p/6868cb724ba7

y_pre_ori = [clf.predict(X_test) for clf in models_ori] #预测输出

models_my = [my.SVM(kernel='linear', max_iter=1000, C=C),
             my.SVM(kernel='poly', max_iter=1000, C=C),
             my.SVM(kernel='rbf', max_iter=1000, C=C)]

y_pre_my = [] 
for i in range(3):
    models_my[i].fit(X_train, y_train) # 训练
    # y_pre_my[i] = models_my[i].predicts(X_test) # 空数组不能直接指定位置
    y_pre_my.append(models_my[i].predicts(X_test))

# =============================================================================
# 模型预测结果评估
y_pre = y_pre_ori + y_pre_my #前四组为sklearn,后三组为自己写的SVM
cm = [] # confusion_matrix
f1_scores = [] # https://blog.csdn.net/qq_14997473/article/details/82684300
ACC = [] # 
for i in range(len(y_pre)):
    cm.append(confusion_matrix(y_test, y_pre[i]))
    # https://blog.csdn.net/shenxiaoming77/article/details/72627882
    f1_scores.append(f1_score(y_test, y_pre[i]))
    ACC.append(accuracy_score(y_test, y_pre[i]))
print('预测准确率:' , ACC)
print('预测f1_score' , f1_scores)
scores = pd.DataFrame([f1_scores, ACC], 
                  columns = ['linear svc','linearSVC','rbf svc',
                             'poly svc','linear SVM', 'poly SVM', 'rbf SVM'],
                  index = ['f1_score','Accuracy score'])
      
#显示所有列
pd.set_option('display.max_columns', None)
print('模型结果比较', scores)

运行结果如下:

                 linear svc  linearSVC  rbf svc  poly svc  linear SVM  poly SVM  rbf SVM
f1_score              0.96       0.96     0.96      0.96    0.642857     0.64     0.00
Accuracy score        0.96       0.96     0.96      0.96    0.600000     0.64     0.52
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值