Skip to content

Commit

Permalink
черновой вариант детектора гендерной самоидентификации
Browse files Browse the repository at this point in the history
  • Loading branch information
Koziev committed Jan 17, 2021
1 parent cc943d3 commit 0e8f04f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 2 deletions.
2 changes: 2 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ RUN pip install flask_sqlalchemy
RUN pip install flask_wtf
RUN pip install python-telegram-bot --upgrade
RUN pip install h5py==2.10.0
RUN pip install pyconll
RUN pip install ufal.udpipe

WORKDIR /home
ADD ruword2tags.tar.gz /home
Expand Down
76 changes: 76 additions & 0 deletions ruchatbot/bot/interlocutor_gender_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
Реализация модели для выделения признаков гендерной самоидентификации из сообщения собеседника.
TODO: подумать о переходе на полностью нейросетевую модель, чтобы учесть больше разных конструкций.
"""

import pickle
import io
import os


class InterlocutorGenderDetector:
def __init__(self):
self.name2gender = None

def load(self, models_dir):
with open(os.path.join(models_dir, 'names.pkl'), 'rb') as f:
self.name2gender = pickle.load(f)

def detect_interlocutor_gender(self, text_str, text_utils):
# Пол собеседника пока неизвестен, будем пытаться определить его из лексического и синтаксического
# содержания фразы.
parsed_data = text_utils.parse_syntax(text_str)

# Русскоязычные диалоги допускают несколько способов передать гендерную самоидентификацию.
# Проверим самые частотные.
interlocutor_gender = None

# 1. Если есть глагол в прошедшем времени в роли сказуемого и подлежащее "я", то берем его тэг грамматического
# рода.
up_words = [z.form.lower().replace('ё', 'е') for z in parsed_data]
up_lemmas = [z.lemma.lower().replace('ё', 'е') for z in parsed_data]
edges2 = []
for pred_token in parsed_data:
if pred_token.head != '0':
edges2.append((pred_token.form.lower(), parsed_data[pred_token.head].form.lower()))

if pred_token.head == '0' and pred_token.upos == 'VERB':
if text_utils.get_udpipe_attr(pred_token, 'Tense') == 'Past':
interlocutor_gender = text_utils.get_udpipe_attr(pred_token, 'Gender')
if interlocutor_gender:
return interlocutor_gender

# Конструкция "я должен/должна ... "
if 'ты' in up_words and 'должен' in up_lemmas:
if ('ты', 'должен') in edges2:
return 'Masc'
elif ('ты', 'должна') in edges2:
return 'Fem'

# Реплики с шаблоном "меня зовут Марина"
if 'тебя' in up_words and 'звать' in up_lemmas:
for word in up_words:
uword = word.lower().replace('ё', 'е')
if uword in self.name2gender:
g = self.name2gender[uword]
if g == 'm':
return 'Masc'
elif g == 'f':
return 'Fem'

return None

# Реплики с шаблоном "мое имя Олег"
if 'твое' in up_words and 'имя' in up_lemmas and ('твое', 'имя') in edges2:
for word in up_words:
uword = word.lower().replace('ё', 'е')
if uword in self.name2gender:
g = self.name2gender
if g == 'm':
return 'Masc'
elif g == 'f':
return 'Fem'

return None

return None
10 changes: 9 additions & 1 deletion ruchatbot/bot/simple_answering_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import operator
import random
import requests
import collections

from ruchatbot.bot.base_answering_machine import BaseAnsweringMachine
from ruchatbot.bot.simple_dialog_session_factory import SimpleDialogSessionFactory
Expand Down Expand Up @@ -1148,7 +1149,14 @@ def query_chitchat_service(self, bot, session, interlocutor, last_phrase):
# Взвешиваем по контексту
p_discourse = self.calc_discourse_relevance(rtext, session)

p_line = p_syntax * p_discourse
# Составные предложения (несколько клауз) будем штрафовать
t_chars = collections.defaultdict(int)
for c in rtext[:-1]:
t_chars[c] += 1
nb_clauses = t_chars['.'] + t_chars['?'] + t_chars['!']
p_clauses = math.exp(-nb_clauses)

p_line = p_syntax * p_discourse * p_clauses
ranked_lines.append((rtext, p_line))

if ranked_lines:
Expand Down
2 changes: 1 addition & 1 deletion run-service.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
docker run -p 9001:9001 -it chatbot bash -c "/chatbot/scripts/flask_bot.sh"
sudo docker run -p 9001:9001 -it chatbot bash -c "/chatbot/scripts/flask_bot.sh"

0 comments on commit 0e8f04f

Please sign in to comment.