基于Python的西瓜数据集 3.0α的SVM实现

在西瓜数据集 3.0α 上分别用线性核和高斯核训练一个 SVM,并比较其支持向量的差别。
数据集下载地址:
https://amazecourses.obs.cn-north-4.myhuaweicloud.com/datasets/watermelon_3a.csv
任选数据集中的一种分布类型的数据,分别用软、硬间隔SVM和各类核函数训练,并分析他们分类的效果。
数据集下载地址:https://amazecourses.obs.cn-north-4.myhuaweicloud.com/datasets/SVM.zip

由于课业繁忙,实在是没有时间从底层数学逻辑来实现SVM从而更好地理解把握支持向量机的原理。因此本次作业利用sklearn实现。
此博客为第一问的SVM的简单实现。
1. SVM实现
下方的链接博客很详细的给出了sklearn中SVM的参数,值得参考。

https://www.cnblogs.com/guodavid/p/10174763.html

  • 数据导入与处理
def load_dataset(fname):
    # fname = 'ensemble_study/dataset/weatherHistory.csv'
    data = pd.read_csv(fname, index_col=0)
    return data


def process_data(data: pd.core.frame.DataFrame):
    data.drop('编号', axis=1, inplace=True)
    feature_list = data['色泽'].unique().tolist()
    # print(feature_list)
    data['色泽'] = data['色泽'].apply(lambda n: feature_list.index(n))
    feature_list = data['根蒂'].unique().tolist()
    data['根蒂'] = data['根蒂'].apply(lambda n: feature_list.index(n))
    feature_list = data['敲声'].unique().tolist()
    data['敲声'] = data['敲声'].apply(lambda n: feature_list.index(n))
    feature_list = data['纹理'].unique().tolist()
    data['纹理'] = data['纹理'].apply(lambda n: feature_list.index(n))
    feature_list = data['脐部'].unique().tolist()
    data['脐部'] = data['脐部'].apply(lambda n: feature_list.index(n))
    feature_list = data['触感'].unique().tolist()
    data['触感'] = data['触感'].apply(lambda n: feature_list.index(n))
    feature_list = ['否', '是']
    data['好瓜'] = data['好瓜'].apply(lambda n: feature_list.index(n))

    return data


def split_train_test_set(data: pd.core.frame.DataFrame):
    y = data['好瓜'].values
    data.drop('好瓜', axis=1, inplace=True)
    xtrain, xtest, ytrain, ytest = train_test_split(data, y, test_size=0.2)
    return xtrain, xtest, ytrain, ytest

数据处理部分主要做的是将数据集中的中文特征标签全部利用序列号编号处理,即利用数值来代表,再去除掉编号这一无用数据特征,将目标特征单独提出,之后利用sklearn的train_test_split方法随机划分数据集。

- 线性核,高斯核的支持向量机实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/12/19 19:54
# @Author  : Ryu
# @Site    : 
# @File    : SVM.py
# @Software: PyCharm

from data_process import *
from sklearn import svm
from sklearn.metrics import accuracy_score
from visual import visual
import copy

if __name__ == '__main__':
    file_name = 'D:\Pythonwork\FisherLDA\SVM\watermelon_3a.csv'

    data = load_dataset(file_name)
    raw_data = copy.deepcopy(data)
    train = process_data(raw_data)
    xtrain, xtest, ytrain, ytest = split_train_test_set(train)

    # 线性核处理
    linear_svm = svm.LinearSVC(C=0.5, class_weight='balanced')
    linear_svm.fit(xtrain, ytrain)
    y_pred = linear_svm.predict(xtest)
    print('线性核的准确率为:{}'.format(accuracy_score(y_pred=y_pred, y_true=ytest)))

    # 高斯核处理
    gauss_svm = svm.SVC(C=0.5, kernel='rbf', class_weight='balanced')
    gauss_svm.fit(xtrain, ytrain)
    y_pred2 = gauss_svm.predict(xtest)
    print('高斯核的准确率: %s' % (accuracy_score(y_pred=y_pred2, y_true=ytest)))

    #多项式核
    poly_svm = svm.SVC(C=0.5, kernel='poly', degree=3, gamma='auto', coef0=0, class_weight='balanced')
    poly_svm.fit(xtrain, ytrain)
    y_pred3 = poly_svm.predict(xtest)
    print('多项式核的准确率: %s' % (accuracy_score(y_pred=y_pred3, y_true=ytest)))

    #sigmoid核
    sigmoid_svm = svm.SVC(C=0.5, kernel='sigmoid', degree=3, gamma='auto', coef0=0, class_weight='balanced')
    sigmoid_svm.fit(xtrain, ytrain)
    y_pred4 = sigmoid_svm.predict(xtest)
    print('sigmoid核的准确率: %s' % (accuracy_score(y_pred=y_pred4, y_true=ytest)))


    visual(data, 'gauss_svm', gauss_svm)
    visual(data, 'sigmoid svm', sigmoid_svm)

需要说明的是,上述代码中惩罚系数均使用0.5完成。线性核和高斯核的两个SVM中笔者均将class_weighted这个参数设置为了‘balanced’,利用自动计算的样本权值来调整数据集分布——主要愿意是样本数据只有17个,实在是太小了,导致任意一个样本的分类不当都会对整个SVM的准确率产生极大的影响。

  • 实验分析
    在这里插入图片描述
    在class_weighted参数未加入时,实验效果极差。由于样本数很少,划分训练测试数据集时比率取到0.2已是极限。在这种情况下,如果不采用加权样本分类的方法,两个核函数的SVM最终结果基本只有很小概率能够达到50%以上。在加入了之后正确率基本能够稳定在67%以上。并且线性划分的效果基本都好于高斯核的效果。这可能也与训练集过于简单有关。在这里插入图片描述
    由于线性svm在sklearn中没有特征向量支持,故选用sigmoid的核替代展示。可以明显的发现,sigmoid的分类效果不尽人如意。

在这里插入图片描述
高斯核的分类效果相较sigmoid更好,经多次试验发现也更加稳定。

  • 13
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
首先,需要下载西瓜数据集3.0α并安装LIBSVDL库。 然后,我们可以使用以下代码来加载数据集并将其分成训练集和测试集: ```python import numpy as np import svdL data = np.loadtxt('watermelon_3.0α.txt', delimiter='\t') X = data[:, 1:3] # features y = data[:, 3] # labels # normalize features X = (X - np.mean(X, axis=0)) / np.std(X, axis=0) # split data into train and test sets train_X, train_y = X[:10], y[:10] test_X, test_y = X[10:], y[10:] ``` 接下来,我们可以使用LIBSVDL库来训练一个线性核SVM模型: ```python # train linear kernel SVM svm = svdL.SVM(kernel='linear', C=1) svm.train(train_X, train_y) # predict test set labels pred_y = svm.predict(test_X) # print support vectors print('Support vectors for linear kernel SVM:') print(svm.get_support_vectors()) ``` 同样,我们可以使用以下代码来训练一个高斯核SVM模型: ```python # train Gaussian kernel SVM svm = svdL.SVM(kernel='rbf', C=1, gamma=0.1) svm.train(train_X, train_y) # predict test set labels pred_y = svm.predict(test_X) # print support vectors print('Support vectors for Gaussian kernel SVM:') print(svm.get_support_vectors()) ``` 在训练完两个模型后,我们可以比较它们的支持向量。支持向量是SVM模型中起关键作用的数据点,它们决定了模型的边界。通常情况下,高斯核SVM模型的支持向量数会比线性核SVM模型的支持向量数要多,因为高斯核SVM模型可以更好地处理非线性问题。 通过打印支持向量,我们可以看到两个模型的支持向量数量和位置的差异。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值