Skip to main content

backchannel classifier

detects backchannel responses vs real user input for voice ai systems. supports thai (standard + อีสาน/เหนือ/ใต้ dialects) and japanese (aizuchi).

install

pip install backchannel-classifier

usage

from backchannel_classifier import is_backchannel

# thai (default)
is_backchannel("ครับ")                    # (True, 0.91)
is_backchannel("ไม่ครับ")                 # (False, 0.01)
is_backchannel("ใช่ แต่ว่า")              # (False, 0.01)

# thai dialects
is_backchannel("แม่นเด้อ")                # (True, 0.99)   อีสาน (isan)
is_backchannel("เจ้า")                    # (True, 0.99)   เหนือ (northern)
is_backchannel("จริงเหอ")                 # (True, 0.99)   ใต้ (southern)
is_backchannel("บ่ได้ครับ")               # (False, 0.001) isan negation = real response
is_backchannel("สวัสดีเจ้า")              # (False, 0.0001) northern greeting = real response

# japanese
is_backchannel("はい", lang="ja")         # (True, 0.99)
is_backchannel("そうですね", lang="ja")    # (True, 0.99)
is_backchannel("予約したいです", lang="ja") # (False, 0.0001)

# direct import
from backchannel_classifier.jp import is_backchannel_ja
is_backchannel_ja("なるほど")              # (True, 0.99)

returns (is_backchannel: bool, confidence: float).

why

voice bots using asr → llm → tts pipelines need to distinguish between backchannels (acknowledgment sounds that should be ignored) and real responses that need processing. simple exact matching fails on asr variants and misses edge cases.

approach

small sklearn classifier (best of logistic regression / gradient boosting per training run) with handcrafted language-specific features. key idea: strip known backchannel components from the text, measure what's left (remaining_ratio). if nothing remains, it's a backchannel.

thai (29 features, gradient boosting)

feature importance
remaining_ratio 0.4736
remaining_len 0.3189
is_bc_prefix 0.0953
has_negation 0.0659
has_wama 0.0167
  • polite particle detection (ครับ/ค่ะ/จ้ะ variants)
  • backchannel sound patterns (อืม/อ๋อ/เออ with tone variants)
  • question/negation/request/continuation markers
  • handles asr misspellings (ค่า→ค่ะ, คับ→ครับ, อื้ม→อืม)
  • handles streaming asr partial words (ฮัลโ→ฮัลโหล, ครั→ครับ) — fragments that are prefixes of known backchannels, with guards so real words (ไม่, สวัสดี) never match
  • handles asr aborted-word markers (อ่า ใน-, ฮัลโ-) — trailing-hyphen fragments are ignorable unless they signal negation/request (ไม่-, ขอ- stay real)
  • apology pleasantries are ignorable (ขอโทษครับ, โทษที, ค่ะ ขอโทษทีค่ะ ลืมจริงๆ ค่ะ) — but apology + content stays real (ขอโทษค่ะ อยากถามเรื่องราคา, ลืมรหัสผ่านค่ะ)
  • dialect support:
    • อีสาน (isan): แม่น, เด้อ, เนาะ, โดย, อีหลี + บ่ negation, ไส/หยัง/ใด๋ questions
    • เหนือ (northern): เจ้า, ใจ้/ใจ่, แต๊, เน้อ, กา tags
    • ใต้ (southern): เหอ/หอ/หวา tags, แหละ, พันนั้นแหละ + พรื่อ questions

japanese (27 features)

feature importance
remaining_ratio 0.7765
remaining_len 0.0484
katakana 0.0347
word_count 0.0325
kanji_ratio 0.0206
  • core aizuchi (はい/ええ/うん/そう)
  • agreement, understanding, surprise, filler, reaction markers
  • question/continuation/request/negation/verb negative indicators
  • handles asr elongation variants (はーーい, えーーー)

results

thai

  • 99.71% f1 (5-fold cv)
  • test suite: 238/238 (100%)

japanese

  • 98.37% f1 (5-fold cv)
  • test suite: 119/119 (100%)

test coverage

thai (238 cases)

backchannels (67): ครับ, ค่ะ, อืม, ใช่, อ๋อ, เหรอ, ฮัลโหล, ฮัลโหลจ้ะพี่, ได้ไหมจ้ะ, ดี, ไม่เป็นไร, จ้ะ/จ่ะ/จ๊ะ, asr variants... dialect backchannels (48): แม่น, เด้อ, เนาะ (อีสาน) / เจ้า, ใจ้, แต๊ (เหนือ) / เหอ, หวา, แหละ (ใต้) apologies (18): ขอโทษครับ, โทษที, ลืมจริงๆ + guards (ขอโทษค่ะ อยากถามเรื่องราคา stays real) partial + aborted words (19): ฮัลโ, ครั, เจ้, โอเ, อ่า ใน-, ฮัลโ- + guards (ไม่, สวัส, ไม่-, ขอ- stay real) real responses (78): สวัสดีครับ, ไม่ครับ, ราคาเท่าไหร่ครับ, ขอเปลี่ยนวันได้ไหมค่ะ, พี่คะ อยากถามหน่อยค่ะ, dialect (บ่ได้ครับ, สวัสดีเจ้า, ว่าพรื่อครับ), edge cases (ใช่ แต่ว่า, แม่น แต่ว่า)...

japanese (119 cases)

aizuchi (63): はい, うん, そうですね, なるほど, へー, まじで, えーと, すごい, 承知しました, compounds... real responses (56): ありがとうございます, いくらですか, 予約したいです, edge cases (はい、質問があります, そうですね、でも...)...

testing

python3 -m pytest tests/ -v

files

  • backchannel_classifier/__init__.py - thai classifier + unified api
  • backchannel_classifier/jp.py - japanese classifier
  • backchannel_classifier/train_data_th.py - thai training data (packaged for sklearn-mismatch retrain)
  • backchannel_classifier/train_data_ja.py - japanese training data (packaged for sklearn-mismatch retrain)
  • train.py - thai training script
  • train_ja.py - japanese training script
  • tests/test_classifier.py - thai test suite (238 cases, incl. อีสาน/เหนือ/ใต้ dialects + asr partials + apologies)
  • tests/test_classifier_ja.py - japanese test suite (119 cases)

requirements

  • python 3.8+
  • scikit-learn
  • numpy

memory

~3.7 MB per language model, lazy-loaded. if you only use thai, japanese model is never loaded (zero overhead).

Metadata

Release files for backchannel-classifier 0.5.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for backchannel-classifier 0.5.6
File Size Uploaded Provenance
backchannel_classifier-0.5.6.tar.gz 173.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for backchannel-classifier 0.5.6
File Interpreter ABI Platform
backchannel_classifier-0.5.6-py3-none-any.whl Python 3 none any Details

Total release size: 293.7 kB

Release files / backchannel_classifier-0.5.6.tar.gz

Download URL backchannel_classifier-0.5.6.tar.gz
Size 173.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5c1d8ef40ee68fb8ad32c2281f7f77985bb875bfdfd58ec5898dc89eedffdc06
BLAKE2b-256 checksum
How to use checksums
f280569dfc5318c3fefc4b72f000a3944b42a4c2fb06833aab2f29ea6e6e4446
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / backchannel_classifier-0.5.6-py3-none-any.whl

Download URL backchannel_classifier-0.5.6-py3-none-any.whl
Size 120.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76ca9b3f464d68d0b23f1637d6546d5b95dab3c5482e4c86cf3934672b22512d
BLAKE2b-256 checksum
How to use checksums
60a86605c6e813160c6d02746ad6648831aa1d1b3b66a6b70f20bf4674763a28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Security for backchannel-classifier 0.5.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page