Определить строки, которые уже хэшированы в абзаце текста, используя Python

То, что я пытаюсь сделать, это по сути разделить URL-адрес и извлечь слова из URL-адреса, однако в большинстве случаев URL-адреса могут содержать строки, которые представляют собой буквенно-цифровые хеши или формы неразборчивого текста.

Возьмите следующий пример: http://www.example.com/wp-content/uploads/2017/10/15321408dd97beb7b5a94f0957b215cf/black-and-white-photography-portrait-of-brad-pitt.jpg

У нас есть описательный URL, из которого можно извлечь ключевые слова. Самая большая проблема с этими ключевыми словами заключается в том, что 15321408dd97beb7b5a94f0957b215cf это один из них. Запуск проверки орфографии не обязательно является лучшим вариантом, поскольку он может отфильтровывать определенные ключевые слова, которые не были добавлены в модель проверки орфографии. Ручное лечение, которое сейчас невозможно. Кроме того, эта строка варьируется по длине и не соответствует. В то время как рассматриваемая строка выглядит как md5, мы знаем, что позиции цифр к буквам могут меняться, поэтому нам нужно учитывать это, а также переменную длину. Думая вслух, почти то, что просто определяет, является ли строка хешем или нет...

Инструменты, которые я использую: Python Spacy

Мой скрипт ниже дает следующий вывод:

  • в.ч.
  • содержание
  • добавления
  • 15321408dd97beb7b5a94f0957b215cf
  • черный
  • а также
  • белый
  • фотография
  • портрет
  • из
  • штифтик
  • Питта
  • JPG

Вот где я до сих пор:

import spacy
from nltk.tokenize import WordPunctTokenizer
from urllib.parse import urlparse


# Check if the word is noise
def is_noise(token, noisy_tags, min_token_length):     
    is_noise = False
    if token.pos_ in noisy_tags:
        is_noise = True 
    elif token.is_digit == True:
        is_noise = True
    elif token.is_stop == True:
        is_noise = True
    elif len(token.string) < min_token_length:
        is_noise = True
    return is_noise 

# Clean word
def clean_word(token, lower = True):
    if lower:
       token = token.lower()
    return token.strip()


nlp = spacy.load('en')

word_tokenizer = WordPunctTokenizer()

parsed_uri = urlparse(url)
text = '{uri.path} {uri.query} {uri.fragment}'.format(uri=parsed_uri)
text = re.sub('[^a-zA-Z\d\s]+', ' ', text)
text = ' '.join(word_tokenizer.tokenize(text))

document = nlp(text)
noisy_pos_tags = ['PROP']
cleaned_words = [clean_word(word.string) for word in document \
                                if not is_noise(word, noisy_pos_tags, 2)]

print(cleaned_words)

Обновление: здесь я добавляю вывод для тегов части речи, используя Spacy:

word: 15321408dd97beb7b5a94f0957b215cf
word.lemma_: 15321408dd97beb7b5a94f0957b215cf
word.dep_: amod
word.shape_: ddddxxddxxxdxdxddxddddxdddxx
word.is_alpha: False
word.is_stop: False

Обновление: я попробовал два других метода, один из которых приблизил меня.

Метод 1 Мне не удалось переобучить классификатор на основе хороших и плохих слов: https://github.com/rrenaud/Gibberish-Detector

Способ 2 Вот второй метод, но работает только с более длинным текстом. В некоторых случаях извлекается только 1 слово, и с помощью этого метода это всегда считается бредом: https://www.codeproject.com/Articles/894766/Gibberish-Classification-Algorithm-and-Implementat

1 ответ

Помимо использования хорошего вероятностного подхода, обеспеченного модулем детектора тарабарщины. Вы также можете использовать несколько сигналов, предоставляемых встроенными корпусами в NLTK и Spacy. Примеры NLTK (с использованием коричневых и Wordnet корпусов)

>>> from nltk.corpus import wordnet
>>> from nltk.corpus import brown
>>> from nltk.corpus import webtext
>>> brown.words()
[u'The', u'Fulton', u'County', u'Grand', u'Jury', ...]
>>> 'brad' in brown.words()
True
>>> 'pitt' in brown.words()
False
>>> '15321408dd97beb7b5a94f0957b215cf' in brown.words()
False
>>> 'photography' in brown.words()
True
>>> wordnet.synsets('photography')
[Synset('photography.n.01'), Synset('photography.n.02'), Synset('photography.n.03')]
>>> wordnet.synsets('brad')
[Synset('brad.n.01'), Synset('brad.v.01')]
>>> wordnet.synsets('pitt')
[Synset('pitt.n.01'), Synset('pitt.n.02'), Synset('pitt.n.03')]
>>> wordnet.synsets('15321408dd97beb7b5a94f0957b215cf')
[]
>>> wordnet.synsets('anothergibberishhash')
[]

Эти поиски не оптимизированы, однако, вам придется создавать оптимизированные структуры данных для поиска этих сигналов в режиме реального времени вместо полной итерации по словам в корпусе.

Другие вопросы по тегам