Audio-EvalBot / research /text_features.py
norhan12's picture
EvalBot platform: accounts, mock interviews for 30 tracks, hiring interviews, human-calibrated scores, React web app
7804693 verified
Raw History Blame Contribute Delete
2.21 kB
"""Lexical features from the interviewee's words (computable from any transcript)."""
import re
import numpy as np
FILLERS = re.compile(r"\b(um+|uh+|uhm+|er+|ah+|hmm+|like|you know|i mean|kind of|sort of|basically|actually)\b")
POS = set("good great love enjoy excited happy interesting passion passionate fun amazing excellent best success successful proud glad".split())
NEG = set("bad hard difficult problem problems stress stressed worried hate fail failed failure wrong sorry unfortunately".split())
TENTATIVE = set("maybe perhaps guess probably possibly somewhat seems".split())
WE = {"we", "us", "our", "team", "together"}
I = {"i", "me", "my", "i'm", "i've", "myself"}
def interviewee_turns(transcript: str):
turns = []
for t in transcript.split("|"):
if ":" in t:
who, text = t.split(":", 1)
if who.strip().lower().startswith("interviewee"):
turns.append(re.sub(r"\[.*?\]", " ", text).strip())
return [t for t in turns if t]
def text_features(turns):
text = " ".join(turns).lower()
words = re.findall(r"[a-z']+", text)
n = max(len(words), 1)
sents = [s for s in re.split(r"[.!?]+", text) if s.strip()]
uniq = len(set(words))
return {
"txt_words": len(words),
"txt_words_per_turn": len(words) / max(len(turns), 1),
"txt_type_token": uniq / n,
"txt_unique_words": uniq,
"txt_filler_rate": len(FILLERS.findall(text)) / n,
"txt_i_rate": sum(w in I for w in words) / n,
"txt_we_rate": sum(w in WE for w in words) / n,
"txt_pos_rate": sum(w in POS for w in words) / n,
"txt_neg_rate": sum(w in NEG for w in words) / n,
"txt_tentative_rate": sum(w in TENTATIVE for w in words) / n,
"txt_number_rate": len(re.findall(r"\b\d+\b|\b(one|two|three|four|five|ten|hundred|percent)\b", text)) / n,
"txt_avg_word_len": float(np.mean([len(w) for w in words])) if words else 0,
"txt_avg_sentence_len": len(words) / max(len(sents), 1),
"txt_long_word_rate": sum(len(w) >= 7 for w in words) / n,
"txt_because_rate": len(re.findall(r"\b(because|so that|therefore|which meant|as a result)\b", text)) / n,
}