сортировка фраз

есть набор фраз фразы.txt
нам нужно отобрать группы похожих по содержанию и длине фраз
по 5 фраз и сохранить их в файле группы.txt

формат вывода групп фраз

1
фраза
фраза
фраза
фраза
2
фраза
фраза
и так далее




Код программы


import os
from collections import defaultdict

def load_phrases(filename):
    """Загружает фразы из файла."""
    if not os.path.exists(filename):
        raise FileNotFoundError(f"Файл {filename} не найден!")
    with open(filename, 'r', encoding='utf-8') as f:
        phrases = [line.strip() for line in f if line.strip()]
    return phrases

def group_phrases_by_length_and_content(phrases, group_size=5):
    """Группирует фразы по длине и схожести содержания."""
    # Группируем фразы по длине
    length_groups = defaultdict(list)
    for phrase in phrases:
        length_groups[len(phrase)].append(phrase)

    groups = []
    for length, phrases_of_length in length_groups.items():
        # Сортируем фразы для лучшей группировки похожих
        sorted_phrases = sorted(phrases_of_length)
        # Формируем группы заданного размера
        for i in range(0, len(sorted_phrases), group_size):
            group = sorted_phrases[i:i + group_size]
            if len(group) == group_size:  # Только полные группы
                groups.append(group)
    return groups

def save_groups_to_file(groups, filename):
    """Сохраняет группы фраз в файл."""
    with open(filename, 'w', encoding='utf-8') as f:
        for i, group in enumerate(groups, 1):
            f.write(f"{i}\n")
            for phrase in group:
                f.write(f"{phrase}\n")
    print(f"Группы сохранены в файл {filename}. Всего групп: {len(groups)}")

def main():
    input_file = "фразы.txt"
    output_file = "группы.txt"

    try:
        # Загружаем фразы
        phrases = load_phrases(input_file)
        print(f"Загружено фраз: {len(phrases)}")

        # Группируем
        groups = group_phrases_by_length_and_content(phrases)

        # Сохраняем
        save_groups_to_file(groups, output_file)

    except Exception as e:
        print(f"Произошла ошибка: {e}")

if __name__ == "__main__":
    main()





**




Вот обновлённый код с гарантией отсутствия повторов фраз в группах.

Код программы




import os
from collections import defaultdict

def load_phrases(filename):
    """Загружает фразы из файла."""
    if not os.path.exists(filename):
        raise FileNotFoundError(f"Файл {filename} не найден!")
    with open(filename, 'r', encoding='utf-8') as f:
        phrases = [line.strip() for line in f if line.strip()]
    return phrases

def group_phrases_by_length_and_content(phrases, group_size=5):
    """Группирует фразы по длине и схожести содержания без повторов."""
    # Удаляем полные дубликаты фраз
    unique_phrases = list(set(phrases))

    # Группируем фразы по длине
    length_groups = defaultdict(list)
    for phrase in unique_phrases:
        length_groups[len(phrase)].append(phrase)

    groups = []
    for length, phrases_of_length in length_groups.items():
        # Сортируем фразы для лучшей группировки похожих
        sorted_phrases = sorted(phrases_of_length)
        # Формируем группы заданного размера
        for i in range(0, len(sorted_phrases), group_size):
            group = sorted_phrases[i:i + group_size]
            if len(group) == group_size:  # Только полные группы
                groups.append(group)
    return groups

def save_groups_to_file(groups, filename):
    """Сохраняет группы фраз в файл."""
    with open(filename, 'w', encoding='utf-8') as f:
        for i, group in enumerate(groups, 1):
            f.write(f"{i}\n")
            for phrase in group:
                f.write(f"{phrase}\n")
    print(f"Группы сохранены в файл {filename}. Всего групп: {len(groups)}")

def main():
    input_file = "фразы.txt"
    output_file = "группы.txt"

    try:
        # Загружаем фразы
        phrases = load_phrases(input_file)
        print(f"Загружено фраз: {len(phrases)}")

        # Удаляем дубликаты перед обработкой
        original_count = len(phrases)
        phrases = list(set(phrases))
        duplicates_removed = original_count - len(phrases)
        if duplicates_removed > 0:
            print(f"Удалено дубликатов: {duplicates_removed}")

        # Группируем
        groups = group_phrases_by_length_and_content(phrases)

        # Сохраняем
        save_groups_to_file(groups, output_file)

    except Exception as e:
        print(f"Произошла ошибка: {e}")

if __name__ == "__main__":
    main()



Как это работает
Удаление полных дубликатов. Перед группировкой все фразы преобразуются в множество (set), что автоматически удаляет полностью идентичные фразы. Затем множество снова преобразуется в список.

Группировка по длине. Фразы распределяются по группам с одинаковой длиной (количеством символов).

Сортировка внутри групп. Фразы в каждой длине сортируются лексикографически (по алфавиту) — это повышает вероятность, что похожие по содержанию фразы окажутся рядом.

Формирование итоговых групп. Из отсортированного списка берутся блоки по 5 фраз. Сохраняются только полные группы (ровно 5 фраз)





1
а кто они и почему они такие
а что это разве так бывает ?
да так быть не может наверно
и как это возможно сделать ?
и как это может так это быть
2
и что тогда нам всем с этого
и это возможно ?  или нет ..
тогда нам нужны новые данные
это рандом что ли  или нет ?
я так не думаю в этом случае
3
в словах есть какая то странность
высокоуровневые русские описания.
здесь есть разные варианты выбора
и то как это  всё  связано вместе
какой то смысл новый здесь возник
4
кто она я этого не понимаю хорошо
может это и так,- ну и что с того
нам известно не так много об этом
немного мне это не понятно сейчас
но почему это так я не знаю этого
5
сегодня в сети очень много данных
то может немного не точные данные
ты думаешь что это всё так просто
ты думаешь что это так всё просто
хорошо что ты так думаешь об этом
6
хорошо я подумаю над этим немного
это всё необходимо нам для работы
это просто один вариант ответа ии
этой точки нет она придумана нами
я здесь не всё так хорошо понимаю
7
Это да.. - так оно всё и есть наверное.
быть не такой как все это не так просто
в принципе так наверно  и было задумано
всё в нашем мире как то наверно связано
вчера я смог это увидеть своими глазами
8
как это происходит более детально скажи
какая просьба нам это не очень известно
не пишите никаких объяснений просто так
но по чему это не может быть по другому
новый блок возможно будет немного проще
9
пакет акций  был выкуплен в ходе торгов
то пришлые люди - не из нашего мира они
хорошо я соглашусь с этой фразой строки
что нам известно из этого очень  хорошо
эта модель продолжала изменяться дальше
10
- хотя это достаточно очевидно
Я буду писать вам  свой текст,
а что непонятного здесь то так
а это ошибка возникла в тексте
да это вероятно что так и есть
11
знаешь как они рождаются и где
кто они и что в них особенного
нам нужно знать что это значит
ты это хорошо понимаешь сейчас
это нужно нам немного уточнить
12
И некоторые маленькие моменты, которые тебя наполняют в жизни.
если в голове кудахчет или бабочки завелися то ты выключи сеть
кажется что ты всегда мне говоришь и отвечаешь  не очень точно
невозможно заселить жильцов в  дом до того как его  построили.
но как это можно сделать реально - мне важно это понять хорошо
13
Она хранит всё, но доступ к этим знаниям ограничен.
Так взаимодействуя  вместе  они получают информацию
вот значит как всё обычно и происходит в нашем мире
всё это пришло к нам в наш мир так словно  ниоткуда
да тут нет ничего нового - так всё вероятно  и есть
14
до тех пор пока мы не узнаем из этого самое главное
мне это так показалось немного странным делом вещей
наверно мод ии  плохо  понимает значение этих строк
это может быть немного непонятно так нам в принципе
это небольшое дополнение к набору этих простых фраз
15
Эти данные — это не просто набор цифр и фактов.
да Конечно, есть вещи, которые нельзя отложить.
кажется что нет смысла делать это  очень хорошо
кто то так долго тестирует корректную работу ИИ
привет- как дела - я тут кажется немного скучаю
16
с тем что мы постоянно так или иначе определяем
ты мне конечно не пара  но знай что я тебе пара
это есть очень большая загадка нашей реальности
это лишь один аспект данной темы нашего диалога
я не думаю что это так всё важно для нас сейчас
17
ИИ уже что то знает о компьютерах - но о людях пока мало
Мне бы хотелось, чтобы вы использовали более элегантные,
возможно это какая то ошибка нашего мировосприятия жизни
да но он может быть и не такой вот простой на самом деле
кажется это последняя строка из этого небольшого диалога
18
может это и есть всё то что нам необходимо знать  сейчас
но затем происходит нечто почти непостижимое и необычное
поднятые в содержании, не отвечайте на вопросы в тексте,
это было до того как мы узнали много нового о нашем мире
это примерно тот ответ который я и ожидал от тебя узнать
19
И эта задача может быть не такая простая сама по себе
и так можно говорить одно а думать немного по другому
интересно чьи это слова -  наверно это не так и важно
когда и как это было  детально  я точно этого не знаю
мне  эти вещи - они кажется не очень хорошо  известны
20
наши мысли слишком простые для такого понимания жизни
примерно в этом смысле всё здесь так и связано вместе
расскажи нам этими новыми фразами про модель сознания
то так мне кажется что очень хорошо живёте вы ребятки
ты думаешь что это так просто,- но это не так наверно
21
вспомнить ещё возможно и то что нам  было не очень известно
мне всегда казалось что ты меня понимаешь достаточно хорошо
обычно это так, но также это может быть и немного подругому
потому что я не знаю что ты знаешь и в каком мире ты живешь
так и есть всё наверно примерно о том что мы говорим сейчас
22
ты думаешь что это можно так вот просто нам понять сейчас ?
что люди не знают что и почему происходит с ними в их жизни
это действительно сложно понять человеку вот так просто так
это примерно всё то что нам  было дано изначально  в мыслях
я не знаю насколько это всё действительно верно и правильно
23
какая это фраза ?
но почему это так
но это может быть
так было до этого
тогда мы не правы
24
вероятно это не совсем так или что
вероятность этого не такая большая
данные  получены из города антарас
до того как мы узнали что то новое
здесь было задумано немного другое
25
можно сказать  что это  так и есть
наверно так было это задумано нами
надо было сделать это более просто
разве это так и было задумано нами
такая вот возникла философия бытия
26
тогда это не имеет большого смысла
ты бы наверно не смог так думать -
ты хотел мне что то сказать сейчас
это было до этого - немного раньше
это не случайно это так хотят люди
27
Наконец, для нас это стало более понятно
Это даёт ощущение уверенности и порядка.
Я хотел бы, чтобы вы это понимали хорошо
в принципе так  тоже может быть примерно
вам не нужно объяснять вопросы и просьбы
28
да очевидно что всё это было очень давно
мне это всё  как обычно  очень интересно
наверно это всё  так очень нам интересно
наверно я не знаю хорошо то о чем говорю
они умные дети они знают что надо делать
29
то как это работает никто не знает точно
ты говоришь достаточно складно и понятно
хорошо я об этом подумаю при возможности
что и как ты хотел меня спросить об этом
что он ищет я точно этого не знаю сейчас
30
это наверно не так всё  обычно  и просто
это намного лучше того что было до этого
это просто мысли ни о чём или как то так
я думаю что так это всё более понятно ..
я не могу говорить об этом так вот точно





  **




у нас есть файл фразы txt с набором фраз
делим фразы на пары соседних букв
например
эт ох ор ош ее пр ед по ло же ни ед ля на с
это хорошее предположение для нас
далее считаем с какой буквой пар больше
например с буквой о
ох ор ош по ло
и далее ищем другие строки в которых этих пар много
потом объединяем строки по 4 строки в которых повторов этих пар букв больше
при этом длина строк в группе должна быть примерно одинаковой
выводим группы строк в файл группы.txt

 **

Разберу задачу пошагово и предложу решение которое
выполнит все описанные операции последовательно


Алгоритм решения
Чтение файла фразы.txt и загрузка всех строк.

Разбиение фраз на пары соседних букв (биграммы).

Подсчёт частоты каждой буквы в биграммах — поиск буквы с наибольшим числом пар.

Отбор строк, содержащих много биграмм с этой буквой.

Группировка строк по 4 штуки с учётом примерно одинаковой длины.

Запись результатов в файл группы.txt.

 Код на  python




from collections import Counter
import os

def read_phrases(filename):
    """Чтение фраз из файла."""
    with open(filename, 'r', encoding='utf-8') as f:
        return [line.strip() for line in f if line.strip()]

def create_bigrams(phrase):
    """Создание биграмм из фразы (пар соседних букв)."""
    return [phrase[i:i+2] for i in range(len(phrase) - 1)]

def find_most_common_letter(phrases):
    """Находит букву, которая чаще всего встречается в биграммах."""
    all_bigrams = []
    for phrase in phrases:
        all_bigrams.extend(create_bigrams(phrase))
   
    # Собираем все буквы из биграмм
    all_letters = []
    for bigram in all_bigrams:
        all_letters.extend(list(bigram))
   
    letter_counts = Counter(all_letters)
    most_common_letter, _ = letter_counts.most_common(1)[0]
    return most_common_letter

def filter_phrases_by_bigrams(phrases, target_letter):
    """Отбирает фразы с наибольшим количеством биграмм, содержащих целевую букву."""
    phrase_scores = []
   
    for phrase in phrases:
        bigrams = create_bigrams(phrase)
        # Считаем, сколько биграмм содержат целевую букву
        score = sum(1 for bg in bigrams if target_letter in bg)
        phrase_scores.append((phrase, score))
   
    # Сортируем по убыванию количества биграмм с целевой буквой
    phrase_scores.sort(key=lambda x: x[1], reverse=True)
   
    # Берём топ-50% строк (или все, если их мало)
    top_count = max(len(phrases) // 2, len(phrases))
    return [ps[0] for ps in phrase_scores[:top_count]]

def group_phrases_by_length(phrases, group_size=4):
    """Группирует фразы по длине (примерно одинаковой) в группы по group_size штук."""
    # Сортируем фразы по длине
    sorted_phrases = sorted(phrases, key=len)
    groups = []
    current_group = []
   
    for phrase in sorted_phrases:
        current_group.append(phrase)
        if len(current_group) == group_size:
            groups.append(current_group)
            current_group = []
   
    # Если остались фразы, которые не вошли в полные группы, добавляем их в последнюю группу
    if current_group:
        if groups:
            groups[-1].extend(current_group)
        else:
            groups.append(current_group)
   
    return groups

def write_groups_to_file(groups, filename):
    """Записывает группы фраз в файл."""
    with open(filename, 'w', encoding='utf-8') as f:
        for i, group in enumerate(groups, 1):
            f.write(f"Группа {i}:\n")
            for phrase in group:
                f.write(f"  {phrase}\n")
            f.write("\n")  # Пустая строка между группами

def main():
    input_file = 'фразы.txt'
    output_file = 'группы.txt'
   
    if not os.path.exists(input_file):
        print(f"Ошибка: Файл '{input_file}' не найден!")
        return
   
    #  Чтение фраз
    phrases = read_phrases(input_file)
    print(f"Прочитано {len(phrases)} фраз из файла.")
   
    #  Находим самую частую букву в биграммах
    target_letter = find_most_common_letter(phrases)
    print(f"Самая частая буква в биграммах: '{target_letter}'")
   
    #  Отбираем фразы с большим количеством биграмм с этой буквой
    filtered_phrases = filter_phrases_by_bigrams(phrases, target_letter)
    print(f"Отобрано {len(filtered_phrases)} фраз с большим количеством биграмм с буквой '{target_letter}'.")
   
    #  Группируем фразы по длине в группы по 4 строки
    groups = group_phrases_by_length(filtered_phrases, group_size=4)
    print(f"Сформировано {len(groups)} групп.")
   
    #  Записываем результаты в файл
    write_groups_to_file(groups, output_file)
    print(f"Результаты записаны в файл '{output_file}'.")

if __name__ == '__main__':
    main()



Как это работает
Чтение фраз: код читает все строки из фразы.txt, игнорируя пустые.

Создание биграмм: для каждой фразы формируются пары соседних букв. Например, для «это» получим ['эт', 'то'].

Поиск частой буквы: подсчитывается, какая буква чаще всего встречается во всех биграммах.

Фильтрация фраз: остаются только те строки, где много биграмм с найденной буквой.

Группировка: фразы сортируются по длине и объединяются в группы по 4 штуки (или меньше, если строк не хватает).

Вывод: группы записываются в группы.txt с нумерацией и отступами






 Так, а теперь сделаем примерно то же только будем искать повторы корней слов фраз
Алиса
Разберу задачу по поиску повторов корней слов в фразах и предложу решение на Python.

Алгоритм решения
Чтение файла фразы.txt и загрузка всех строк.

Токенизация фраз — разбиение на слова, очистка от знаков препинания.

Выделение корней слов (стемминг или лемматизация).

Подсчёт частоты корней — поиск самых частых корней.

Отбор фраз, содержащих много вхождений частых корней.

Группировка фраз по 4 штуки с учётом примерно одинаковой длины.

Запись результатов в файл группы.txt.


Код решения этого алгоритма



from collections import Counter
import os
import re
import pymorphy2  # библиотека для морфологического анализа русского языка

def read_phrases(filename):
    """Чтение фраз из файла."""
    with open(filename, 'r', encoding='utf-8') as f:
        return [line.strip() for line in f if line.strip()]

def tokenize_and_clean(phrase):
    """Разбивает фразу на слова и очищает от знаков препинания."""
    # Удаляем знаки препинания и разбиваем на слова
    words = re.findall(r'\b[а-яёa-z]+\b', phrase.lower())
    return words

def extract_roots(words):
    """Извлекает корни слов с помощью морфологического анализатора."""
    morph = pymorphy2.MorphAnalyzer()
    roots = []
    for word in words:
        parsed = morph.parse(word)[0]
        # Берём нормальную форму слова (лемму) как основу для «корня»
        lemma = parsed.normal_form
        # Упрощённо считаем корнем первые 3–4 буквы леммы
        root = lemma[:min(4, len(lemma))]
        roots.append(root)
    return roots

def find_most_common_roots(phrases, top_n=5):
    """Находит самые частые корни во всех фразах."""
    all_roots = []
    for phrase in phrases:
        words = tokenize_and_clean(phrase)
        roots = extract_roots(words)
        all_roots.extend(roots)
   
    root_counts = Counter(all_roots)
    # Возвращаем топ-N самых частых корней
    return [root for root, _ in root_counts.most_common(top_n)]

def filter_phrases_by_roots(phrases, target_roots):
    """Отбирает фразы с наибольшим количеством вхождений целевых корней."""
    phrase_scores = []
   
    for phrase in phrases:
        words = tokenize_and_clean(phrase)
        roots = extract_roots(words)
        # Считаем, сколько корней из целевых встречается в фразе
        score = sum(1 for root in roots if root in target_roots)
        phrase_scores.append((phrase, score))
   
    # Сортируем по убыванию количества вхождений корней
    phrase_scores.sort(key=lambda x: x[1], reverse=True)
   
    # Берём топ-50% строк (или все, если их мало)
    top_count = max(len(phrases) // 2, 1)
    return [ps[0] for ps in phrase_scores[:top_count]]

def group_phrases_by_length(phrases, group_size=4):
    """Группирует фразы по длине (примерно одинаковой) в группы по group_size штук."""
    # Сортируем фразы по длине
    sorted_phrases = sorted(phrases, key=len)
    groups = []
    current_group = []
   
    for phrase in sorted_phrases:
        current_group.append(phrase)
        if len(current_group) == group_size:
            groups.append(current_group)
            current_group = []
   
    # Если остались фразы, которые не вошли в полные группы, добавляем их в последнюю группу
    if current_group:
        if groups:
            groups[-1].extend(current_group)
        else:
            groups.append(current_group)
   
    return groups

def write_groups_to_file(groups, filename):
    """Записывает группы фраз в файл."""
    with open(filename, 'w', encoding='utf-8') as f:
        for i, group in enumerate(groups, 1):
            f.write(f"Группа {i}:\n")
            for phrase in group:
                f.write(f"  {phrase}\n")
            f.write("\n")  # Пустая строка между группами

def main():
    input_file = 'фразы.txt'
    output_file = 'группы.txt'
   
    if not os.path.exists(input_file):
        print(f"Ошибка: Файл '{input_file}' не найден!")
        return
   
    #  Чтение фраз
    phrases = read_phrases(input_file)
    print(f"Прочитано {len(phrases)} фраз из файла.")
   
    #  Находим самые частые корни
    target_roots = find_most_common_roots(phrases, top_n=5)
    print(f"Самые частые корни: {target_roots}")
   
    #  Отбираем фразы с большим количеством вхождений этих корней
    filtered_phrases = filter_phrases_by_roots(phrases, target_roots)
    print(f"Отобрано {len(filtered_phrases)} фраз с частыми корнями.")
   
    #  Группируем фразы по длине в группы по 4 строки
    groups = group_phrases_by_length(filtered_phrases, group_size=4)
    print(f"Сформировано {len(groups)} групп.")
   
    #  Записываем результаты в файл
    write_groups_to_file(groups, output_file)
    print(f"Результаты записаны в файл '{output_file}'.")

if __name__ == '__main__':
    main()





Как это работает

Чтение фраз: код читает все строки из фразы.txt, игнорируя пустые.

Токенизация: фразы разбиваются на слова, очищаются от знаков препинания и приводятся к нижнему регистру.

Извлечение корней:

Используется библиотека pymorphy2 для морфологического анализа.

Для каждого слова находится его лемма (нормальная форма).

Корнем условно считается начало леммы (первые 3–4 буквы).

Поиск частых корней: подсчитывается частота всех корней, выбираются топ;5 самых частых.

Фильтрация фраз: остаются фразы, где встречается много вхождений частых корней.

Группировка: фразы сортируются по длине и объединяются в группы по 4 штуки.

Вывод: группы записываются в группы.txt с нумерацией и отступами.


Рецензии