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, logistic regression)

feature weight
is_bc_prefix +2.92
has_negation −2.76
has_wama +2.02
remaining_len −1.78
remaining_ratio −1.50
  • 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
  • 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.54% f1 (5-fold cv)
  • test suite: 231/231 (100%)

japanese

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

test coverage

thai (231 cases)

backchannels (67): ครับ, ค่ะ, อืม, ใช่, อ๋อ, เหรอ, ฮัลโหล, ฮัลโหลจ้ะพี่, ได้ไหมจ้ะ, ดี, ไม่เป็นไร, จ้ะ/จ่ะ/จ๊ะ, asr variants... dialect backchannels (48): แม่น, เด้อ, เนาะ (อีสาน) / เจ้า, ใจ้, แต๊ (เหนือ) / เหอ, หวา, แหละ (ใต้) apologies (18): ขอโทษครับ, โทษที, ลืมจริงๆ + guards (ขอโทษค่ะ อยากถามเรื่องราคา stays real) partial words (12): ฮัลโ, ครั, เจ้, โอเ + 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 (231 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.5

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.5
File Size Uploaded Provenance
backchannel_classifier-0.5.5.tar.gz 82.5 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 157.4 kB

Release files / backchannel_classifier-0.5.5.tar.gz

Download URL backchannel_classifier-0.5.5.tar.gz
Size 82.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b49bc2de123a61fffa5ce10c956e42aed0504d5ddbc5fa7e8a6eb2b93a87577c
BLAKE2b-256 checksum
How to use checksums
abededd5614e8f5b3a590dccbe5c39dc6f9cdaa24e943a752e5c512ae62e2ae7
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.5-py3-none-any.whl

Download URL backchannel_classifier-0.5.5-py3-none-any.whl
Size 74.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
011da3f7f729a43b71aa49639f1b73d592f2d9c3119c3058409be2b67168a5b1
BLAKE2b-256 checksum
How to use checksums
0bc67d733c3f1a68c580dc793ffe7a68ea83244bbd3b0849204ee0ce63523fe7
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.5

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