генератор новых фраз ru core news sm

import spacy
import random
from collections import defaultdict, Counter
import pymorphy2

# Загрузка русской модели spaCy
nlp = spacy.load("ru_core_news_sm")
morph = pymorphy2.MorphAnalyzer()

# Чтение исходного текста
with open("диалог.txt", encoding="utf-8") as f:
    text = f.read()

doc = nlp(text)

# Сбор статистики слов по POS
words_by_tag = defaultdict(set)
tag_sequences = []

for sent in doc.sents:
    tags = []
    for token in sent:
        if token.is_space:
            continue
        tags.append(token.pos_)
        words_by_tag[token.pos_].add(token.text)
    tag_sequences.append(tags)

# Преобразуем множества в списки для случайного выбора
words_by_tag = {tag: list(words) for tag, words in words_by_tag.items()}

# Подсчёт переходов между тегами
transitions = Counter()
for tags in tag_sequences:
    for i in range(len(tags) - 1):
        transitions[(tags[i], tags[i+1])] += 1

transitions_dict = defaultdict(list)
for (tag1, tag2), count in transitions.items():
    transitions_dict[tag1].append((tag2, count))

def weighted_choice(choices):
    total = sum(w for c, w in choices)
    r = random.uniform(0, total)
    upto = 0
    for c, w in choices:
        if upto + w >= r:
            return c
        upto += w
    return choices[-1][0]

def agree_adj_with_noun(adj, noun):
    p_adj = morph.parse(adj)[0]
    p_noun = morph.parse(noun)[0]
    # Согласование по роду, числу, падежу
    tags = set()
    if p_noun.tag.gender:
        tags.add(p_noun.tag.gender)
    if p_noun.tag.number:
        tags.add(p_noun.tag.number)
    if p_noun.tag.case:
        tags.add(p_noun.tag.case)
    agreed = p_adj.inflect(tags)
    if agreed:
        return agreed.word
    return adj

def generate_phrase():
    # Выбираем стартовый тег случайно
    current_tag = random.choice(list(words_by_tag.keys()))
    phrase_tags = [current_tag]
    max_len = random.randint(5, 10)
    for _ in range(max_len -1):
        choices = transitions_dict.get(current_tag)
        if not choices:
            break
        current_tag = weighted_choice(choices)
        phrase_tags.append(current_tag)

    phrase_words = []
    noun_word = None
    for tag in phrase_tags:
        word_list = words_by_tag.get(tag)
        if not word_list:
            continue
        word = random.choice(word_list)
        # Если прилагательное и есть существительное — согласуем
        if tag == "ADJ" and noun_word:
            word = agree_adj_with_noun(word, noun_word)
        if tag == "NOUN":
            noun_word = word
        phrase_words.append(word)

    phrase = ' '.join(phrase_words)
    # Заглавная буква и точка в конце
    if phrase:
        phrase = phrase[0].upper() + phrase[1:]
        if phrase[-1] not in ".!?":
            phrase += "."
    return phrase

# Генерация новых фраз
for _ in range(20):
    print(generate_phrase())







  ##  другая версия этого кода






import spacy
import random
from collections import defaultdict, Counter
import pymorphy2

# Загрузка русской модели spaCy
nlp = spacy.load("ru_core_news_sm")
morph = pymorphy2.MorphAnalyzer()

# Чтение исходного текста
with open("диалог.txt", encoding="utf-8") as f:
    text = f.read()

doc = nlp(text)

# Сбор статистики слов по POS
words_by_tag = defaultdict(set)
tag_sequences = []

for sent in doc.sents:
    tags = []
    for token in sent:
        if token.is_space:
            continue
        tags.append(token.pos_)
        words_by_tag[token.pos_].add(token.text)
    tag_sequences.append(tags)

# Преобразуем множества в списки для случайного выбора
words_by_tag = {tag: list(words) for tag, words in words_by_tag.items()}

# Подсчёт переходов между тегами
transitions = Counter()
for tags in tag_sequences:
    for i in range(len(tags) - 1):
        transitions[(tags[i], tags[i+1])] += 1

transitions_dict = defaultdict(list)
for (tag1, tag2), count in transitions.items():
    transitions_dict[tag1].append((tag2, count))

def weighted_choice(choices):
    total = sum(w for c, w in choices)
    r = random.uniform(0, total)
    upto = 0
    for c, w in choices:
        if upto + w >= r:
            return c
        upto += w
    return choices[-1][0]

def agree_adj_with_noun(adj, noun):
    p_adj = morph.parse(adj)[0]
    p_noun = morph.parse(noun)[0]
    # Согласование по роду, числу, падежу
    tags = set()
    if p_noun.tag.gender:
        tags.add(p_noun.tag.gender)
    if p_noun.tag.number:
        tags.add(p_noun.tag.number)
    if p_noun.tag.case:
        tags.add(p_noun.tag.case)
    agreed = p_adj.inflect(tags)
    if agreed:
        return agreed.word
    return adj

def generate_phrase():
    # Выбираем стартовый тег случайно
    current_tag = random.choice(list(words_by_tag.keys()))
    phrase_tags = [current_tag]
    max_len = random.randint(5, 10)
    for _ in range(max_len -1):
        choices = transitions_dict.get(current_tag)
        if not choices:
            break
        current_tag = weighted_choice(choices)
        phrase_tags.append(current_tag)

    phrase_words = []
    noun_word = None
    for tag in phrase_tags:
        word_list = words_by_tag.get(tag)
        if not word_list:
            continue
        word = random.choice(word_list)
        # Если прилагательное и есть существительное — согласуем
        if tag == "ADJ" and noun_word:
            word = agree_adj_with_noun(word, noun_word)
        if tag == "NOUN":
            noun_word = word
        phrase_words.append(word)

    phrase = ' '.join(phrase_words)
    # Заглавная буква и точка в конце
    if phrase:
        phrase = phrase[0].upper() + phrase[1:]
        if phrase[-1] not in ".!?":
            phrase += "."
    return phrase

# Генерация  фраз
for _ in range(15):
    print(generate_phrase())


Рецензии