Python: отображать совпадающие ключи со словами словаря - PullRequest
0 голосов
/ 02 марта 2020

Я хочу отобразить соответствующие ключи для словарных слов в моем проекте. Мой код в настоящее время выводит ключи, но те же самые клавиши для любого слова, которое вы вводите. Например, если я введу 'england played well', возвращаемые ключи будут [737, 736, 735, 734, 733, 732, 731, 730, 729, 728]. Если я поставлю 'Hello', то будут возвращены такие же ключи. Пожалуйста, посмотрите код ниже и дайте мне знать, если я делаю что-то не так

import re
import os
import math
import heapq

def readfile(path, docid):
    files = sorted(os.listdir(path))
    f = open(os.path.join(path, files[docid]), 'r',encoding='latin-1')
    s = f.read()
    f.close()
    return s

DELIM = '[ \n\t0123456789;:.,/\(\)\"\'-]+'

def tokenize(text):
    return re.split(DELIM, text.lower())

N = len(sorted(os.listdir('docs')))

def indextextfiles_RR(path):
    postings={}
    docLength = {}
    term_in_document = {}
    for docID in range(N):
        s = readfile(path, docID)
        words = tokenize(s)
        length = 0
        for w in words:
            if w!='':
                length += (math.log10(words.count(w)))**2
        docLength[docID] = math.sqrt(length)
        for w in words:
            if w!='':
                doc_length = math.log10(words.count(w))/docLength[docID]
                term_in_document.setdefault(doc_length, set()).add(docID)
                postings[w] = term_in_document
    return postings


def query_RR(postings, qtext):
    words = tokenize(qtext)
    doc_scores = {}
    for docID in range(N):
        score = 0
        for w in words:
            tf = words.count(w)
            df = len(postings[w])
            idf = math.log10(N / (df+1))
            query_weights = tf * idf
        for w in words:
            if w in postings:
                score = score + query_weights
        doc_scores[docID] = score
    res = heapq.nlargest(10, doc_scores)
    return res

postings = indextextfiles_RR('docs')
print(query_RR(postings, 'hello'))

Когда я запускаю сообщения, он должен вернуть привет и список ключей, связанных с ним.

1 Ответ

1 голос
/ 02 марта 2020

Скорее всего, ваша ошибка происходит от term_in_document, поскольку вы используете один и тот же dict для всех слов в каждом файле.

Несколько комментариев

  1. len(sorted(...)) его потеря ресурсы, сортирующие что-то (сортировка недешевая), которую не нужно сортировать, так как вы только получаете длину.
  2. Чтение файлов по номеру не имеет никакого смысла, и для этого вы в конечном итоге вызываете файловая система несколько раз для чтения имен файлов всего каталога, когда вы перечисляете файлы каждый раз, когда читаете один.
  3. Файлы должны открываться внутри оператора with, который обрабатывает закрытие файла для нас.
  4. Переменные и функции должны использовать this_notation, в то время как классы должны использовать ThisNotation.
  5. Вы дважды выполняете итерацию по списку слов, чтобы получить десятичные логарифмы.

Логика c впоследствии довольно запутанная, вы, кажется, делаете среднеквадратическое (Root Среднее квадратичное) десятичного логарифма раз, когда каждое слово появляется, но вы не делите его на n множество слов. А потом вы снова получаете логарифмы. Вы, вероятно, должны определить свою проблему лучше. Я буду редактировать свой ответ по мере получения новой информации.

import re
import os
import math
import heapq

def read_file(path):
    with open(path, 'r', encoding='latin-1') as f:
        return f.read()

DELIM = '[ \n\t0123456789;:.,/\(\)\"\'-]+'

def tokenize(text):
    return re.split(DELIM, text.lower())

def index_text_files_rr(path):
    postings = {}
    doc_lengths = {}
    term_in_document = {}
    files = sorted(os.listdir(path))
    for i, file in enumerate(files):
        file_path = os.path.join(path, file)
        s = read_file(file_path)
        words = tokenize(s)
        length = 0
        # We will store pairs of the word with the decimal logarithm of
        # the word count here to use it later
        words_and_logs = []
        for word in words:
            # Discard empty words
            if word != '':
                # Compute the decimal logarithm of the word count
                log = math.log10(words.count(word))
                # Add the square of the decimal logarithm to the length
                length += log**2
                # Store the word and decimal logarithm pair
                words_and_logs.append((word, log))
        # Compute the square root of the sum of the squares
        # of the decimal logarithms of the words count
        doc_lengths[i] = math.sqrt(length)
        # Iterate over our stored pairs where we already have the
        # decimal logarithms computed so we do not have to do it again
        for word, log in words_and_logs:
            # No need to discard empty words here as we discarded them before
            # so words_and_logs will not have the empty word
            term_in_document.setdefault(log / doc_lengths[i], set()).add(i)
            postings[w] = term_in_document
    return postings


def query_rr(postings, qtext):
    words = tokenize(qtext)
    doc_scores = {}
    for i in range(N):
        score = 0
        for w in words:
            tf = words.count(w)
            df = len(postings[w])
            idf = math.log10(N / (df+1))
            query_weights = tf * idf
        for w in words:
            if w in postings:
                score = score + query_weights
        doc_scores[i] = score
    res = heapq.nlargest(10, doc_scores)
    return res

postings = index_text_files_rr('docs')
print(query_rr(postings, 'hello'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...