"""Classify the bundled synthetic messages. Python standard library only.""" from pathlib import Path from datetime import datetime,timezone,timedelta import argparse import hashlib import json import platform KEYWORDS = [ ['料金','請求','支払','領収','課金','返金','解約','価格','金額','引き落と'], ['ログイン','パスワード','認証','アカウント','サインイン','本人確認','ID','コード'], ['画面','保存','ファイル','アプリ','検索','エラー','アップロード','印刷','表示','動画','ボタン'], ] def rule_v1(text): for label, words in enumerate(KEYWORDS): if any(word in text for word in words): return label return -1 def rule_v2(text): focus=text for marker in ['ありませんが、','できますが、','正常ですが、','後に']: if marker in focus: focus=focus.split(marker)[-1] return rule_v1(focus) def trace(text,version): focus=text;applied=[] if version=='v2': for marker in ['ありませんが、','できますが、','正常ですが、','後に']: if marker in focus: focus=focus.split(marker)[-1];applied.append(marker) label=rule_v1(focus) return {'focus':focus,'appliedMarkers':applied,'firstMatchedWords':[] if label==-1 else [w for w in KEYWORDS[label] if w in focus]} def run(data_path,location='local CPU'): raw=data_path.read_bytes();data=json.loads(raw) scores={} for version,predict in [('v1',rule_v1),('v2',rule_v2)]: scores[version]={} for split in ['dev','test']: cases=[] for text,gold in data[split]: prediction=predict(text);detail=trace(text,version) assert prediction==rule_v1(detail['focus']) cases.append({'text':text,'expected':gold,'predicted':prediction,'correct':prediction==gold,**detail}) scores[version][split]={'correct':sum(x['correct'] for x in cases),'total':len(cases),'unclassified':sum(x['predicted']==-1 for x in cases),'cases':cases} changes=[{'text':a['text'],'before':a['predicted'],'after':b['predicted'],'expected':a['expected']} for a,b in zip(scores['v1']['test']['cases'],scores['v2']['test']['cases']) if a['predicted']!=b['predicted']] return {'completedAt':datetime.now(timezone.utc).isoformat(),'measurementDateJST':datetime.now(timezone(timedelta(hours=9))).date().isoformat(),'location':location,'platform':platform.system(),'python':platform.python_version(), 'scriptSha256':hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),'datasetSha256':hashlib.sha256(raw).hexdigest(), 'labels':data['labels'],'keywords':KEYWORDS,'markers':['ありませんが、','できますが、','正常ですが、','後に'], 'dataStatus':data['evaluationStatus'],'trainingUsed':False,'classifierModelUsed':False,'scores':scores,'testPredictionChanges':changes, 'markerSupportInDev':{m:sum(m in text for text,_ in data['dev']) for m in ['ありませんが、','できますが、','正常ですが、','後に']}} if __name__=='__main__': parser=argparse.ArgumentParser();parser.add_argument('--data',default=str(Path(__file__).with_name('dataset.json')));parser.add_argument('--out',default='rules-results-local.json');parser.add_argument('--location',default='local CPU');args=parser.parse_args() result=run(Path(args.data),args.location);Path(args.out).write_text(json.dumps(result,ensure_ascii=False,indent=2,allow_nan=False)+'\n') scores={v:{s:(r['correct'],r['total']) for s,r in splits.items()} for v,splits in result['scores'].items()} print(json.dumps({'saved':args.out,'scores':scores},ensure_ascii=False))