从一段代码开始 运行这段代码之前,需要通过pip安装numpy、scipy、scikit-learn、jieba等依赖的Python模块。 # -*- coding: utf-8 -*- #
从一段代码开始
运行这段代码之前,需要通过pip安装numpy、scipy、scikit-learn、jieba等依赖的Python模块。
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 PPMessage.
# Guijin Ding, [email protected]
#
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import SVC
import jieba
def _classification():
_target = []
_data1 = ["您好", "你多大了", "你是什么呀", "你怎么了", "你男的女的呀"]
_target.append("我是PPMessage智能客服,我的名字叫PP,我很面,就是一个小PP,所以叫PP,您有什么的问题需要问我?")
_data2 = ["我想买", "怎么部署PPMESSAGE", "怎么下载PPMessage", "ppmessage是什么意思"]
_target.append("这个问题涉及到我们的核心利益 ^_^,转人工客服吧?")
_X = []
_Y = []
for _data in _data1:
_X.append(" ".join(jieba.lcut(_data)))
_Y.append(0)
for _data in _data2:
_X.append(" ".join(jieba.lcut(_data)))
_Y.append(1)
_v = TfidfVectorizer()
_X = _v.fit_transform(_X)
_clf = SVC(C=1000000.0, gamma='auto', kernel='rbf')
_clf.fit(_X, _Y)
_data = "PPMessage"
_x = " ".join(jieba.lcut(_data))
_x = _v.transform([_x])
_y = _clf.predict(_x)
print(_target[_y[0]])
return
if __name__ == "__main__":
_classification()
代码详解
上述程序演示了使用SVM做的文本分类,SVM不同于经常听到的Deep Learning,SVM有完整的数学解释,关注的同学可以自己Google。这里需要提一句的是,互联网上的SVM算法实现几乎都基于一个台湾人的贡献。
for _data in _data2:
_X.append(" ".join(jieba.lcut(_data)))
_Y.append(1)
首先使用结巴分词将训练集合中的句子进行中文分词,英文不需要分词,因为英文每个单词天然靠空格分隔,中文都是连着的,所以要根据语料的理解进行分词。分词之后再用空格隔开。
然后把每个待训练数据和训练结果对应起来,X[0]的数据对应结果是0,X[1]对应1这样。把数据集的结果集保存至_Y中。
_v = TfidfVectorizer()
_X = _v.fit_transform(_X)
这步是自然语言处理的关键之处,一个句子在分词之后,只是加了空格的字符串,并没有转化为数学问题,只有把真实的世界转换成数学问题,才可以求解。
TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随著它在文件中出现的次数成正比增加,但同时会随著它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜寻引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了TF-IDF以外,因特网上的搜寻引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TFXIDF,TF词频(Term Frequency),IDF反文档频率(Inverse Document Frequency)。TF表示词条,在文档d中出现的频率。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类C.中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当gfl大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处.
这里面用Tfidf做向量化,什么意思?就是把文本串转换成一个向量。向量必须存在于某种维度的空间之中。空间的每一个点即这个空间中的一个向量。上述两行代码即使用了Tfidf的概念建立空间,并且确定每个字符串的每个词在这个空间内的向量值。确定维度、定义域、以及每个词的值向量。
向量化之后的X就是一个数学上的X,_X中的内容将由一个个实数构成,无论是数组还是矩阵,无非就是表达一个向量的维度。
_clf = SVC(C=1000000.0, gamma='auto', kernel='rbf')
_clf.fit(_X, _Y)
建立一个RBF为核函数的支持向量机,用_X, _Y训练。训练支持向量机的过程被scikit learn做了抽象,使用scikit learn的其它机器学习的方法也使用同样的fit方法去训练。
_data = "PPMessage"
_x = " ".join(jieba.lcut(_data))
_x = _v.transform([_x])
_y = _clf.predict(_x)
训练结束后既可以用训练好的SVM对象进行识别,同样 scikit learn 对识别过程也做了抽象,几乎所有的机器学习过程的识别函数都是predict。这里的识别的结果应该是0或者1,返回值是以数组返回,因为predict可以一次predict多个数据。这里仅预测一个数据,所以只需关注返回值的第一个元素。
print(_target[_y[0]])
至此一个超级简单的文本分类完成。
需要改进
· 向量化过程
向量化过程,使用Google开源的word2vec,通过自己的语料库训练。word2vec转换出来的词向量能够支持距离的概念,即一个词语根据一个语料库转换成向量后,同义词之间向量距离更近。
· 在线训练
上述的SVM不支持在线训练,就是不能够增量训练,在某些生产环境这是不可以接受的。这是libSVM的问题,所以传导到全世界了,所有实用libSVM的都不支持在线训练。从一个侧面看出libSVM得到了多么广泛的应用。替这位炎黄子孙骄傲一下。
由于上传附件及文字限制,有时部分图片、文字可能显示不了,详情请见:http://mp.weixin.qq.com/s?__biz=MzI5ODI3NzY2MA==&mid=100000563&idx=3&sn=209b23f6a4b8faadf111dba4ab9dcca1#rd
欢迎大家一起交流。
扫描以下二维码,获取更多更精美文章!(扫码关注有意向不到的惊喜的哦!!)
关注我们微信订阅号( uniguytech100) 与服务号(uniguytech),获取更多更精美文章!
也欢迎加入【大家技术网讨论QQ群】,群号码:256175955,请备注你个人的介绍!让我们一起聊聊it的那些事!