TF-IDF原理以及sklearn实现和测试

Posted wyb-mingtian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TF-IDF原理以及sklearn实现和测试相关的知识,希望对你有一定的参考价值。

输入

  输入1:

  本文章采用“python实现中文文档jieba分词和分词结果写入excel文件”文章中输出的两个关于正面中文评价、负面中文评价的excel表格作为输入。

  输入2:

  一些文档分词后得到的字符串列表。

输出

  输出1:根据输入1,训练得到的逻辑回归模型。

  输出2:根据输入2和输出1得到的模型,得到对应的预测结果(正类or负类)

工具

  本文使用工具为:Anaconda、PyCharm、python语言、sklearn

原理

  TF-IDF 是在词袋方法上的一种扩展,它表示词频-逆文档频率。TF-IDF的思想主要为以下两点:在一篇文本中反复出现的词会更重要,在所有文本中都出现的词不重要。这两点分别对应IT和IDF:

  1. TF(Term Freguency,词频)是某一个词在文本中出现的次数,对于某个文本d中的某个词w而言,词w在文本d中的词频记为TF(w,d)。
  2. IDF(Inverse Document Freguency,逆文档频率指数)是已有的文本总数除以某一个词在已有的文本集合中出现的次数。假设总文本数为N,词w出现的文本数为n,那么词w在文档集合中的逆文档频率IDF(w) = N/n,也可记为对数形式IDF(w) = log(N/n)。对于一个给定的文本集合,每个词的逆文本频率是可以提前统计好的。

  TF-IDF就是IF和IDF两者相乘:TF-IDF(w,d) = TF(w,d) * IDF(w)

  以上就是关于TF-IDF的原理介绍。本文采用sklearn包中的TF-IDF工具组件对输入的数据表格进行操作,得到词频-逆文档频率矩阵。然后采用sklearn包自带的逻辑回归模型进行训练,通过网格搜索的方式得到最优的正则化参数,通过k折交叉验证方法减少模型的方差,提高模型对数据的普遍适应性。

Python代码实现

 1 # 从txt生成的excel文件,一定要另存为csv文件,然后再用read_csv读取,不然会遇到一些格式的问题
 2 import pandas as pd
 3 import numpy as np
 4 f = open(neg_fenci_excel_to_csv.csv)
 5 neg_pd = pd.read_csv(f)
 6 f.close()
 7 
 8 f = open(pos_fenci_excel_to_csv.csv)
 9 pos_pd = pd.read_csv(f)
10 f.close()
11 
12 # 连接neg_pd和pos_pd
13 neg_pos_pd = pd.concat([neg_pd, pos_pd], axis=0)
14 neg_pos_pd.to_csv(neg_pos.csv)
15 
16 # 划分训练集、测试集,比例为70%、30%
17 from sklearn.model_selection import train_test_split
18 x_train, x_test, y_train, y_test = train_test_split(neg_pos_pd[review], neg_pos_pd[label], test_size = 0.3)
19 
20 from sklearn.feature_extraction.text import CountVectorizer
21 from sklearn.feature_extraction.text import TfidfVectorizer
22 from sklearn.feature_extraction.text import TfidfTransformer
23 # fit_transform相当于先fit,再transform
24 # fit入参为训练数据集(文档集合),得到词典
25 # transform 入参为文档集合,通过fit得到的词典,得到词频矩阵
26 
27 #构建词频矩阵
28 countVec = CountVectorizer()
29 countVec_bow = countVec.fit_transform(x_train)
30 # countVec 中有一些关于词典的属性
31 print(countVec_bow get_feature_names len:{}.format(len(countVec.get_feature_names())))
32 print(countVec_bow vocabulary_:
{}.format(countVec.vocabulary_))
33 print(countVec_bow get_feature_names :{}.format(countVec.get_feature_names()))
34 # 构建词频矩阵,转成矩阵形式
35 # 矩阵元素a[i][j] 表示j词在第i个文本下的词频
36 print(countVec_bow array:
{}.format(countVec_bow.toarray()))
37 
38 # 两种得到词频-逆文档频率矩阵的方法
39 # 经过词频矩阵得到词频-逆文档频率矩阵
40 tfidf_test = TfidfTransformer()
41 tfidf_test_bow = tfidf_test.fit_transform(countVec_bow)
42 print(tfidf_test_bow array:
{}.format(tfidf_test_bow))
43 # 通过原始文档,直接得到词频-逆文档频率矩阵
44 tfidf = TfidfVectorizer()
45 tfidf_bow = tfidf.fit_transform(x_train)
46 print(tfidf_bow array:
{}.format(tfidf_bow))
47 
48 import sklearn.model_selection as modsel
49 from sklearn.linear_model import LogisticRegression
50 # 搜索网格的范围(网格搜索:一种基本的超参数调优过程)
51 param_grid = {C : [1e-5, 1e-3, 1e-1, 1e0, 1e1, 1e2]}
52 # 采用10折交叉验证
53 tfidf_search = modsel.GridSearchCV(LogisticRegression(), cv=10, param_grid=param_grid)
54 tfidf_search.fit(tfidf_bow, y_train)
55 print(result:
{}.format(tfidf_search.cv_results_))
56 # 通过cv_results_中的结果,选择正则化参数为1e0
57 result_model = LogisticRegression(C=1e0).fit(tfidf_bow, y_train)
58 tfidf_x_test = tfidf.transform(x_test)
59 score = result_model.score(tfidf_x_test, y_test)
60 print(score:{}.format(score))
61 
62 def model_test(model, strList):
63     strList_to_tfidf = tfidf.transform(strList)
64     print(strList_to_tfidf:{}.format(strList_to_tfidf.toarray().shape))
65     probaList = model.predict_proba(strList_to_tfidf)
66     print(probaList:
{}.format(probaList))
67 # 6条测试用例,已知前3条为负例,后3条为正例
68 testList = [商品 划花 忍受 京东 配送 实在 气愤,
69            驱动 系统 安装 光盘 带来 不便 最让人 感到 气愤 硬盘 分区 厂家 做法 未免太 懒惰 太 不负责任,
70             操作系统 裸机 分成 盘 重装 acer 光盘 重装 专用 软件 网站 找到 美中不足,
71             优点   外观 够 型 配置 不错 价格合理 非常适合 商务     光驱 声音 真的 很大 底部 发热量 很大     特价 4999 价格 购买 超值 值得,
72             商品 值得一提 性价比 hp 品牌 P8600 CPU 足够 升级 太 便宜 做工 价位 不错 IBM   T23 X41 距离 价位 整体 不错 京东 服务 不错 网上 快递 进程 客户 有谱,
73             几天 终于 拿到 配置 品牌 令人满意 商务 选择]
74 
75 model_test(result_model, testList)

 

 

 

代码运行结果

  模型准确率为:score:0.8875

  6条测试用例的测试结果为:

  probaList:

  [[0.83668722 0.16331278]

   [0.80493181 0.19506819]

   [0.84483608 0.15516392]

   [0.08431679 0.91568321]

   [0.03640066 0.96359934]

   [0.15293085 0.84706915]]

  可以看到前3条为负例的概率大于0.5,后3条为正例的概率大于0.5。所以这6条测试用例预测的都是准确的。

 

以上是关于TF-IDF原理以及sklearn实现和测试的主要内容,如果未能解决你的问题,请参考以下文章

使用 sklearn 获取单词的 tf-idf 权重

使用 sklearn 如何计算文档和查询之间的 tf-idf 余弦相似度?

使用 Sklearn 的 TfidfVectorizer 变换

使用 sklearn tf-idf 查找矢量化文本文档中的簇数

sklearn中的tf-idf计算公式详解

sklearn : TFIDF Transformer : 如何获取文档中给定单词的 tf-idf 值