词袋模型(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’,)
将文本文档集合转换为词频计数矩阵
-
ngram_range : tuple (min_n, max_n):n-values值得上下界,默认是ngram_range=(1, *1),规定有多少的词的词组会被选择出来。
- ngram_range = (1,1) 有一个词的词组会被选出来
- ngram_range = (1,2) 有一个词的词组和有两个词的词组都会被选出来
- ngram_range = (2,2) 有两个词的词组会被选出来
-
token_pattern
正则表达式表示什么构成“标记”,仅在analyzer =='word'时使用。 默认正则表达式选择2个或更多字母数字字符的标记(标点符号完全被忽略,并始终被视为标记分隔符)。
- 正则表达式(缺)
analyzer 分析的依据,默认是按‘word’ 分析,也可以按‘char’单个字符分析
min_df 构建词汇表时,忽略频率严格低于给定阈值的单词。 该值也称为截止值。 如果是float,则参数表示单词在文档的比例,整数指绝对计数。
max_df 构建词汇表时,忽略频率严格高于给定阈值的单词。 该值也称为截止值。 如果是float,则参数表示单词在文档的比例,整数指绝对计数。
stop_words = ‘english’ 忽略常见单词
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高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
- TF-IDF实际上是:TF * IDF。
词频(Term Frequency,TF)
指的是某一个给定的词语在该文档中出现的频率。
即词w在文档d中出现的次数count(w, d)和文档d中总词数size(d)的比值。
这个数字是对词数(term count)的归一化,以防止它偏向长的文件。
(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)
逆向文件频率(Inverse Document Frequency,IDF)
是一个词语普遍重要性的度量。
某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。即文档总数n与词w所出现文件数docs(w, D)比值的对数。
TF-IDF
根据 tf 和 idf 为每一个文档d和由关键词w[1]…w[k]组成的查询串q计算一个权值,用于表示查询串q与文档d的匹配度
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的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值
-
smooth_idf
如果为 FALSE
如果为 TRUE
fit_transform()
输入的是 词频矩阵
返回的是 每个词组的tf-tdf 值矩阵
TfidfVectorizer
可以用 TfidfVectorizer 将 CountVectorizer 和 TfidfTransformer的活一起做了
- min_df 构建词汇表时,忽略频率严格低于给定阈值的单词。 该值也称为截止值。 如果是float,则参数表示单词在文档的比例,整数指绝对计数。
- max_df 构建词汇表时,忽略频率严格高于给定阈值的单词。 该值也称为截止值。 如果是float,则参数表示单词在文档的比例,整数指绝对计数。
- stop_words = ‘english’ 忽略常见单词
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 analysis,PCA)是一种分析、简化数据集的技术。
主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。
这是通过保留低阶主成分,忽略高阶主成分做到的。
sklearn.decomposition.PCA
(n_components=None, copy=True, whiten=False)
参数
-
n_components:
意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
属性
- components_ :返回各个 feature在 PCA 结果中的比重。
- explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。_
- 占所有特征的方差百分比越接近1,意味着几乎保留了所有的信息
- n_components_:返回所保留的成分个数n。
方法
-
fit
(X,)用X来训练PCA模型
-
fit_transform(X)
用X来训练PCA模型,同时返回降维后的数据。
newX=pca.fit_transform(X),newX就是降维后的数据。
生成数据
%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