sklearn.feature_extraction.text中常见 Vectorizer 使用方法以及Tf–idf 值获取

对于在tf-idf进行关键字提取的过程中,Scikit-learn提供了TFIDF算法的相关函数,本文主要用到了sklearn.feature_extraction.text下的TfidfTransformer和CountVectorizer函数。其中,CountVectorizer函数用来构建语料库的中的词频矩阵,TfidfTransformer函数用来计算词语的tfidf权值。

本部分参考自:http://sklearn.apachecn.org/#/docs/39?id=_52-%e7%89%b9%e5%be%81%e6%8f%90%e5%8f%96

模块 sklearn.feature_extraction 可用于提取符合机器学习算法支持的特征,比如文本和图片

文本分析是机器学习算法的主要应用领域。 然而,原始数据,符号文字序列不能直接传递给算法,因为它们大多数要求具有固定长度的数字矩阵特征向量,而不是具有可变长度的原始文本文档。

为解决这个问题,scikit-learn提供了从文本内容中提取数字特征的最常见方法,即:

  • 令牌化(tokenizing) 对每个可能的词令牌分成字符串并赋予整数形的id,例如通过使用空格和标点符号作为令牌分隔符。
  • 统计(counting) 每个词令牌在文档中的出现次数。
  • 标准化(normalizing) 在大多数的文档 / 样本中,可以减少重要的次令牌的出现次数的权重。。

在该方案中,特征和样本定义如下:

  • 每个单独的令牌发生频率(归一化或不归零)被视为一个特征
  • 给定文档中所有的令牌频率向量被看做一个多元sample样本

因此,文本的集合可被表示为矩阵形式,每行对应一条文本,每列对应每个文本中出现的词令牌(如单个词)。

我们称向量化是将文本文档集合转换为数字集合特征向量的普通方法。 这种特殊思想(令牌化,计数和归一化)被称为 Bag of Words 或 “Bag of n-grams” 模型。

稀疏

由于大多数文本文档通常只使用文本词向量全集中的一个小子集,所以得到的矩阵将具有许多特征值为零(通常大于99%)。

例如,10,000 个短文本文档(如电子邮件)的集合将使用总共100,000个独特词的大小的词汇,而每个文档将单独使用100到1000个独特的单词。

为了能够将这样的矩阵存储在存储器中,并且还可以加速代数的矩阵/向量运算,实现通常将使用诸如 scipy.sparse 包中的稀疏实现。

类 CountVectorizer 在单个类中实现了 tokenization (词语切分)和 occurrence counting (出现频数统计):

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
help(vectorizer)

text=['李明非常喜欢北京天安门',
        '西安是一个十三朝古都的国际化大都市',
        '杨康是长安大学信息工程学院的一名研究生',
        '郭靖是西安邮电大学计算机学院的一名大学生'
       ]
corpus = []
for t in text:
    seg_text=[]
    # 定义选取的词性
    #pos = ['n', 'nz', 'v', 'vd', 'vn', 'l', 'a', 'd']  
    # 分词
    seg = jieba.posseg.cut(t) 
    jieba.add_word("长安大学")
    jieba.add_word("西安邮电大学")
    jieba.add_word("信息工程学院")
    jieba.add_word("计算机学院")
    # 停用词
    stopkey = [w.strip() for w in codecs.open('H:/GitHub项目/关键词提取/data/stopWord.txt', 'r', encoding="utf-8").readlines()]
    for i in seg:
        #if i.word not in stopkey and i.flag in pos:  # 去停用词 + 词性筛选
        if i.word not in stopkey:
            seg_text.append(i.word)
    corpus.append(seg_text)

corpus

[['李明', '喜欢', '北京', '天安门'],
 ['西安', '一个', '十三', '古都', '国际化', '大都市'],
 ['杨康', '长安大学', '信息工程学院', '一名', '研究生'],
 ['郭靖', '西安邮电大学', '计算机学院', '一名', '大学生']]

注意此时出现了一个错误!!!corpus格式必须为:

X = vectorizer.fit_transform(corpus)
X

'''
输出:
<4x13 sparse matrix of type '<class 'numpy.int64'>'
	with 20 stored elements in Compressed Sparse Row format>
'''

X.toarray()  
'''
输出:a[i][j]表示词语j(词语的索引号)在文本i中出现的频数
array([[0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
       [1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0],
       [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0],
       [0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1]], dtype=int64)

'''

vectorizer.vocabulary_.get('北京天安门')
'''
输出“北京天安门”的索引号id:2
'''

vectorizer.get_feature_names()
'''
输出:语料库中的词语按序排列的字典
['一个','一名','北京天安门','十三','古都','喜欢','国际化','大学生','大都市','李明','杨康','西安','郭靖']
'''

vectorizer.transform(['城墙 赛格 永宁门']).toarray()
'''
输出:对于没有出现在上面13个预料中的词语,将会被直接忽略
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int64)
'''

 TF-IDF

from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)

# 统计词袋模型中的每个词的tf-idf权值
print(tfidf)

  (0, 9)	0.7266414923403136
  (0, 5)	0.3791916749655464
  (0, 2)	0.5728924988566925
  (1, 11)	0.3247514870272976
  (1, 8)	0.41190608298099013
  (1, 6)	0.41190608298099013
  (1, 5)	0.21494968176261076
  (1, 4)	0.41190608298099013
  (1, 3)	0.41190608298099013
  (1, 0)	0.41190608298099013
  (2, 11)	0.4451321885325025
  (2, 10)	0.5645937386324167
  (2, 7)	0.4451321885325025
  (2, 5)	0.29462843463227384
  (2, 1)	0.4451321885325025
  (3, 12)	0.5645937386324167
  (3, 7)	0.4451321885325025
  (3, 5)	0.29462843463227384
  (3, 2)	0.4451321885325025
  (3, 1)	0.4451321885325025

tfidf.toarray()
array([[0.        , 0.        , 0.5728925 , 0.        , 0.        ,
        0.37919167, 0.        , 0.        , 0.        , 0.72664149,
        0.        , 0.        , 0.        ],
       [0.41190608, 0.        , 0.        , 0.41190608, 0.41190608,
        0.21494968, 0.41190608, 0.        , 0.41190608, 0.        ,
        0.        , 0.32475149, 0.        ],
       [0.        , 0.44513219, 0.        , 0.        , 0.        ,
        0.29462843, 0.        , 0.44513219, 0.        , 0.        ,
        0.56459374, 0.44513219, 0.        ],
       [0.        , 0.44513219, 0.44513219, 0.        , 0.        ,
        0.29462843, 0.        , 0.44513219, 0.        , 0.        ,
        0.        , 0.        , 0.56459374]])
# 获取到词袋模型的词语们及其tf-idf值
words = vectorizer.get_feature_names()
weights = tfidf.toarray()


# 选取每个文本的前俩个关键词进行输出
keys = []
for i in range(len(weight)):
    print(u"-------这里输出第", i+1 , u"篇文本的词语及其tf-idf------")
    print(words)
    print(weights[i])
    # 当前文章的所有词汇列表、词汇对应权重列表
    df_word,df_weight = [],[] 
    for j in range(len(word)):
        #print(word[j],weight[i][j])
        df_word.append(word[j])
        df_weight.append(weight[i][j])
    df_word = pd.DataFrame(df_word,columns=['word'])
    df_weight = pd.DataFrame(df_weight,columns=['weight'])
    # 拼接词汇列表和权重列表
    word_weight = pd.concat([df_word, df_weight], axis=1)
    # 按照权重值降序排列
    word_weight = word_weight.sort_values(by="weight",ascending = False) 
    # 选择词汇列并转成数组格式
    keyword = np.array(word_weight['word']) 
    # 抽取前topK个词汇作为关键词
    word_split = [keyword[x] for x in range(0,2)] 
    word_split = " ".join(word_split)
    keys.append(word_split)
keys
发布了92 篇原创文章 · 获赞 23 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Pit3369/article/details/95643392