词袋模型

2019-07-26  本文已影响0人  Bounty_Hunter

词袋模型(Bag of words,简称 BoW )

词袋模型假设我们不考虑文本中词与词之间的上下文关系,仅仅只考虑所有词的权重。而权重与词在文本中出现的频率有关。

词袋模型首先会进行分词,在分词之后,通过统计每个词在文本中出现的次数,我们就可以得到该文本基于词的特征,如果将各个文本样本的这些词与对应的词频放在一起,就是我们常说的向量化。向量化完毕后一般也会使用 TF-IDF 进行特征的权重修正,再将特征进行标准化。 再进行一些其他的操作后,就可以将数据带入机器学习模型中计算。

词袋模型的三部曲:分词(tokenizing),统计修订词特征值(counting)与标准化(normalizing)。

词袋模型有很大的局限性,因为它仅仅考虑了词频,没有考虑上下文的关系,因此会丢失一部分文本的语义。

在词袋模型统计词频的时候,可以使用 sklearn 中的 CountVectorizer 来完成。

词频向量化

CountVectorizer 类会将文本中的词语转换为词频矩阵,例如矩阵中包含一个元素a[i][j],它表示j词在i类文本下的词频。它通过 fit_transform 函数计算各个词语出现的次数,通过get_feature_names()可获取词袋中所有文本的关键字,通过 toarray()可看到词频矩阵的结果。

程序将corpus生成了一个字典,如feature_name,而 X_txt 则是把corpus里面的每一行根据字典生成了词频向量。

sklearn.feature_extraction.text.CountVectorizer

(token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’,)

将文本文档集合转换为词频计数矩阵

fit_transform

(raw_documents)

学习词汇并返回词频矩阵

get_feature_names()

返回学习到的词组组成的 list

build_analyzer()

返回一个完成预处理和分词操作的句柄

from sklearn.feature_extraction.text import CountVectorizer 
vectorizer = CountVectorizer(min_df = 2, max_df = 0.5 , stop_words = 'english' )

corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
]

X_txt = vectorizer.fit_transform(corpus)
feature_name = vectorizer.get_feature_names()
print(X_txt)
print(feature_name)
print (X_txt.toarray())

结果:

(0, 1)  1
  (0, 2)    1
  (0, 6)    1
  (0, 3)    1
  (0, 8)    1
  (1, 5)    2
  (1, 1)    1
  (1, 6)    1
  (1, 3)    1
  (1, 8)    1
  (2, 4)    1
  (2, 7)    1
  (2, 0)    1
  (2, 6)    1
  (3, 1)    1
  (3, 2)    1
  (3, 6)    1
  (3, 3)    1
  (3, 8)    1
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
[[0 1 1 1 0 0 1 0 1]
 [0 1 0 1 0 2 1 0 1]
 [1 0 0 0 1 0 1 1 0]
 [0 1 1 1 0 0 1 0 1]]

左边的括号中的第一个数字是文本的序号i,第2个数字是词的序号j,第三个数字就是我们的词频。

因此词向量中有大量的0,也就是说词向量是稀疏的。因此在实际应用中一般使用稀疏矩阵来存储。

上面提取的特征全部都是单个词,同样可以提取连词

提取连词 需要 让参数 ngram_range=(2, 2)

bigram_vectorizer = CountVectorizer(ngram_range=(2, 2), token_pattern=r'\b\w+\b', min_df=1)

analyze = bigram_vectorizer.build_analyzer()
print(analyze('believe or not a b c d e'))

TF-IDF

在较低的文本语料库中,一些词非常常见(例如,英文中的“the”,“a”,“is”),因此很少带有文档实际内容的有用信息。如果我们将单纯的计数数据直接喂给分类器,那些频繁出现的词会掩盖那些很少出现但是更有意义的词的频率。

为了重新计算特征的计数权重,以便转化为适合分类器使用的浮点值,通常都会进行tf-idf转换。

TF-IDF(Term Frequency–Inverse Document Frequency)

是一种用于资讯检索与文本挖掘的常用加权技术。

TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。

主要思想:

如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

词频(Term Frequency,TF)

指的是某一个给定的词语在该文档中出现的频率。

即词w在文档d中出现的次数count(w, d)和文档d中总词数size(d)的比值。
tf(w,d) = count(w, d) / size(d)
这个数字是对词数(term count)的归一化,以防止它偏向长的文件。

(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)

逆向文件频率(Inverse Document Frequency,IDF)

是一个词语普遍重要性的度量。

某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。即文档总数n与词w所出现文件数docs(w, D)比值的对数。
idf = log( \frac{n}{docs(w, D) + 1})

TF-IDF

根据 tf 和 idf 为每一个文档d和由关键词w[1]…w[k]组成的查询串q计算一个权值,用于表示查询串q与文档d的匹配度
tf-idf(q, d) = \sum_{i=1}^{k} { tf-idf(w[i], d) } = \sum_{i=1}^{n} { tf(w[i], d) * idf(w[i]) }
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

在IDF中可以发现,当某个词在语料库中各个文档出现的次数越多,它的IDF值越低,当它在所有文档中都出现时,其IDF计算结果为0,而通常这些出现次数非常多的词或字为“的”、“我”、“吗”等,它对文章的权重计算起不到一定的作用。

sklearn.feature_extraction.text.TfidfTransformer

(norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)

TfidfTransformer用于统计vectorizer中每个词语的TF-IDF值

fit_transform()

输入的是 词频矩阵

返回的是 每个词组的tf-tdf 值矩阵

TfidfVectorizer

可以用 TfidfVectorizer 将 CountVectorizer 和 TfidfTransformer的活一起做了

from sklearn.feature_extraction.text import TfidfVectorizer 
vectorizer = TfidfVectorizer()
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
]
#print(corpus)
X_txt_3 = vectorizer.fit_transform(corpus)
print(X_txt_3.toarray())

PCA 模型

主成分分析(英语:Principal components analysisPCA)是一种分析、简化数据集的技术。

主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。

这是通过保留低阶主成分,忽略高阶主成分做到的。

sklearn.decomposition.PCA

(n_components=None, copy=True, whiten=False)

参数

属性

方法

生成数据

%matplotlib inline
from scipy.stats import multivariate_normal
import numpy as np
import matplotlib.pyplot as plt

# Generate some data with two features (2D)

means = [0, 0]
cov = np.matrix([ [1, 0.5], [0.5, 1] ])

X = multivariate_normal.rvs(mean = means, cov = cov, size = 1000)

plt.scatter(X[:,0], X[:,1], alpha = 0.4)

plt.show()

调用PCA 降维

# 降至1维
pca = PCA(n_components=1)
pca.fit(X)
T_small = pca.transform(X)


# 画图
plt.scatter(T_small, np.zeros(len(T_small)), alpha = 0.1)

plt.show()

选择PCA维度

画n-总方差图

先对数据正则化,使用 PCA 处理数据

import pandas as pd

br_df = pd.read_excel("BatonRouge.xls")

X = br_df[ br_df.columns.difference(['Price']) ]

# Standardisation. Very important!
X = (X - X.mean()) / X.std()

pca = PCA()

pca.fit(X)

画出 维度-方差和 图

一般选择保留 80 % 方差

cum_var = np.cumsum(pca.explained_variance_ratio_) * 100

print(cum_var)

plt.plot(np.arange(1, 11), cum_var, marker = "o")

plt.xlabel("Number of Components")
plt.ylabel("Variance")

plt.title("Scree Plot (Number of Components vs Variance)")

plt.show()

Elbow 法

画出 维度 - explained_variance_ratio 图

选择变化率最大处的维度

主成分权重的可视化

根据 PCA 的 components_ 属性,可视化各个feature 在 PCA 结果中的权重

first_component_weights = pd.DataFrame({'Weight': pca.components_[0], 'Feature': X.columns})

first_component_weights = first_component_weights.sort_values('Weight')

first_component_weights

上一篇下一篇

猜你喜欢

热点阅读