文本特征提取和向量化

您所在的位置:网站首页 文本向量化什么意思 文本特征提取和向量化

文本特征提取和向量化

2024-07-09 21:32| 来源: 网络整理| 查看: 265

转自:https://fancoo.wordpress.com/2016/03/09/三-文本特征提取和向量化/

在(二)中,我已经能获取每个词条在百度搜索下的结果。我将所有的可疑词条的百度搜索结果保存为文件。每一行文本是一个词条的搜索结果。例如,我有728个可以词条,那么我将保存728行文本,现在我们要提取出每一行文本中的特征词。

接下来的操作依次是:

标记正负样本并下载它们的全部文本对文本进行分词通过Tf-Idf、词频、CHI、或是信息增益等方法取出特征词将特征词向量化

获取正负样本

我使用手工的方法,在近3000个样本分离出了150个负样本,也就是诸如’asdf’之类看上去很不正常的名称,正样本就选取带’有限公司’的公司名,并使用(二)中的方法,将正负样本的的网页搜索结果解析出来的 文本保存下来。

  分词  

  中文分词我使用的是jieba,jieba有多种切词模式,还支持自定义停用词和idf词库,如果你使用的是jieba.analyse这个库,它支持tfidf和textRank两种特征,在我的使用过程中有一个很不爽的地方是,如果你仅仅使用jieba.cut,那么在原文本中包含的多种特殊符号将令人头疼(当然你也可以用正则消除掉),而一旦你使用jieba.analyse,你会发下它已经自动过滤了这些词,可是它已经使用了tf-idf或是textRank,一句话:如果你仅仅想用它来分词,提取特征的事情后续由自己来做,那么jieba.analyse会令人讨厌的先给你的词预筛选一遍。这里我topK设置为前10000个词,基本上不会筛掉词了。

分词代码段:

def extract_tag(text_file, tag_file): with open(text_file, 'r') as tf: for text in tf: utf8_text = text.decode('utf-8', 'ignore') #print utf8_text seg_list = jieba.cut(utf8_text, cut_all=True) clean_text = " ".join(seg_list) jieba.analyse.set_stop_words("extra/stop_words.dict") print '\n' tags = jieba.analyse.textrank(clean_text, topK=10000, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) print(" ".join(tags)) mstr = " ".join(tags) mlist = mstr.split() mlist = list(set(mlist)) with open(tag_file, 'a') as f: for item in mlist: utf8_item = item.encode('utf-8', 'ignore') f.write(utf8_item+'\t') f.write('\n') f.close() tf.close()

这里我得到一个tag_file,每一行有若干个词,代表这一个文本的特征集合,下面要做的事就是提取特征。

特征提取我没有使用Tf-Idf,是因为它存在的一个严重缺陷是:假如一个词仅仅在某个类中出现过多次,那么其实该词是该类的一个非常好的特征,但根据Tf-Idf的机制,该词由于出现过太多次反而权重不高,在本次中,我目前使用的仅仅是词频,未来可能尝试其他方法。

向量化

所谓向量化,即对存在的词,每个词赋予其一个维度,然后对正负样本的每一行特征,按照其是否在特征向量中的某一维,决定该行特征是0还是非0。

我的做法是:

先将正负样本词库整合,并计算每个词出现的次数t,假设出现次数最大的词出现次数为max,每个词的权重即为t/max,导师建议使用每个维度的最大次数而非全局,之后可以试试看。构造正负样本矩阵并保存构造测试样本的矩阵,矩阵的权重来源于训练样本。

代码如下:

合并词库:

def merge_dict(pos_tag, neg_tag): """ Parameter ------- pos_tag: file of pos tag neg_tag: file of neg tags Return ----- mixed tags list """ words = [] with open(pos_tag, 'r') as pt: for line in pt: word = line.split() for t in word: words.append(t) with open(neg_tag, 'r') as nt: for line in nt: word = line.split() for t in word: words.append(t) tag_list = list(set(words)) print tag_list return tag_list

构造正负样本矩阵:

def get_libsvm_data(pos_tag, neg_tag, word_list, matrix_file): fmatrix = open(matrix_file, 'a+') with open(pos_tag, 'r') as pt: for line in pt: tag = [] word_flag = [] word = line.split() if len(word) == 0: continue word = list(set(word)) tag.append('+1') for t in word: p = word_list.index(t) word_flag.append(p) word_flag.sort() for t in word_flag: tag.append(' '+str(t)+':'+'1') mstr = ''.join(tag) fmatrix.write(mstr) fmatrix.write('\n') with open(neg_tag, 'r') as nt: for line in nt: tag = [] word_flag = [] word = line.split() if len(word) == 0: continue word = list(set(word)) tag.append('-1') for t in word: p = word_list.index(t) word_flag.append(p) word_flag.sort() for t in word_flag: tag.append(' '+str(t)+':'+'1') mstr = ''.join(tag) fmatrix.write(mstr) fmatrix.write('\n')

构造测试样本矩阵:

def shape_testdata(pos_test_tag, neg_test_tag, word_list, matrix_file): fmatrix = open(matrix_file, 'a+') with open(pos_test_tag, 'r') as pt: for line in pt: tag = [] last_flag = 0 # if the last has value word_flag = [] word = line.split() if len(word) == 0: continue word = list(set(word)) tag.append('+1') for t in word: if t in word_list: p = word_list.index(t) if p == len(word_list): last_flag = 1 word_flag.append(p) word_flag.sort() if len(word_flag) != 0: for t in word_flag: tag.append(' '+str(t)+':'+'1') if last_flag == 0: tag.append(' '+str(len(word_list))+':'+'0') mstr = ''.join(tag) fmatrix.write(mstr) fmatrix.write('\n') with open(neg_test_tag, 'r') as nt: for line in nt: tag = [] word_flag = [] last_flag = 0 word = line.split() if len(word) == 0: continue word = list(set(word)) tag.append('-1') for t in word: if t in word_list: p = word_list.index(t) if p==len(word_list): last_flag = 1 word_flag.append(p) word_flag.sort() if len(word_flag) != 0: for t in word_flag: tag.append(' '+str(t)+':'+'1') if last_flag == 0: tag.append(' '+str(len(word_list))+':'+'0') mstr = ''.join(tag) fmatrix.write(mstr) fmatrix.write('\n')

于是我们成功得到了训练样本和测试样本的矩阵,中间出现过一个bug是:训练样本和测试样本矩阵维度不同,这是由于记录时自动去除了值为0的维度,因此假如在测试样本中,未出现训练样本的末尾的维度,测试样本的维度将小于训练样本。改进是判断最后一维是否在测试样本中出现。未出现则注’0′

以下为矩阵格式(其实是libsvm的格式):

QQ截图20160309210229



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3