文本分类(二)文本数据数值化,向量化,降维

文本分类大体被我分为4类,链接如下:
文本分类流程(一)文本分类的大致步骤+数据预处理------毕业论文的纪念
文本分类(二)文本数据数值化,向量化,降维
文本分类(三)–对已经处理好的数据使用KNN、Naive Bayes、SVM分类方法
文本分类(四)–分类好坏的评价

文章目录

  • 前言
  • ==3.文本数据转化为数值向量==
    • 1.CounterVectorizer---one hot矩阵
      • 举例子:
      • 傻瓜解释:
    • 2. TfidfVectorizer---one hot 矩阵的变换
      • 一个例子:
      • 综合对比两者 Counter VS TFIDF
    • 3.Word2Vec
  • 三者之间的差异与联系
  • 数据降维
    • 利用max_feature来进行维度的控制
    • 利用pca降维

前言

上面一篇博客文本分类流程(一)文本分类的大致步骤+数据预处理------毕业论文的纪念已经讲述了文本处理中的两个步骤,网页获取+数据清洗,得到了干净的文本数据。
下面开始介绍如何将我们能够识别的文本数据转化为机器可以识别的数值数据(向量)
首先看看这篇文章了解一下特征选择于特征提取的大致内容文本分类入门(番外篇)特征选择与特征权重计算的区别

我们知道机器能够对数值数据使用各种公式,它只能够识别这些,所以我们就开始着手将我们所获取到的文本数据转化为数值数据
以下简单的介绍一些我所知道的三种文本数据数值向量化的方法

3.文本数据转化为数值向量

1.CounterVectorizer—one hot矩阵

在学习概率论的时候,我们不管将大自然中的什么东西变成我们所能够研究的东西,首先都是先统计构成样本空间中的所有元素得到样本元素的频率表示,简单来讲就是计数而已。现在我们将其推广到文本数值化上面来就是:使用split函数将用空格连接的文本数据分开,每个文本我们都会得到一个列表,构成词典,在第一个样本中,统计其中的包含于字典的每个元素出现的次数,这就是CounterVectorizer的文本向量化的原理。
eg. comment1=comments[0]=[element1,element2,…,element_nm_i]
设样本容量为n,第i个样本中含有m_i个元素。
所有元素构成的字典(是字典的形式,但是这里我们使用列表来存储)为:dict = {elem1,elem2,…elem_N} 设字典中的元素个数为N,注:字典中的所有元素是不重复的。

举例子:

from sklearn.feature_extraction.text import CountVectorizer
corpus = [
        'This is the first document.',
        'This document is the second document.',
        'And this is the third one.',
        'Is this the first document?',
    ]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
# ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
print(X.toarray())  # doctest: +NORMALIZE_WHITESPACE
# [[0 1 1 1 0 0 1 0 1]
#     [0 2 0 1 0 1 1 0 1]
#     [1 0 0 1 1 0 1 1 1]
#     [0 1 1 1 0 0 1 0 1]]

傻瓜解释:

字典的长度就是每个样本的维度,所有样本的维度一致。样本的每个维度都代表着相应字典中的元素在每一个具体的样本中出现的频率。对应到具体的例子,This is the first document. 可以看到字典的顺序是[‘and’, ‘document’, ‘first’, ‘is’, ‘one’, ‘second’, ‘the’, ‘third’, ‘this’],将其一一对应起来,and不出现,频率是0,document出现,频率是1…this出现,频率是1。这样一个文本数据就可以转变成数值向量啦。这样一一对应的关系我们可以简单的理解为数学上面的映射,将字典中的元素映射到N+正整数域上面来,
字典(文本数据)---->正整数(数值数据)(0,1,2,…)

2. TfidfVectorizer—one hot 矩阵的变换

与2不同,tf-idf主要使用的是逆文档频率,具体计算可以自己百度,csdn看别人的解释。简单来讲,我们认为在一个文档中出现次数越小的越能够代表一个文档,相反,一个元素在文档中频繁存在的文本的文本所拥有的权重就越小,越不能够代表一个文档。

一个例子:

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
        'This is the first document.',
        'This document is the second document.',
        'And this is the third one.',
        'Is this the first document?',
    ]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus) # 拟合并且转化文本
print(vectorizer.get_feature_names()) # 输出特征字典
# ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
print(X.shape) # 输出文本的维数,4行9列,每个文本的的维度为9,与上面的特征数量的长度相同
# (4, 9)
print(X.toarray()) # 将文本数据向量化--是9维数据
# [[0.         0.46979139 0.58028582 0.38408524 0.         0.
#   0.38408524 0.         0.38408524]
#  [0.         0.6876236  0.         0.28108867 0.         0.53864762
#   0.28108867 0.         0.28108867]
#  [0.51184851 0.         0.         0.26710379 0.51184851 0.
#   0.26710379 0.51184851 0.26710379]
#  [0.         0.46979139 0.58028582 0.38408524 0.         0.
#   0.38408524 0.         0.38408524]]

综合对比两者 Counter VS TFIDF

TfidfTransformer+CounterVectorizer=tfidfVectorizer

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
        'This is the first document.',
        'This document is the second document.',
        'And this is the third one.',
        'Is this the first document?',
    ]

# method1 TfidfTransformer+CounterVectorizer=tfidfVectorizer
from sklearn.feature_extraction.text import TfidfTransformer,CountVectorizer
vectorizer = CountVectorizer() # 先使用频率表示法
transformer = TfidfTransformer() # 再使用tdif进行逆文档频率转换
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
print(tfidf.toarray()) # 输出数值化之后的矩阵

# method2 直接使用TfidfVectorizer
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus) # 拟合并且转化文本
print(vectorizer.get_feature_names()) # 输出特征字典
# ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
print(X.shape) # 输出文本的维数,4行9列,每个文本的的维度为9,与上面的特征数量的长度相同
# (4, 9)
print(X.toarray())
# [[0.         0.46979139 0.58028582 0.38408524 0.         0.
#   0.38408524 0.         0.38408524]
#  [0.         0.6876236  0.         0.28108867 0.         0.53864762
#   0.28108867 0.         0.28108867]
#  [0.51184851 0.         0.         0.26710379 0.51184851 0.
#   0.26710379 0.51184851 0.26710379]
#  [0.         0.46979139 0.58028582 0.38408524 0.         0.
#   0.38408524 0.         0.38408524]]

参考:
文本挖掘预处理指TF-IDF
scikit-learn:CountVectorizer提取tf都做了什么
python 利用sklearn自带的模块 快速简单实现文章的 tfidf向量空间的表示
sklearn文本特征提取
关键词抽取

3.Word2Vec

将一个词语的前后单词(2/3/more个单词)连接在一起,当作一个新的元素,存放在字典中,之后用的方法就跟counterVectorizer和tfidfVectorizer差不多了
在我的论文中只是简单地了解了一下,最后内容实在是太多就没有将这个文本数据向量化的方法与前两者进行比较,学有余力的可以对比看看,这么文本向量化会对以后的分类效果产生什么样的影响。
具体看的参考资料:
通俗理解word2vec
word2vec构建中文词向量
Word2vec基础介绍(四):CBOW和skip-gram模型
word2vec词向量原理并实践
python进行文本分类,基于word2vec,sklearn-svm对微博垃圾评论分类

三者之间的差异与联系

12所使用的字典是一样的。
3使用的词典较大一些。
不过从本质上来讲,三者都是基于词典,利用频率这个基础将文本数据转化为数值向量。

数据降维

我所知道并且使用的有两种方法,当然还有其他的方法,如LDA等。自己去探索罢。
就我自己从专业课上面写学习到的,有LDA ,PCA , 因子分析,SVD。

利用max_feature来进行维度的控制

在sklearn文本特征提取中有介绍一个参数:max_features,将这个参数设置维你想要控制的维度,这里我设置为200.
countervectorizer和tfidfvectorizer都有这个参数,可以实现维度控制。

利用pca降维

sklearn中PCA的使用方法这里面有介绍pca的简单用法。
注意:使用pca降维数据,之前要将数据标准化用sklearn 实践PCA降维这个例子不是很完成,主要举它是想说明在利用pca降维之前对于数据预处理对数据标准化的重要性
这个[代码分析] 使用sklearn PCA对特征数据降维讲的可以,是我想要的样子。PCA降维的原理及步骤很好,简单,满意。

关于标准化:
数据归一化 - MinMaxScaler()/MaxAbsScaler() - Python代码
【原】关于使用sklearn进行数据预处理 —— 归一化/标准化/正则化

数值向量化,预处理的代码
data_preprocessed_final.py

"""
数据初始处理
1、将原来处理好的评论转换成能够被数值化处理的形式
2、数值化处理
3、将样本数据切分为训练集与样本集,同样对class处理
4、数据标准化
5、主成分降维
"""
def get_preprocessed(): 
    max_f = 200  
    import re
    from last_process_2 import noStopWord_comments,noStopWord_class
    from sklearn.feature_extraction.text import TfidfVectorizer,CountVectorizer # 向量化的类方法
    from sklearn.decomposition import PCA # 主成分方法
    from sklearn.model_selection import train_test_split # 切割数据---train + test
    from sklearn import preprocessing # 结果评估
    # 将开始的字符串用空格隔开
    def get_split(x):
        temp = [v for v in re.split(' ',x) if v is not '']
        return temp
    def joinData(data_to_join):# 空字符串将文本隔开
        temp = [' '.join(x) for x in data_to_join]
        return temp    
    corpus = joinData([get_split(v) for v in noStopWord_comments]) # 得到的是一个列表
    tfidf = TfidfVectorizer() # 继承类方法
    retfidf = tfidf.fit_transform(corpus) # 拟合,将corpus转化为数值向量 
    input_data_matrix = retfidf.toarray() # 得到的矩阵

    # 切割数据 train: 0.8, test: 0.2
    x_train,x_test,y_train,y_test=train_test_split(input_data_matrix,noStopWord_class,test_size=0.2,random_state=400)
    # 将上面的数据标准化处理
    # -----------------------
    # stander=preprocessing.StandardScaler()
    # x_train = stander.fit_transform(x_train)
    # x_test = stander.transform(x_test)
    max_min=preprocessing.MinMaxScaler()
    x_train = max_min.fit_transform(x_train)
    x_test = max_min.fit_transform(x_test)
    # ---------------------
    # 主成分降维
    pca = PCA(n_components=max_f)
    x_train,x_test = pca.fit_transform(x_train),pca.transform(x_test)
    return x_train,x_test,y_train,y_test 

这样一段下来,特征工程的相关工作就完成啦。接下来的步骤就快了,讲我们降维得到的数据输入到分类其中进行训练,测试,评估,我的论文也就这样完成了。
指路,下一节文本分类(三)–对已经处理好的数据使用KNN、Naive Bayes、SVM分类方法

你可能感兴趣的:(文本分类,机器学习,python)