Corin1998 commited on
Commit
8b06bd8
·
verified ·
1 Parent(s): fda280c

Delete es_advanced_elauator.py

Browse files
Files changed (1) hide show
  1. es_advanced_elauator.py +0 -279
es_advanced_elauator.py DELETED
@@ -1,279 +0,0 @@
1
- # es_advanced_evaluator.py
2
- from typing import List, Dict, Any, Optional
3
- import re
4
-
5
- from transformers import (
6
- AutoTokenizer,
7
- AutoModelForSequenceClassification,
8
- pipeline,
9
- )
10
-
11
- # =========================
12
- # モデル定義(Hugging Face)
13
- # =========================
14
-
15
- # 日本語感情分析モデル
16
- SENTIMENT_MODEL_NAME = "koheiduck/bert-japanese-finetuned-sentiment"
17
- # 多言語ゼロショット分類モデル(STAR分類・トーン評価用)
18
- NLI_MODEL_NAME = "joeddav/xlm-roberta-large-xnli"
19
-
20
- # 必要に応じて device=0 (GPU) に変更してください
21
- sentiment_classifier = pipeline(
22
- "sentiment-analysis",
23
- model=SENTIMENT_MODEL_NAME,
24
- tokenizer=SENTIMENT_MODEL_NAME,
25
- )
26
-
27
- zero_shot_classifier = pipeline(
28
- "zero-shot-classification",
29
- model=NLI_MODEL_NAME,
30
- tokenizer=NLI_MODEL_NAME,
31
- )
32
-
33
-
34
- # =========================
35
- # ユーティリティ
36
- # =========================
37
-
38
- _SENT_SPLIT_RE = re.compile(r"[。!?\n]+")
39
-
40
-
41
- def split_sentences(text: str) -> List[str]:
42
- """日本語の文をざっくり分割する簡易関数"""
43
- sentences = [s.strip() for s in _SENT_SPLIT_RE.split(text) if s.strip()]
44
- return sentences
45
-
46
-
47
- # =========================
48
- # 感情・トーン分析
49
- # =========================
50
-
51
- def analyze_sentiment(text: str) -> Dict[str, Any]:
52
- """
53
- 日本語テキストのネガポジ分析。
54
- 出力例:
55
- {
56
- "label": "POSITIVE",
57
- "score": 0.98
58
- }
59
- """
60
- if not text.strip():
61
- return {"label": "NEUTRAL", "score": 0.0}
62
-
63
- result = sentiment_classifier(text)[0]
64
- return {
65
- "label": result["label"],
66
- "score": float(result["score"]),
67
- }
68
-
69
-
70
- def analyze_tone(text: str) -> Dict[str, Any]:
71
- """
72
- ゼロショット分類で「熱意・主体性・一貫性・論理性・協調性」などをスコアリング。
73
- multi_label=True なので、1文が複数のトーンを兼ねることも許容。
74
- 出力例:
75
- {
76
- "labels": {
77
- "熱意": 0.92,
78
- "主体性": 0.81,
79
- "一貫性": 0.55,
80
- "論理性": 0.73,
81
- "協調性": 0.40
82
- }
83
- }
84
- """
85
- if not text.strip():
86
- return {"labels": {}}
87
-
88
- tone_labels = ["熱意", "主体性", "一貫性", "論理性", "協調性"]
89
-
90
- result = zero_shot_classifier(
91
- text,
92
- candidate_labels=tone_labels,
93
- multi_label=True,
94
- )
95
-
96
- label_scores = {
97
- label: float(score)
98
- for label, score in zip(result["labels"], result["scores"])
99
- }
100
-
101
- ordered = {label: label_scores.get(label, 0.0) for label in tone_labels}
102
-
103
- return {"labels": ordered}
104
-
105
-
106
- # =========================
107
- # STAR 構造分析
108
- # =========================
109
-
110
- STAR_LABELS_JP = [
111
- "Situation(状況)",
112
- "Task(課題)",
113
- "Action(行動)",
114
- "Result(結果)",
115
- "Other(その他)",
116
- ]
117
-
118
- STAR_KEY_MAP = {
119
- "Situation(状況)": "S",
120
- "Task(課題)": "T",
121
- "Action(行動)": "A",
122
- "Result(結果)": "R",
123
- "Other(その他)": "O",
124
- }
125
-
126
-
127
- def classify_sentence_star(sentence: str) -> Dict[str, Any]:
128
- """
129
- 1文を STAR のどれに近いかゼロショット分類する。
130
- multi_label=False とし、最も近いラベルのみ採用。
131
- 出力例:
132
- {
133
- "sentence": "...",
134
- "star_label": "S",
135
- "raw_label": "Situation(状況)",
136
- "score": 0.87
137
- }
138
- """
139
- if not sentence.strip():
140
- return {
141
- "sentence": sentence,
142
- "star_label": "O",
143
- "raw_label": "Other(その他)",
144
- "score": 0.0,
145
- }
146
-
147
- result = zero_shot_classifier(
148
- sentence,
149
- candidate_labels=STAR_LABELS_JP,
150
- multi_label=False,
151
- )
152
- raw_label = result["labels"][0]
153
- score = float(result["scores"][0])
154
- star_label = STAR_KEY_MAP.get(raw_label, "O")
155
-
156
- return {
157
- "sentence": sentence,
158
- "star_label": star_label,
159
- "raw_label": raw_label,
160
- "score": score,
161
- }
162
-
163
-
164
- def analyze_star_structure(text: str) -> Dict[str, Any]:
165
- """
166
- 自己PRテキストの STAR 構造(S/T/A/R がどの程度含まれているか)を分析。
167
- 出力例:
168
- {
169
- "coverage": {
170
- "S": true,
171
- "T": true,
172
- "A": true,
173
- "R": false
174
- },
175
- "star_score": 0.75,
176
- "per_sentence": [...],
177
- "missing_elements": ["R"],
178
- "comment": "結果(Result)の記述が弱いため、成果をより具体的に書くと良いです。"
179
- }
180
- """
181
- sentences = split_sentences(text)
182
- if not sentences:
183
- return {
184
- "coverage": {k: False for k in ["S", "T", "A", "R"]},
185
- "star_score": 0.0,
186
- "per_sentence": [],
187
- "missing_elements": ["S", "T", "A", "R"],
188
- "comment": "文章が空か極端に短いため、STAR 構造の判定ができません。",
189
- }
190
-
191
- per_sentence_results = [
192
- classify_sentence_star(s) for s in sentences
193
- ]
194
-
195
- coverage = {k: False for k in ["S", "T", "A", "R"]}
196
- for r in per_sentence_results:
197
- key = r["star_label"]
198
- if key in coverage:
199
- coverage[key] = True
200
-
201
- missing = [k for k, v in coverage.items() if not v]
202
- star_score = sum(1 for v in coverage.values() if v) / 4.0
203
-
204
- # コメント生成(シンプルなヒューリスティック)
205
- if not missing:
206
- comment = "STAR の各要素(状況・課題・行動・結果)が一通り含まれています。構成としてバランスは良好です。"
207
- else:
208
- parts = []
209
- mapping_jp = {"S": "状況(Situation)", "T": "課題(Task)", "A": "行動(Action)", "R": "結果(Result)"}
210
- for m in missing:
211
- parts.append(mapping_jp[m])
212
- missing_jp = "・".join(parts)
213
- comment = (
214
- f"{missing_jp} の要素が弱い/不足しています。"
215
- "不足している要素を具体的に書き足すと、より論理的で説得力のある自己PRになります。"
216
- )
217
-
218
- return {
219
- "coverage": coverage,
220
- "star_score": star_score,
221
- "per_sentence": per_sentence_results,
222
- "missing_elements": missing,
223
- "comment": comment,
224
- }
225
-
226
-
227
- # =========================
228
- # ES 全体の評価インターフェース
229
- # =========================
230
-
231
- def evaluate_entry_sheet(
232
- self_pr: str,
233
- motivation: Optional[str] = None,
234
- ) -> Dict[str, Any]:
235
- """
236
- ES の自己PR(必須)、志望動機(任意)を入力として、
237
- 感情・トーン・STAR 構造をまとめて評価するインターフェース。
238
- """
239
- texts = [self_pr]
240
- if motivation:
241
- texts.append(motivation)
242
- full_text = "\n".join([t for t in texts if t])
243
-
244
- sentiment = analyze_sentiment(full_text)
245
- tone = analyze_tone(full_text)
246
- star = analyze_star_structure(self_pr) # STAR は主に自己PRに対して実行
247
-
248
- return {
249
- "input": {
250
- "self_pr": self_pr,
251
- "motivation": motivation,
252
- },
253
- "sentiment": sentiment,
254
- "tone": tone,
255
- "star": star,
256
- }
257
-
258
-
259
- # =========================
260
- # 単体テスト用の簡易実行
261
- # =========================
262
-
263
- if __name__ == "__main__":
264
- sample_self_pr = """
265
- 私は大学時代、サッカー部の主将としてチームをまとめました。
266
- チームは当初、練習への参加率が低く、公式戦でも連敗が続いていました。
267
- そこで私は、メンバー全員への個別ヒアリングを行い、参加しづらい理由や不満点を把握しました。
268
- その上で、練習メニューの見直しや役割分担の明確化を提案し、自ら先頭に立って行動しました。
269
- その結果、練習参加率は 50% から 85% に向上し、公式戦でも県大会ベスト8まで進出することができました。
270
- """
271
-
272
- sample_motivation = """
273
- 貴社を志望する理由は、ヘルスケア領域でデータとテクノロジーを活用し、
274
- 社会的インパクトの大きいサービスを創出している点に強く共感したためです。
275
- """
276
-
277
- result = evaluate_entry_sheet(sample_self_pr, sample_motivation)
278
- import json
279
- print(json.dumps(result, ensure_ascii=False, indent=2))