Spaces:
Sleeping
Sleeping
| # src/features_q4.py | |
| import re | |
| import pandas as pd | |
| # мини-словарики (можно расширять) | |
| PLACE_WORDS = r"(кухн|парк|сквер|берег|река|дом|улиц|квартир|комнат|набережн)" | |
| SEASON_WORDS = r"(лето|зим|весн|осен|снег|жарко|холодно|листопад|сосулк)" | |
| PEOPLE_WORDS = r"(мама|папа|дедушк|бабушк|женщин|мужчин|ребен|дет|сем|дочка|сын|парень|девушк)" | |
| ACTION_WORDS = r"(игра|моет|готов|накрыва|бежит|катает|кормит|сидит|спит|несет|перепрыг|гуляет)" | |
| DETAIL_WORDS = r"(одет|рост|волос|глаз|характер|возраст|пальто|рубашк|кроссовк|плать|кофт|ботинк)" | |
| PIC_INTRO = r"(на картинке|на рисунке|я вижу|изображен)" | |
| CHILDREN_Q = r"(сколько детей|детям|о них|как.*играете.*дет(ями|ьми))" | |
| FREE_TIME_Q = r"(свободн(ое|ым)\s+врем|как.*проводите.*время|выходн(ой|ые))" | |
| def q4_slot_features(df: pd.DataFrame) -> pd.DataFrame: | |
| out = df.copy() | |
| if "question_number" not in out.columns: | |
| raise ValueError("В датафрейме нет колонки 'question_number'") | |
| for col in ["question_text", "answer_text"]: | |
| if col not in out.columns: | |
| out[col] = "" # на всякий случай | |
| mask = out["question_number"] == 4 | |
| q = out.loc[mask, "question_text"].fillna("").astype(str) | |
| a = out.loc[mask, "answer_text"].fillna("").astype(str) | |
| expects_children = q.str.contains(CHILDREN_Q, case=False, regex=True) | |
| expects_free = q.str.contains(FREE_TIME_Q, case=False, regex=True) | |
| has_place_time = a.str.contains(PLACE_WORDS, case=False, regex=True) | a.str.contains(SEASON_WORDS, case=False, regex=True) | |
| has_people = a.str.contains(PEOPLE_WORDS, case=False, regex=True) | |
| has_actions = a.str_contains(ACTION_WORDS, case=False, regex=True) if hasattr(a, "str_contains") else a.str.contains(ACTION_WORDS, case=False, regex=True) | |
| has_detail = a.str.contains(DETAIL_WORDS, case=False, regex=True) | |
| answered_children = a.str.contains(r"(у меня.*дет(и|ей)|в моей семье.*дет|сын|дочк|мы.*играем)", case=False, regex=True) | |
| answered_free = a.str.contains(r"(свободн.*врем|обычно.*(в выходн|по выходн)|люблю|занимаюсь|хожу|смотрю|рисую|спорт|танц)", case=False, regex=True) | |
| non_cyr_ratio = a.apply(lambda t: (len(re.findall(r"[A-Za-z]", t)) / max(1, len(t)))) | |
| picture_first = a.str.contains(PIC_INTRO, case=False, regex=True) | |
| dont_know = a.str.contains(r"(не знаю|не понимаю|трудно сказать|не могу описать)", case=False, regex=True) | |
| slots = (has_place_time.astype(int) + has_people.astype(int) + has_actions.astype(int) + has_detail.astype(int)) | |
| slots_covered = (slots / 4.0).clip(0, 1) | |
| personal_ok = ( | |
| (expects_children & answered_children) | | |
| (expects_free & answered_free) | | |
| (~expects_children & ~expects_free) | |
| ) | |
| # создаём колонки с нулями; для Q4 — заполняем значениями | |
| cols = { | |
| "q4_slots_covered": slots_covered, | |
| "q4_has_place_time": has_place_time.astype(int), | |
| "q4_has_people": has_people.astype(int), | |
| "q4_has_actions": has_actions.astype(int), | |
| "q4_has_detail": has_detail.astype(int), | |
| "q4_expects_children": expects_children.astype(int), | |
| "q4_expects_free": expects_free.astype(int), | |
| "q4_answered_personal": personal_ok.astype(int), | |
| "q4_non_cyr_ratio": non_cyr_ratio, | |
| "q4_picture_first": picture_first.astype(int), | |
| "q4_dont_know": dont_know.astype(int), | |
| } | |
| for name, series in cols.items(): | |
| out[name] = 0 | |
| out.loc[mask, name] = series.values | |
| return out | |