ErzhanAb commited on
Commit
41796ea
·
verified ·
1 Parent(s): af1fd59

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -53
app.py CHANGED
@@ -23,11 +23,12 @@ def clean_text(s: str) -> str:
23
  return s
24
 
25
  # ---------------------------------
26
- # 2) Загрузка пайплайна и конфига (без изменений)
27
  # ---------------------------------
28
  PIPE = joblib.load("model.joblib")
29
 
30
- DEFAULT_THRESHOLD = 0.4
 
31
  try:
32
  with open("config.json", "r", encoding="utf-8") as f:
33
  cfg = json.load(f)
@@ -36,35 +37,35 @@ except Exception:
36
  pass
37
 
38
  # ---------------------------------
39
- # 3) Обновленный инференс для нового интерфейса
40
  # ---------------------------------
41
  def predict(comment: str, threshold: float):
42
  """
43
- Функция инференса, адаптированная для вывода в компонент gr.Label.
44
- Возвращает словарь {метка: вероятность}.
 
 
45
  """
46
  if not comment or not comment.strip():
47
- return None # Возвращаем None, чтобы очистить поле вывода
 
48
 
49
  proba_toxic = float(PIPE.predict_proba([comment])[0, 1])
50
  proba_not_toxic = 1 - proba_toxic
 
 
 
 
 
 
 
 
 
51
 
52
- # gr.Label автоматически выделит класс с большей вероятностью,
53
- # но мы также можем сделать это наглядно, сравнив с порогом.
54
- # Для простоты и наглядности, вернем вероятности для обоих классов.
55
- # Компонент gr.Label сам подсветит тот, у которого значение выше.
56
- if proba_toxic >= threshold:
57
- # Если превышен порог, то "Токсичный" должен быть основным результатом
58
- return {"Токсичный": proba_toxic, "Не токсичный": proba_not_toxic}
59
- else:
60
- # Иначе - "Не токсичный"
61
- return {"Не токсичный": proba_not_toxic, "Токсичный": proba_toxic}
62
-
63
  # ---------------------------------
64
- # 4) Новый стильный и минималистичный интерфейс на gr.Blocks
65
  # ---------------------------------
66
 
67
- # Описание выносим в отдельную переменную для чистоты
68
  TITLE = "Анализатор токсичности комментариев"
69
  DESCRIPTION = "Введите комментарий на русском языке, чтобы определить его токсичность. Модель вернет вероятность принадлежности к классу 'Токсичный'."
70
  ARTICLE = """
@@ -75,13 +76,18 @@ ARTICLE = """
75
  * **Разработано для**: Демонстрации работы простой, но эффективной baseline-модели.
76
  """
77
 
78
- # Используем gr.Blocks для кастомного дизайна
79
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky")) as demo:
80
- # Заголовок и описание
 
 
 
 
 
 
81
  gr.Markdown(f"# {TITLE}")
82
  gr.Markdown(DESCRIPTION)
83
 
84
- # Основная раскладка в две колонки
85
  with gr.Row():
86
  # Левая колонка для ввода
87
  with gr.Column(scale=2):
@@ -90,61 +96,46 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky")) as
90
  lines=5,
91
  placeholder="Напр��мер: Ты полный идиот!",
92
  )
93
-
94
  with gr.Row():
95
  clear_btn = gr.Button("Очистить", variant="secondary")
96
  analyze_btn = gr.Button("Анализ", variant="primary")
97
-
98
- # Примеры для быстрого тестирования
99
- gr.Examples(
100
- examples=[
101
- "Ты полный идиот!",
102
- "Спасибо большое за помощь!",
103
- "Посмотри это <url> и скажи, что думаешь",
104
- "Что за бред ты несешь?",
105
- "Отличная работа, продолжайте в том же духе!",
106
- ],
107
- inputs=comment_input,
108
- )
109
 
110
  # Правая колонка для вывода
111
  with gr.Column(scale=1):
112
- result_label = gr.Label(label="Результат", num_top_classes=2)
113
-
114
- # Выпадающий блок с настройками
115
  with gr.Accordion("Настройки", open=False):
116
  threshold_slider = gr.Slider(
117
- minimum=0.0,
118
- maximum=1.0,
119
- value=DEFAULT_THRESHOLD,
120
- step=0.01,
121
  label="Порог классификации",
122
  info="Комментарий считается токсичным, если вероятность превышает это значение."
123
  )
124
 
125
- # Техническая информация о модели в самом низу
126
  gr.Markdown(ARTICLE)
127
 
128
  # --- Логика взаимодействия компонентов ---
129
 
130
- # Функция для очистки полей
131
  def clear_all():
132
- return "", None # Очищает текстовое поле и поле с результатом
133
 
134
- # Привязка функций к кнопкам и событиям
135
  analyze_btn.click(
136
  fn=predict,
137
  inputs=[comment_input, threshold_slider],
138
- outputs=result_label
139
  )
140
- # Также запускаем анализ по нажатию Enter в текстовом поле
141
  comment_input.submit(
142
  fn=predict,
143
  inputs=[comment_input, threshold_slider],
144
- outputs=result_label
 
 
 
 
 
145
  )
146
- clear_btn.click(fn=clear_all, inputs=[], outputs=[comment_input, result_label])
147
-
148
 
149
  if __name__ == "__main__":
150
- demo.launch(debug=True) # debug=True помогает при отладке
 
23
  return s
24
 
25
  # ---------------------------------
26
+ # 2) Загрузка пайплайна и конфига (порог изменен)
27
  # ---------------------------------
28
  PIPE = joblib.load("model.joblib")
29
 
30
+ # Устанавливаем новый порог по умолчанию
31
+ DEFAULT_THRESHOLD = 0.5
32
  try:
33
  with open("config.json", "r", encoding="utf-8") as f:
34
  cfg = json.load(f)
 
37
  pass
38
 
39
  # ---------------------------------
40
+ # 3) Инференс, возвращающий вердикт и вероятности отдельно
41
  # ---------------------------------
42
  def predict(comment: str, threshold: float):
43
  """
44
+ Возвращает три значения:
45
+ 1. Вердикт (строка) на основе порога.
46
+ 2. Вероятности (словарь) для gr.Label.
47
+ 3. Вероятность токсичности (число) для наглядности.
48
  """
49
  if not comment or not comment.strip():
50
+ # Возвращаем пустые значения для всех трех полей вывода
51
+ return "", None, None
52
 
53
  proba_toxic = float(PIPE.predict_proba([comment])[0, 1])
54
  proba_not_toxic = 1 - proba_toxic
55
+
56
+ # 1. Определяем вердикт на основе порога
57
+ verdict = "Токсичный" if proba_toxic >= threshold else "Не токсичный"
58
+
59
+ # 2. Готовим словарь для gr.Label
60
+ probabilities = {"Токсичный": proba_toxic, "Не токсичный": proba_not_toxic}
61
+
62
+ # 3. Возвращаем все три результата
63
+ return verdict, probabilities, proba_toxic
64
 
 
 
 
 
 
 
 
 
 
 
 
65
  # ---------------------------------
66
+ # 4) Обновленный интерфейс с кастомным шрифтом и рабочим порогом
67
  # ---------------------------------
68
 
 
69
  TITLE = "Анализатор токсичности комментариев"
70
  DESCRIPTION = "Введите комментарий на русском языке, чтобы определить его токсичность. Модель вернет вероятность принадлежности к классу 'Токсичный'."
71
  ARTICLE = """
 
76
  * **Разработано для**: Демонстрации работы простой, но эффективной baseline-модели.
77
  """
78
 
79
+ # CSS для подключения и применения шрифта "Inter"
80
+ CUSTOM_CSS = """
81
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
82
+ gradio-app {
83
+ font-family: 'Inter', sans-serif;
84
+ }
85
+ """
86
+
87
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"), css=CUSTOM_CSS) as demo:
88
  gr.Markdown(f"# {TITLE}")
89
  gr.Markdown(DESCRIPTION)
90
 
 
91
  with gr.Row():
92
  # Левая колонка для ввода
93
  with gr.Column(scale=2):
 
96
  lines=5,
97
  placeholder="Напр��мер: Ты полный идиот!",
98
  )
 
99
  with gr.Row():
100
  clear_btn = gr.Button("Очистить", variant="secondary")
101
  analyze_btn = gr.Button("Анализ", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
  # Правая колонка для вывода
104
  with gr.Column(scale=1):
105
+ verdict_output = gr.Textbox(label="Вердикт (с учетом порога)", interactive=False)
106
+ probabilities_output = gr.Label(label="Распределение вероятностей", num_top_classes=2)
107
+
108
  with gr.Accordion("Настройки", open=False):
109
  threshold_slider = gr.Slider(
110
+ minimum=0.0, maximum=1.0, value=DEFAULT_THRESHOLD, step=0.01,
 
 
 
111
  label="Порог классификации",
112
  info="Комментарий считается токсичным, если вероятность превышает это значение."
113
  )
114
 
 
115
  gr.Markdown(ARTICLE)
116
 
117
  # --- Логика взаимодействия компонентов ---
118
 
119
+ # Обновленная функция очистки для трех полей вывода
120
  def clear_all():
121
+ return "", "", None
122
 
123
+ # Привязываем predict к трем компонентам вывода
124
  analyze_btn.click(
125
  fn=predict,
126
  inputs=[comment_input, threshold_slider],
127
+ outputs=[verdict_output, probabilities_output]
128
  )
 
129
  comment_input.submit(
130
  fn=predict,
131
  inputs=[comment_input, threshold_slider],
132
+ outputs=[verdict_output, probabilities_output]
133
+ )
134
+ clear_btn.click(
135
+ fn=clear_all,
136
+ inputs=[],
137
+ outputs=[comment_input, verdict_output, probabilities_output]
138
  )
 
 
139
 
140
  if __name__ == "__main__":
141
+ demo.launch()