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:
- TF(Term Freguency,词频)是某一个词在文本中出现的次数,对于某个文本d中的某个词w而言,词w在文本d中的词频记为TF(w,d)。
- 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 的 TfidfVectorizer 变换