Расчет схожести строк в Python: простой подход с библиотеками
Быстрый ответ
Для оценки соответствия двух текстов может быть использован такой показатель, как коэффициент Левенштейна
. При помощи модуля python-Levenshtein
этот параметр легко вычисляется, принимая значения от 0 (абсолютное несовпадение) до 1 (полная идентичность строк). Приведём пример кода:
from Levenshtein import ratio
similarity_score = ratio("kitten", "sitting")
print(similarity_score) # Ответ: "0.57142". Достаточно высокая схожесть, несмотря на различия в словах!
Таким образом, вы можете быстро определить степень сходства сравниваемых текстов.
Сравнение строк в Python: подробный разбор
Анализ сходства строк не всегда заключается в поиске полных совпадений. У нас есть целый арсенал методов и подходов для оценки близости текстов.
Стандартная библиотека Python придёт на помощь!
Сравнение строк не всегда требует дополнительных библиотек. Класс SequenceMatcher
из модуля difflib
Python предоставляет простой и эффективный метод сравнения встроенными средствами.
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
print(similar("Apple", "Appel")) # Большое сходство – вкус яблока не изменится, даже если вы напишете его по-другому!
print(similar("Apple", "Mango")) # Значительные различия, особенность фруктового мира
Продвинутые методики с Jaro-Winkler и Jellyfish
Библиотека jellyfish
поддерживает надёжные методы, включая расстояние Жаро и расстояние Левенштейна, что может пригодиться для более глубокого анализа текстов.
import jellyfish
jaro_score = jellyfish.jaro_distance("Apple", "Appel")
levenshtein_score = jellyfish.levenshtein_distance("Apple", "Appel")
print(jaro_score, levenshtein_score) # Оказывается, у этих яблок еще много интересного!
Усовершенствование методов с "TheFuzz"
Библиотека TheFuzz
, известная ранее как FuzzyWuzzy
, предлагает функциональные средства для эффективного вычисления сходства с использованием функций типа fuzz.ratio
и fuzz.token_sort_ratio
.
from thefuzz import fuzz
print(fuzz.ratio("Apple", "Appel")) # Игнорирует порядок букв и видит сходство
print(fuzz.token_sort_ratio("introduction to algorithms", "intro to algo")) # По сути, тот же самый вводный курс, просто в сокращенном виде
Факторы, влияющие на сравнение строк
При оценке сходства следует учитывать контекст и применимость данного метода сравнения к конкретной задаче. Вот основные факторы:
Учет перестановок слов с помощью token sort ratio
Для обработки строк с изменяемым порядком слов использован token sort ratio:
from thefuzz import fuzz
# Отлично подходит для строк с переставленными словами
print(fuzz.token_sort_ratio("algorithm intro", "intro to algo")) # Разный порядок слов, но суть та же!
Визуализация
Для наглядной демонстрации схожести между двумя текстами сравним две строковые последовательности:
Строка A (🔒): "Introduction to Algorithms"
Строка B (🔑): "Intro to Algo"
Давайте рассмотрим 🔍 меру сходства как пазл. У одного человека в руках одна часть (🔒), у другого – соответствующая ей (🔑).
🔒🔑
- Полное Совпадение: 🔒🔑 (Идеально подходящие друг к другу элементы!)
- Частичное Совпадение: 🔒🔄🔑 (Есть общие элементы!)
- Несовпадение: 🔒❌🔑 (Совсем нет совпадений!)
Частичное Совпадение указывает на то, что в содержании строк есть общие элементы.
'Introduction'🔄'Intro', 'Algorithms'🔄'Algo'
Справедливое сравнение строк разной длины
Часто строки имеют разную длину. Приведение более коротких строк к одной длине путём добавления символов поможет в справедливом сравнении.
def padded_similarity(str1, str2, pad_char=' '):
max_len = max(len(str1), len(str2))
padded_str1 = str1.ljust(max_len, pad_char)
padded_str2 = str2.ljust(max_len, pad_char)
return similar(padded_str1, padded_str2)
print(padded_similarity("algorithm", "algo ")) # Теперь длина слов не имеет значения!
Нормализация для точного сравнения
Нормализация данных помогает сделать более точной оценку схожести между строками, особенно когда речь идёт о разнице в регистре и символах.
import re
def normalize(s):
return re.sub('[^A-Za-z0-9]+', '', s).lower()
normalized_score = similar(normalize("Algo-rithm"), normalize("algOrithm"))
print(normalized_score) # Теперь регистр или символы не могут помешать
Полезные материалы
- difflib — Дополнительные утилиты для вычисления различий — Документация Python 3.12.1 – Подробное описание возможностей модуля
difflib
Python для сравнения текстов. - Расстояние Левенштейна – Википедия – Детальная информация об алгоритме расстояния Левенштейна, широко используемом для анализа строк.
- Индекс Жаккара – Википедия – Обзор индекса Жаккара и его применения в текстовом анализе.
- Косинусное сходство – Как это работает? (с Python-примерами) — Machine Learning Plus – Глубокий анализ математической модели косинусного сходства и примеры её реализации на Python.
- 6.2. Извлечение признаков — документация scikit-learn 1.4.0 – Примеры извлечения текстовых признаков в библиотеке scikit-learn.
- GitHub – seatgeek/fuzzywuzzy: Fuzzy String Matching в Python – FuzzyWuzzy, лидер в мире поиска схожести строк для Python.
- Ускоряем сравнение строк в Python – Методики ускорения процесса сравнения строк в Python.