Scikit-learn中使用SVM对文本进行分类

(一)背景

  本人最近弄了两个和svm算法有关的大作业,一个是处理手写数字识别的,另外一个是文本分类的。最开始,我用libsvm提供的包进行分类。但是总是会出现分成一类的情况。有时候数据归一化之后,就不会分成一类,能够正常分类;但有时候源数据能正常分类,而归一化数据之后却会分成只有一类的情况。

  这让我感到很苦恼,并且了解了一下SVM算法,但是仍然不知道问题所在。后来在大神指点下,使用机器学习框架scikit-learn中自带的svm算法,能够有效的避免这种分成一类的现象,下面以某个文本分类为例子,对scikit-learn中的svm算法用法进行讲解。

(二)系统环境及scikit-learn安装

  本人使用的ubuntu系统,在安装skicit-learn之前,请保证安装了Python3(尽量最新版),以及pip3(便于Python模块的安装)。在安装了Python3和pip3的前提下,要安装skicit-learn,得先安装numpy和scipy模块。

  1.安装numpy模块

sudo pip3 install numpy

  2.安装scipy模块

sudo pip3 install scipy

  3.安装scikit-learn

sudo pip3 install scikit-learn

  也可以先下载好相应的whl文件,然后用pip3命令进行安装

(三)文本分类

  先给出文本分类的数据,包括两个文件,一个是train_data.txt 和predict_data.txt文件,这两个文件的格式是标准的libsvm数据文件的格式,即:

lable1 dimension1:value1 dimension2:value2......
lable2 dimension1:value1 dimension2:value2......

数据网盘地址为:http://pan.baidu.com/s/1hrLoHMk
提取码为:yjxx

1.scikit-learn中svm介绍
  scikit-learn中用于svm分类的类包括三个类,SVC,NuSVC和LinearSVC这三个类。SVC和NuSVC两种方法类似,但是接受的参数有细微不同,而且底层数学原理不一样。LinearSVC是指核函数为线性核的SVM。

2.SVC用法介绍
  要使用SVC需要将数据的标签类别和维向量分开保存,例如文本类别用y数组包括,文本内容向量用x数组保存。然后再使用numpy.array对数据进行规整,编程标准的数组格式,再调用SVC的fit()函数训练出模型。训练好模型之后用SVC.predict()函数根据文本内容向量预测出文本的类别。

其中SVC.fit(train_y, train_x)中参数train_y为文本类别,是一个一维数组;train_x为文本内容向量,是一个二维数组。经过fit()函数处
理后,模型就会保存在SVC中(也许SVC类中有一个model变量)。fit()函数无返回值。

SVC.predict(predict_x),参数predict_x是需要分类的文本内容的向量,是一个二维数组。predict()函数的返回值是一个文本类别数组。

3.文本分类代码:

__author__ = 'liuwei'


import os
import pickle
import numpy as np
from sklearn.svm import SVC


class DataProc(object):
    '''get datas from the file'''

    def __init__(self, fileName):
        self.fileName = fileName
        self.readData()


    def readData(self):
        self.main_data = []

        with open(self.fileName, 'r') as file:
            data = file.readlines()


            for item in data:
                item = item.rstrip('\n')                                   #去除尾部换行符
                item = item.rstrip(' ')                                    #去除尾部空格
                items = item.split(' ')                     

                f_items = []

                for son_item in items:
                    f_items.append(float(son_item))                        #将字符类型转化为浮点类型


                self.main_data.append(f_items)

        self.main_data = np.array(self.main_data)                          #转换为二维数组


    def getY(self):
        '''get all labels,is the first column of the array'''

        self.y_data = self.main_data[:,0]                                  #获取所有文本的类别便签,即第一列

        return self.y_data


    def getX(self):
        '''get the data of text except the first column'''

        self.x_data = self.main_data[:,1:]                                 #获取所有文本的内容向量,除第一列以外的列

        return self.x_data


class SVM(object):
    '''use the svm algorithm in the skicit-learn to predict the class of text'''

    def __init__(self, train_dataproc, predict_dataproc):
        self.__train_data = train_dataproc
        self.__pred_data = predict_dataproc
        self.__svc = SVC()


    def train(self):
        '''train data,and general a model'''

        train_y = self.__train_data.getY()                                  #所有训练文本类别
        train_x = self.__train_data.getX()                                  #所有训练文本内容向量

        self.__svc.fit(train_x, train_y)                                    #开始训练,

        #we can save the model in .pkl file
        self.model_presistence()                                            #将SVC对象持久化,相当于将模型持久化



    def predict(self):
        '''predict the data'''

        predict_y = self.__pred_data.getY()                                 #
        predict_x = self.__pred_data.getX()

        test_data = np.array(predict_x)

        res = self.__svc.predict(test_data)                                 #开始预测,结果在res中

        accu = 0

        for i in range(len(predict_y)):
            if predict_y[i] == res[i]:                                      #统计正确率
                accu += 1

        accu = accu / len(predict_y)


        print('the accuracy is %f' %accu)                                   #输出正确率




    def model_presistence(self):
        '''save a model in .pkl file'''

        fileObject = open('SVM.pkl', 'wb')
        pickle.dump(self.__svc, fileObject)                                 #将SVC持久化
        fileObject.close()


    def read_model(self):
        '''load a model from a .pkl file'''

        fileName = 'SVM.pkl'
        fileObject = open(fileName, 'rb')
        self.__svc = pickle.load(fileObject)                                #读取SVC



if __name__ == '__main__':
    train_data = DataProc('/home/liuwei/python-space/datas/train_data.txt')
    predict_data = DataProc('/home/liuwei/python-space/datas/predict_data.txt')

    svm = SVM(train_data, predict_data)

    #开始训练
    svm.train()

    #开始预测
    svm.predict()

4.运行结果:
这里写图片描述

可以看出,分类的正确率为67.8%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值