1.准备工作
在本文开始之前,我们首先是对原始的CSV表格的数据读取,然后分词,之后才开始进行智能匹配。csv的读取和分词都在之前的博客,所有的代码都是一个工程的。但是由于训练集是公司的数据,所以不方便放出,请谅解。但是对于训练集数据的描述CSV读取的博客中有提到。
csv的读取:https://blog.csdn.net/qq_28626909/article/details/81674612
分词:https://blog.csdn.net/qq_28626909/article/details/81674728
2.对智能匹配的理解
对于智能匹配,其实我个人感觉用深度学习是最好的,但是公司开始要求用机器学习,所以也就写了............
关于这个思想呢,大致是这样的:
2.1 先对问题的库进行处理,构建成一个词向量库
比如,我们所有的文本中有2万行,但是在分词处理之后可能之后8000个不同的词向量,所以我们就可以用一个 2万*8000的矩阵表示我们整个文本,每一行有8000个元素,只要原来对应的行数中,出现几个这个词向量,我们给她赋值几,没出现的全是0。
我们现在引入一段代码看看(代码原文链接:https://blog.csdn.net/guotong1988/article/details/51567562)
from sklearn.feature_extraction.text import CountVectorizer
texts=["dog cat fish","dog cat cat","fish bird", 'bird']
cv = CountVectorizer()
cv_fit=cv.fit_transform(texts)
print(cv.get_feature_names())
print(cv_fit.toarray())
#['bird', 'cat', 'dog', 'fish']
#[[0 1 1 1]
# [0 2 1 0]
# [1 0 0 1]
# [1 0 0 0]]
2.2 使用TF-IDF方法
先看看TF-IDF公式:
简单描述:TF-IDF逆文本频率指数
概念:是一种统计方法,用以评估一个词对于一个语料库中一份文件的重要程度。词的重要性随着在文件中出现的次 数正比增加,同时随着它在语料库其他文件中出现的频率反比下降。
就是说一个词在某一文档中出现次数比较多,其他文档没有出现,说明该词对该文档分类很重要。然而如果其他文档也出现比较多,说明该词区分性不大,就用IDF来降低该词的权重。
数学算法:
TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比
TF-IDF = TF (词频) * IDF(逆文档频率)
词频:TF = 词在文档中出现的次数 / 文档中总词数
逆文档频率:IDF = log(语料库中文档总数 / 包含该词的文档数 +1 )
2.3智能匹配
当我们把之前的词频矩阵完全转换为包含tf-idf值的矩阵时,我们就可以开始只能匹配了。
首先,我们把我们输入的话进行分词,然后同样转换成和词频矩阵一样宽(长)的矩阵,然后我们对他们逐一进行矩阵的乘法计算,算出每行的值,最大的值则是匹配度最高的值。
所以我们对矩阵TF-IDF进行一个转置,然后就可以很方便的和输入的矩阵进行相乘,之后我们排序,就可以得到匹配度最高的三句话。
3.代码实现
#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File : TF-IDF.py
# @Author: WangYe
# @Date : 2018/7/23
# @Software: PyCharm
import numpy as np
import collections
import jieba
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer #词频矩阵
def readfile():
path = "C:/Users/wy/Desktop/jieba.txt"
a=[]#存放去掉字符的文本
with open(path,'r',encoding='utf-8') as f:
for line in f:
produce1 = line.replace(',', '').replace('、', '').replace('?', '').\
replace('//',' ').replace('/',' ')
#print(produce1)
a.append(produce1)
path1 = "C:/Users/wy/Desktop/quci.txt"
with open(path1,'w',encoding='utf-8') as f:
for i in a:
f.write(str(i))
# print(a[0])
# b=a[0]
# print(b[1])
#print(a)
f.close()
return a
def TF_IDF():
vectorizer = CountVectorizer() # 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
transformer = TfidfTransformer() # 该类会统计每个词语的tf-idf权值
'''测试词频矩阵'''
b=[]
for cishu in range(100):
b.append(readfile()[cishu])
test_cipin=vectorizer.fit_transform(b)
#print(test_cipin.toarray)
print(test_cipin.toarray()) #获取次品矩阵
print(vectorizer.get_feature_names()) #词带将会存储来vectorizer
'''测试结束'''
'''测试tf-idf'''
test_tfidf=transformer.fit_transform(test_cipin) #if-idf中的输入为已经处理过的词频矩阵
print(test_tfidf.toarray()) #输出词频矩阵的IF-IDF值
print(test_tfidf.toarray().shape)
'''测试结束'''
print("请输出要查询的内容:\n")
input_text=input()
input_text_jieba=jieba.cut(input_text)
'''开始处理输入文本,构建对应的词频矩阵'''
coll=collections.Counter(input_text_jieba)
new_vectorizer=[]
for word in vectorizer.get_feature_names(): #原始词频
new_vectorizer.append(coll[word]) #构建输入的全新词频
print(new_vectorizer)
'''全新词带构建完成'''
'''原始词频的TF-IDF词频矩阵进行转置'''
new_tfidf=np.array(test_tfidf.toarray()).T
#print(new_tfidf)
#print(new_tfidf.shape)
'''矩阵相乘'''
new_vectorizer=np.array(new_vectorizer).reshape(1,len(new_vectorizer))
#print(new_vectorizer)
scores=np.dot(new_vectorizer,new_tfidf)
print('预测结果是:')
print(scores)
print(type(scores))
#print(type(scores))
new_scores=list(scores[0])#将得分的一维矩阵转换为列表
#print(new_scores)
#print(type(new_scores))
#print(new_scores[9])
max_location =sorted(enumerate(new_scores), key=lambda x:x[1])#列表坐标排序,转换为元组
max_location.reverse() #上面默认为从小到大,将他逆序
final_location=[]
for i in range(3): #在元组中找到匹配度最高的三个数的坐标
print(max_location[i][0])
print(max_location[i][1])
final_location.append(max_location[i][0])
print("最近匹配到:")
for i in range(3):
print(b[final_location[i]])
# for i in range(3):
# print(max_location[len(max_location)-i])
#max_location=new_scores.index(max(new_scores))
#print(b[max_location])
if __name__ == '__main__':
#readfile()
TF_IDF()
4.运行截图
5.总结
我们通过排序,得出匹配度最高的三句话,然后我们根据前面的序号,就可以在答案的库中找到对应的答案。这里我多说一下,矩阵的处理很多,大家需要对numpy很熟悉~。最后再说一下,数据集是公司的项目,是有关政府的,所以数据集是不能放的,我和大家分享一下代码~