第4章 算法设计
4.1 实现方式1:欧式距离
实验原理如下图:
图 1 实验原理
4.1.1 步骤1:数据预处理
这一部分对应实验代码1的preprocess函数,首选将文本大写转为小写,然后利用正则表达式去除标点符号,接下来使用nltk包去除句子中的停用词,比如the、a等。经过以上去除一些冗余信息和无关特征,有利于提高模型准确率。
4.2.2 步骤2:获取文档单词列表
实现函数为get_words,主要步骤为读取文档内容,然后行读取句子,将句子按空格分词,最后进行去重,返回单词列表。
4.2.3 步骤三:获取单词词频矩阵
这块分为两部分,一个是为文档单词词频设计的get_Xdw,一个是为查询语句设计的get_Yw,主要步骤是通过get_wors获取文本中的单词列表,然后遍历列表中每一个单词,统计文本中含有该单词的个数。
4.2.4 步骤四:计算查询语句与文档的欧式距离
给定一个查询语句,通过get_Yw获取单词词频矩阵,然后遍历所有的文档,利用下图公式,计算查询语句与文档之间的欧式距离,最后结果按从大到小进行排序。
图2 欧氏距离公式
第5章 程序实现
5.1 实验代码1 计算query与document之间的欧式距离(Euclidean Metric)
# -*- coding: utf-8 -*- # @Time : 2018/4/10 15:11 # @Author : quincyqiang # @File : main.py import os import math from nltk.corpus import stopwords from nltk.stem import PorterStemmer import matplotlib.pyplot as plt import numpy as np # pre-process def preprocess(words=None): print("text propressing..") # lower 大写转小写 words=[word.lower() for word in words] # 去除标点符号 words=[word.replace('[^\w\s]','') for word in words] # 去除停用词 stop=stopwords.words('english') temp=[] for word in words: if word not in stop: temp.append(word) # 提取词干 st=PorterStemmer() words=[st.stem(word) for word in words] return words # get word list def get_words(): words=[] for txt in os.listdir('data'): with open('data/'+txt,'r') as txt_file: for line in txt_file.readlines(): if line!='\n': for word in line.split(): words.append(word) new_words=list(set(words)) # print(new_words) new_words=preprocess(new_words) return new_words # get X-dw(document word vector) def get_Xdw(): Xdw=[] words=get_words() # print(words) # print(len(words)) for txt in os.listdir('data'): with open('data/'+txt,'r') as txt_file: content=txt_file.read() Xdw.append((txt,[content.count(word) for word in words])) # print(Xdw[0],len(Xdw)) return Xdw # get Yw(query word vector) def get_Yw(sentence): words=get_words() sentence_words=sentence.split() sentence_words=preprocess(sentence_words) sentence=' '.join(sentence_words) Yw=[sentence.count(word) for word in words] # print(Yw) return Yw def evaluate(sentence): scores=[] Yw=get_Yw(sentence) Xdw=get_Xdw() for X in Xdw: sum=0 for data in zip(X[1],Yw): sum+=(data[0]-data[1])*(data[0]-data[1]) score=math.sqrt(sum) scores.append(round(score,2)) result=[] for data in zip(os.listdir('data'),scores): result.append(data) result.sort(key=lambda result:result[-1],reverse=True) print(result) return result # evaluate('awarded as a mathematician about approximate measure') result=evaluate('awarded as a statistician about data model and inference') x=np.linspace(1,13,13) y=np.array([score[1] for score in result]) plt.plot(x,y) plt.show()
第六章 实现结果
6.1 实验结果1:
给定查询语句“awarded as a statistician about data model and inference”,得出如下结果,欧氏距离最小的为'leobrieman.txt'。
图3 查询结果
图4 查询语句与文档相似曲线