当前位置:   article > 正文

文本分类特征的选取_文本分类特征选择

文本分类特征选择

一、基本概念

  • 自然语言处理(NLP)
  • 策略、机器学习(深度学习)相比较
    基于策略的文本分类方法要求我们得尽量搞清楚影响问题的所有因素的细节,如果问题越来越复杂,手动地制定规则就变得非常困难;机器学习和深度学习可以从样本中学习到更加深层次的内容(知识,规则),同时我们可以通过调整特征和参数不断优化模型的效果。
  • 精确率、准确率、召回率

二、文本特征选取

文本处理的第一步一般是要做分词(也有部分文本处理算法不需要做分词,这里不做讨论),这里介绍两个分词工具,其中最常用的是jieba,两者有很多相似的地方。

  1. 中文分词:将中文句子分割为多个词语就是中文分词
    jieba分词,支持自定义词典,是对自带词典的补充;支持基于TF-IDF算法和TextRank算法的关键词抽取;支持词性标注
    HanLP,与jieba相比,支持简繁转换,支持拼音转换,支持自定义分词模型,支持语义距离分析,特定情况下分词速度和效果更好,配套书籍《自然语言处理入门》
  2. 在分词后将中文句子转换问多个词语的序列,这一步需要做特征提取,将文本转换为模型可以使用的数据
    • one-hot编码:将一个词语转换为仅有1位是1,其他位全是0的向量,向量的长度是词表的长度,词表可以自定义,也可以使用分词工具中的词表,常用的汉语词汇大约在10W这个等级,也就是向量的维度
    • 词袋模型:对于一条文本,每个单词都收入一个词袋中并计数,为了能比较不同长度的文本,因此词袋中的词出现的频率要做正则化。用的方法叫TF-IDF,也就是词出现的频率要乘以词的权重,这样就能统一比较不同长度的文本了。
    • TF-IDF:TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率较高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
      one-hot编码和词袋模型只保留了词和词频的信息,而丢掉了词的位置信息,而词的位置和文本的意义有很大关系
    • Word2VecWord2vec只关心模型训练完后的副产物——模型参数(这里特指神经网络的权重),并将这些参数,作为输入 x 的某种向量化的表示,这个向量便叫做——词向量,其中的 x 是one-hot编码,模型指的是以下之一:
      • 如果是用一个词语作为输入,来预测它周围的上下文,那这个模型叫做『Skip-gram 模型』
      • 而如果是拿一个词语的上下文作为输入,来预测这个词语本身,则是 『CBOW 模型』
    • 词向量的维度(与隐含层节点数一致)一般情况下要远远小于词语总数 V 的大小,所以 Word2vec 本质上是一种降维操作——把词语从 one-hot encoder 形式的表示降维到 Word2vec 形式的表示。
    • 词向量可以自行训练,但是一般不建议,因为需要很大的工作量,可以使用训练好的词向量:Chinese Word Vectors 中文词向量
      # 使用上述训练好的词向量模型做测试
      import gensim
      BAIKE_VEC = 'resource/baike.vectors.bin'
      w2v_model = gensim.models.KeyedVectors.load_word2vec_format(BAIKE_VEC, binary=True)
      # 打印和“南京”相似的前3个词及其相似度
      print(w2v_model.similar_by_word("南京", topn=3))
      # 结果
      [('苏州', 0.8196749687194824), ('无锡', 0.7864724397659302), ('常州', 0.7753453850746155)]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 词向量在文本分类中的使用:如何用 word2vec 计算两个句子之间的相似度?

三、分类方法实践

  1. 朴素贝叶斯、支持向量机
    上述两种模型使用的都是python的sklearn库:scikit-learn (sklearn) 官方文档中文版
    以下是两种模型的示例代码:
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.metrics import confusion_matrix,classification_report
import numpy as np

# 每条文本为一行,分词之间以空格分割,多行文本组成一个list,get_file是自定义函数
train_text = np.asarray(get_file(TRAIN_DATA))
train_label = np.asarray(get_file(TRAIN_LABEL)
test_text = np.asarray(get_file(TEST_DATA))
test_label = np.asarray(get_file(TEST_LABEL))

# 特征数值计算类,可以使用自定义的词表,也可以使用训练数据生成词表
count_v0 = CountVectorizer()
# 判断CountVectorizer的词表是否为空,为空则生成词表,并使用词表将训练文本转化为词频
counts_train = count_v0.fit_transform(train_text)
# 使用已有的词表将测试文本转化为词频
counts_test = count_v0.transform(test_text)

# 将词频转化为Tf-idf
tfidftransformer = TfidfTransformer()
# fit会计算训练文本中所有词的idf,并存储
train_data = tfidftransformer.fit_transform(counts_train)
# 这里用transform处理测试文本,其中会直接使用训练数据的idf
test_data = tfidftransformer.transform(counts_test)

# 多项式朴素贝叶斯
clf = MultinomialNB(alpha=0.01)
clf.fit(train_data, train_label)
pred = clf.predict(test_data)
preds = pred.tolist()

# 模型效果评价:计算并打印混淆矩阵
c_matrix = confusion_matrix(test_label, preds)
for i in c_matrix:
    print(i)
report = classification_report(test_label, preds)
print(report)

# svm
svclf = SVC(kernel='linear', class_weight='balanced')
svclf.fit(train_data, train_label)
pred = svclf.predict(test_data)
preds = pred.tolist()

# 模型效果评价:计算并打印混淆矩阵
c_matrix = confusion_matrix(test_label, preds)
for i in c_matrix:
    print(i)
report = classification_report(test_label, preds)
print(report)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

精确率和召回率是一对矛盾的向量,通常在一些简单的任务中才可能使查全率和查准率都很高。精确率、召回率、F1计算

  1. 训练集和测试集的划分:留出法、交叉验证法、自助法
    为了将样本数据划分为训练集和测试集,同时避免样本数据分布不均衡,需要使用合理的划分方法,这里使用交叉验证法。
    交叉验证法是将样本数据划分为k个大小相同的子集,每次选取其中k-1个作为训练集,剩下的一个作为测试集,一般取k=10,称为10折交叉验证。
    可以使用sklearn中的StratifiedKFold实现:模型选择和评估
from sklearn.model_selection import StratifiedKFold
# 10折交叉验证
skf = StratifiedKFold(n_splits=9)
for train_index, test_index in skf.split(vect, label):
    print("train_index: ",train_index.shape)
    print("test_index: ",test_index.shape)
    x_train, x_test = vect[train_index], vect[test_index]
    y_train, y_test = label[train_index], label[test_index]
    model_train(x_train, y_train, x_test, y_test)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 二分类/多分类
    以上代码中的MultinomialNB和SVC实现的都是二分类算法,类似的也可以使用二分类组合实现多分类:二分类实现多分类的两种思路
    sklearn中的多分类也是基于以上思想实现的,无论是one-versus-rest还是one-versus-one都有其固有的缺点,具体实践中需要评估。
    多分类效果的评价也可以使用sklarn:sklearn的多分类模型评价指标
  2. 数据不平衡问题
    机器学习中常常会遇到数据的类别不平衡(class imbalance),也叫数据偏斜(class skew)。以常见的二分类问题为例,当正类和负类差距很大时,就是数据不平衡问题,对待不平衡问题一般有三中处理方法:过采样、欠采样和阈值调整:如何处理数据中的「类别不平衡」?
    欠采样(undersampling)和过采样(oversampling)会对模型带来怎样的影响?
  3. 尝试xgboost模型
    使用过采样(或SMOTE)+强正则模型(如XGBoost)可能比较适合不平衡的数据。拿到一个新的数据时,可以不妨直接先试试这个方法,作为基准(Baseline)。
  4. 异常数据识别
    一般可以将异常检测看成是数据不平衡下的分类问题。
    数据挖掘中常见的「异常检测」算法有哪些?
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/350061
推荐阅读
相关标签
  

闽ICP备14008679号