File size: 7,634 Bytes
cd9ea1c
d59ffef
 
 
 
cd9ea1c
d59ffef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cd9ea1c
d59ffef
 
 
 
 
 
 
 
 
 
 
71fe5dc
 
 
 
 
 
 
 
 
 
 
 
 
 
d59ffef
 
 
 
 
 
 
 
5829a54
d59ffef
71fe5dc
 
 
 
d59ffef
71fe5dc
d59ffef
 
 
 
 
 
71fe5dc
d59ffef
 
 
 
 
 
 
 
cd9ea1c
d59ffef
71fe5dc
d59ffef
71fe5dc
 
d59ffef
71fe5dc
d59ffef
 
71fe5dc
 
d59ffef
 
 
71fe5dc
 
965b4c8
71fe5dc
 
 
d59ffef
71fe5dc
 
 
 
d59ffef
 
71fe5dc
 
 
 
 
d59ffef
 
 
71fe5dc
d59ffef
 
 
71fe5dc
 
d59ffef
 
71fe5dc
d59ffef
 
71fe5dc
d59ffef
 
 
71fe5dc
d59ffef
 
 
 
 
5829a54
d59ffef
 
 
 
5829a54
cd9ea1c
d59ffef
71fe5dc
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from pyvis.network import Network
import pandas as pd
import pymorphy3
import re
import gradio as gr

# Инициализация pymorphy3 (лемматизатор)
morph = pymorphy3.MorphAnalyzer()

# Функция токенизации и лемматизации
def tokenize_and_lemmatize(text):
    text = re.sub(r'[^\w\s]', '', text.lower())  # Удаляем пунктуацию, приводим к нижнему регистру
    words = text.split()
    return [morph.parse(word)[0].normal_form for word in words]

# Словарь ключевых слов для каждого сегмента (каждое слово в начальной форме)
personalization_keywords = {
    "Поколение X": ["комиссия", "визит", "снижение", "ставка", "бесплатно", "экономия"],
    "Поколение Y": ["онлайн", "цифровой", "бонус", "лимит", "qr", "sberpay"],
    "Поколение Z": ["быстрота", "мгновенно", "минута", "оперативно", "решение"],
    "Пол Женский": ["комфорт", "удобство", "забота", "легкость", "терминал"],
    "ОПФ ИП": ["эффективность", "комиссия", "снижение", "ставка", "онлайн", "быстрота", "оптимизация"],
    "ОПФ ООО": ["удобство", "комиссия", "открытие", "онлайн", "легкость", "автоматизация"],
    "Психотип Конструктор": ["оптимизация", "снижение", "ставка", "комиссия", "льготный", "период", "выгодно", "настройка"],
    "Пол Мужской": ["динамичность", "быстрота", "лимит", "решение", "активность", "оптимизация"],
    "Стадия бизнеса Новичок": ["доступность", "простота", "низкий", "порог", "комиссия", "легкость"],
    "Стадия бизнеса Профи": ["профессионализм", "комиссия", "снижение", "ставка", "оптимизация", "эффективность", "быстрота"],
    "Психотип Рефлектор": ["премиальность", "эксклюзив", "бизнес", "зал", "акция", "привилегия", "статус"],
    "Психотип Центрист": ["универсальность", "стандарт", "комиссия", "бесплатно", "надежность"],
    "Стадия бизнеса Эксперт": ["максимизация", "высокий", "лимит", "снижение", "ставка", "комиссия", "выгода", "оптимизация"]
}

# Глобальная переменная для хранения DataFrame
df = None

def load_excel(file):
    global df
    if file is None:
        return [], "Файл не загружен. Загрузите Excel-файл."
    try:
        df = pd.read_excel(file.name, usecols=["Продукт", "Преимущество"])
        unique_products = df["Продукт"].unique().tolist()
        return unique_products, "Файл успешно загружен!"
    except Exception as e:
        return [], f"Ошибка при чтении файла: {str(e)}"

def classify_advantage(text, keywords_dict):
    lemmas = tokenize_and_lemmatize(text)
    category_matches = {}

    for category, keywords in keywords_dict.items():
        matches = set(lemmas) & set(keywords)
        if matches:
            category_matches[category] = {
                'count': len(matches),
                'matched_lemmas': matches
            }

    sorted_matches = sorted(category_matches.items(), key=lambda x: x[1]['count'], reverse=True)
    return sorted_matches

def analyze(product):
    global df
    if df is None:
        return "Сначала загрузите файл.", None

    if not product:
        return "Пожалуйста, выберите продукт.", None

    product_advantages = df[df["Продукт"] == product]["Преимущество"]

    if product_advantages.empty:
        return "Для выбранного продукта не найдено преимуществ.", None

    graph_html = create_category_graph(product, product_advantages, personalization_keywords)

    results = []
    for advantage in product_advantages:
        matches = classify_advantage(advantage, personalization_keywords)
        advantage_text = f"**Преимущество**: {advantage}\n\n"
        advantage_text += f"**Леммы**: {tokenize_and_lemmatize(advantage)}\n\n"
        advantage_text += "**Совпадающие категории:**\n"

        if matches:
            for category, data in matches:
                matched_lemmas_str = ", ".join(sorted(data['matched_lemmas']))
                advantage_text += f"- {category}: {data['count']} совпадений (леммы: {matched_lemmas_str})\n"
        else:
            advantage_text += "- Нет совпадений.\n"
        advantage_text += "\n---\n"
        results.append(advantage_text)

    return "\n".join(results), graph_html

def create_category_graph(product, advantages, personalization_keywords):
    net = Network(height="500px", width="100%", directed=True, cdn_resources='in_line')

    net.add_node(product, label=product, color="lightblue", size=30)

    for advantage in advantages:
        net.add_node(advantage, label=advantage, color="orange", size=20)
        net.add_edge(product, advantage)

        matches = classify_advantage(advantage, personalization_keywords)
        for category, data in matches:
            net.add_node(category, label=category, color="green", size=15)
            net.add_edge(advantage, category)

    html = net.generate_html(notebook=False)
    html_escaped = html.replace('"', '"').replace("'", "'")

    iframe_html = f"""
    <iframe 
        width="100%" 
        height="600" 
        frameborder="0" 
        srcdoc="{html_escaped}">
    </iframe>
    """

    print("Generated HTML:", iframe_html[:500])  # Выводим первые 500 символов для отладки

    return iframe_html

with gr.Blocks() as demo:
    gr.Markdown("## Классификация преимуществ по признакам персонализации")
    gr.Markdown("**Шаг 1:** Загрузите Excel-файл с двумя столбцами: 'Продукт' и 'Преимущество'.")

    file_input = gr.File(label="Загрузите Excel-файл", file_types=[".xlsx"])
    load_button = gr.Button("Загрузить файл")
    load_status = gr.Markdown("")

    gr.Markdown("**Шаг 2:** Выберите продукт из списка.")
    product_dropdown = gr.Dropdown(choices=[], label="Продукты", value=None)
    analyze_button = gr.Button("Анализировать")

    output_text = gr.Markdown("")
    output_graph = gr.HTML(label="Визуализация графа")

    def on_file_upload(file):
        unique_products, status_message = load_excel(file)
        return gr.update(choices=unique_products), status_message

    load_button.click(
        fn=on_file_upload,
        inputs=file_input,
        outputs=[product_dropdown, load_status]
    )

    analyze_button.click(
        fn=analyze,
        inputs=product_dropdown,
        outputs=[output_text, output_graph]
    )

if __name__ == "__main__":
    demo.launch(debug=True)