本文介绍了四个方面的内容:
(1)TF-IDF的含义和使用方法
(2)CountVectorizer与TfidfVectorizer使用区别
(3)TF-IDF的两种实现方法
(4)TF-IDF使用的局限性
下面来逐一介绍:
(1)TF-IDF的基本含义
首先介绍一下TF-IDF基本含义:
TF-IDF介绍
TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了TF-IDF以外,互联网上的搜索引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。
TF
TF: Term Frequency, 用于衡量一个词在一个文件中的出现频率。因为每个文档的长度的差别可以很大,因而一个词在某个文档中出现的次数可能远远大于另一个文档,所以词频通常就是一个词出现的次数除以文档的总长度,相当于是做了一次归一化。
TF(t) = (词t在文档中出现的总次数) / (文档的词总数)。
IDF
IDF: 逆向文件频率,用于衡量一个词的重要性。计算词频TF的时候,所有的词语都被当做一样重要的,但是某些词,比如”is”, “of”, “that”很可能出现很多很多次,但是可能根本并不重要,因此我们需要减轻在多个文档中都频繁出现的词的权重。
ID(t) = log_e(总文档数/词t出现的文档数)。
举例说明:
def TL():
allurls = './data/data.csv' #path to our all urls file
allurlscsv = pd.read_csv(allurls,',',error_bad_lines=False) #reading file
allurlsdata = pd.DataFrame(allurlscsv) #converting to a dataframe ###数据格式化
allurlsdata = np.array(allurlsdata) #converting it into an array
np.random.shuffle(allurlsdata) #shuffling ####随机排序,注意此处不可写成random.shuffle(allurlsdata) 详情可以参照我的另外一篇博客专门讲两者的区别https://blog.csdn.net/Homewm/article/details/84671603
y = [d[1] for d in allurlsdata] #all labels ###所有的标签
corpus = [d[0] for d in allurlsdata] #all urls corresponding to a label (either good or bad) ###所有的url
vectorizer = TfidfVectorizer(tokenizer=getTokens) #get a vector for each url but use our customized tokenizer
##特征提取
X = vectorizer.fit_transform(corpus) #get the X vector
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) #split into training and testing set 80/20 ratio
lgs = LogisticRegression() #using logistic regression
lgs.fit(X_train, y_train)
print(lgs.score(X_test, y_test)) #pring the score. It comes out to be 98%
return vectorizer, lgs ###返回向量和模型
(2)CountVectorizer与TfidfVectorizer区别
当然有的时候我我们也会使用Scikit-learn 的CountVectorizer,那么它与TfidfVectorizer有什么区别呢?
CountVectorizer与TfidfVectorizer,这两个类都是特征数值计算的常见方法。对于每一个训练文本,CountVectorizer只考虑每种词汇在该训练文本中出现的频率,而TfidfVectorizer除了考量某一词汇在当前训练文本中出现的频率之外,同时关注包含这个词汇的其它训练文本数目的倒数。相比之下,训练文本的数量越多,TfidfVectorizer这种特征量化方式就更有优势。
CountVectorizer这个类的主要作用是统计每一个训练文本中,每个单词出现的频率;然后构成一个特征矩阵,每一行表示一个训练文本的词频统计结果。其思想是,先根据所有训练文本,不考虑其出现顺序,只将训练文本中每个出现过的词汇单独视为一列特征,构成一个词汇表(vocabulary list),该方法又称为词袋法(Bag of Words)。
使用过程和TF-IDF差不多,代码如下:
def TL():
allurls = 'all_url_label.csv' #path to our all urls file
allurlscsv = pd.read_csv(allurls,',',error_bad_lines=False) #reading file
allurlsdata = pd.DataFrame(allurlscsv) #converting to a dataframe ###数据格式化
allurlsdata = np.array(allurlsdata) #converting it into an array
np.random.shuffle(allurlsdata) #shuffling ####随机排序
y = [d[1] for d in allurlsdata] #all labels ###所有的标签
corpus = [d[0] for d in allurlsdata] #all urls corresponding to a label (either good or bad) ###所有的url
# vectorizer = TfidfVectorizer(tokenizer=getTokens) #get a vector for each url but use our customized tokenizer ###添加过滤规则
count_vec = CountVectorizer(stop_words=None)
X = count_vec.fit_transform(corpus) # get the X vector
# X = vectorizer.fit_transform(corpus) #get the X vector
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) #split into training and testing set 80/20 ratio
lgs = LogisticRegression() #using logistic regression
lgs.fit(X_train, y_train)
print(lgs.score(X_test, y_test)) #pring the score. It comes out to be 98%
# return vectorizer, lgs ###返回向量和模型
return count_vec, lgs
(3)两种方法实现TF-IDF的预处理
第一种方法:
使用CountVectorizer类向量化之后,再调用TfidfTransformer类进行预处理
CountVectorizer:
只考虑词汇在文本中出现的频率
TfidfVectorizer:
除了考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量
能够削减高频没有意义的词汇出现带来的影响, 挖掘更有意义的特征
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
corpus=["I come to China to travel", "This is a car polupar in China", "I love tea and Apple ", "The work is to write some papers in science"]
vectorizer=CountVectorizer()
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
print (tfidf)
第二种方法:
直接使用TfidfVectorizer完成向量化与TF-IDF预处理
由于第二种方法比较的简洁,因此在实际应用中推荐使用,一步到位完成向量化,TF-IDF与标准化。
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer()
re = tfidf2.fit_transform(corpus)
print(re)
推荐使用第二种方法,简单方便、直截了当。
(4)TF-IDF使用的局限性
TF-IDF是非常常用的文本挖掘预处理基本步骤,但是如果预处理中使用了Hash Trick,则一般就无法使用TF-IDF了,因为Hash Trick后我们已经无法得到哈希后的各特征的IDF的值。使用了TF-IDF并标准化以后,我们就可以使用各个文本的词特征向量作为文本的特征,进行分类或者聚类分析。当然TF-IDF不仅可以用于文本挖掘,在信息检索等很多领域都有使用。
参考链接:
https://blog.csdn.net/ixuhangyi/article/details/51820328