第4章 算法设计
4.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获取单词词频矩阵,然后遍历所有的文档,利用下图公式,计算查询语句与文档之间的欧式距离,最后结果按从大到小进行排序。
第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'。