Spaces:
Sleeping
Sleeping
ktsn-ud commited on
Commit ·
0db07a9
1
Parent(s): 0d8c5ed
軽いリファクタリング
Browse files
scripts/3_build_synonyms_from_sudachi.py
CHANGED
|
@@ -12,7 +12,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
| 12 |
from utils.logger import setup_logger
|
| 13 |
from utils.json import get_file_path_from_config, field_getter, json_dumps
|
| 14 |
from utils.io import LineIteratorIO, comment_filtered_lines
|
| 15 |
-
|
| 16 |
|
| 17 |
# --- ロギングの設定 ---
|
| 18 |
log = setup_logger(__name__)
|
|
@@ -65,7 +65,7 @@ def tokenize(text: str) -> list[str]:
|
|
| 65 |
return tokens
|
| 66 |
|
| 67 |
|
| 68 |
-
def get_corpus_vocab(projects: list[
|
| 69 |
"""プロジェクト全体から語彙セットを構築する"""
|
| 70 |
vocab = set()
|
| 71 |
log.info("語彙セットを構築中...")
|
|
@@ -125,7 +125,7 @@ def main():
|
|
| 125 |
with open(input_file, encoding="utf-8") as f:
|
| 126 |
try:
|
| 127 |
project_dicts = json.load(f)
|
| 128 |
-
projects = [
|
| 129 |
except json.JSONDecodeError as e:
|
| 130 |
log.error(f"JSONデコードエラー: {e}")
|
| 131 |
sys.exit(1)
|
|
|
|
| 12 |
from utils.logger import setup_logger
|
| 13 |
from utils.json import get_file_path_from_config, field_getter, json_dumps
|
| 14 |
from utils.io import LineIteratorIO, comment_filtered_lines
|
| 15 |
+
from schemas.projects import Project
|
| 16 |
|
| 17 |
# --- ロギングの設定 ---
|
| 18 |
log = setup_logger(__name__)
|
|
|
|
| 65 |
return tokens
|
| 66 |
|
| 67 |
|
| 68 |
+
def get_corpus_vocab(projects: list[Project]) -> set[str]:
|
| 69 |
"""プロジェクト全体から語彙セットを構築する"""
|
| 70 |
vocab = set()
|
| 71 |
log.info("語彙セットを構築中...")
|
|
|
|
| 125 |
with open(input_file, encoding="utf-8") as f:
|
| 126 |
try:
|
| 127 |
project_dicts = json.load(f)
|
| 128 |
+
projects = [Project(**item) for item in project_dicts]
|
| 129 |
except json.JSONDecodeError as e:
|
| 130 |
log.error(f"JSONデコードエラー: {e}")
|
| 131 |
sys.exit(1)
|
scripts/4_prepare_bm25f_meta.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
import json
|
|
|
|
| 4 |
from collections import defaultdict
|
| 5 |
from typing import Dict, List
|
| 6 |
|
|
@@ -37,7 +38,9 @@ def build_tokenizer(sudachi_config_path: str):
|
|
| 37 |
return tok, mode
|
| 38 |
|
| 39 |
|
| 40 |
-
def tokenize(
|
|
|
|
|
|
|
| 41 |
if not text:
|
| 42 |
return []
|
| 43 |
out: List[str] = []
|
|
@@ -57,13 +60,19 @@ def tokenize(text: str, tok, mode, target_pos_l1: List[str], ban_list: set, stop
|
|
| 57 |
def main():
|
| 58 |
log.info("BM25Fメタデータ(bm25_meta.json)を生成します")
|
| 59 |
try:
|
| 60 |
-
target_pos_l1, target_fields, ban_list, stopwords, sudachi_config_path =
|
|
|
|
|
|
|
| 61 |
except Exception as e:
|
| 62 |
log.error(f"設定の読み込みに失敗しました: {e}")
|
| 63 |
sys.exit(1)
|
| 64 |
|
| 65 |
-
projects_path = get_file_path_from_config(
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
try:
|
| 69 |
with open(projects_path, encoding="utf-8") as f:
|
|
@@ -94,13 +103,14 @@ def main():
|
|
| 94 |
# IDF 計算(BM25で一般的な +0.5 smoothing と +1 オフセット)
|
| 95 |
idf: Dict[str, float] = {}
|
| 96 |
for term, dfi in df.items():
|
| 97 |
-
idf_val = max(0.0, (
|
| 98 |
# 数値安定化のためlog1p
|
| 99 |
-
import math
|
| 100 |
-
|
| 101 |
idf[term] = math.log1p(idf_val)
|
| 102 |
|
| 103 |
-
avg_len = {
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
meta = {
|
| 106 |
"N": N,
|
|
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
import json
|
| 4 |
+
import math
|
| 5 |
from collections import defaultdict
|
| 6 |
from typing import Dict, List
|
| 7 |
|
|
|
|
| 38 |
return tok, mode
|
| 39 |
|
| 40 |
|
| 41 |
+
def tokenize(
|
| 42 |
+
text: str, tok, mode, target_pos_l1: List[str], ban_list: set, stopwords: set
|
| 43 |
+
) -> List[str]:
|
| 44 |
if not text:
|
| 45 |
return []
|
| 46 |
out: List[str] = []
|
|
|
|
| 60 |
def main():
|
| 61 |
log.info("BM25Fメタデータ(bm25_meta.json)を生成します")
|
| 62 |
try:
|
| 63 |
+
target_pos_l1, target_fields, ban_list, stopwords, sudachi_config_path = (
|
| 64 |
+
load_configs()
|
| 65 |
+
)
|
| 66 |
except Exception as e:
|
| 67 |
log.error(f"設定の読み込みに失敗しました: {e}")
|
| 68 |
sys.exit(1)
|
| 69 |
|
| 70 |
+
projects_path = get_file_path_from_config(
|
| 71 |
+
"projects.projects_json", "data/generated/projects.json"
|
| 72 |
+
)
|
| 73 |
+
output_path = get_file_path_from_config(
|
| 74 |
+
"bm25.bm25_meta", "data/generated/bm25_meta.json"
|
| 75 |
+
)
|
| 76 |
|
| 77 |
try:
|
| 78 |
with open(projects_path, encoding="utf-8") as f:
|
|
|
|
| 103 |
# IDF 計算(BM25で一般的な +0.5 smoothing と +1 オフセット)
|
| 104 |
idf: Dict[str, float] = {}
|
| 105 |
for term, dfi in df.items():
|
| 106 |
+
idf_val = max(0.0, ((N - dfi + 0.5) / (dfi + 0.5)))
|
| 107 |
# 数値安定化のためlog1p
|
|
|
|
|
|
|
| 108 |
idf[term] = math.log1p(idf_val)
|
| 109 |
|
| 110 |
+
avg_len = {
|
| 111 |
+
field: (field_token_lens_sum[field] / N if N > 0 else 0.0)
|
| 112 |
+
for field in target_fields
|
| 113 |
+
}
|
| 114 |
|
| 115 |
meta = {
|
| 116 |
"N": N,
|
scripts/5_prepare_tf_token.py
CHANGED
|
@@ -10,7 +10,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
| 10 |
|
| 11 |
from utils.logger import setup_logger
|
| 12 |
from utils.json import get_file_path_from_config, field_getter, json_dumps
|
| 13 |
-
|
| 14 |
|
| 15 |
log = setup_logger(__name__)
|
| 16 |
|
|
@@ -38,7 +38,9 @@ def build_tokenizer(sudachi_config_path: str):
|
|
| 38 |
return tok, mode
|
| 39 |
|
| 40 |
|
| 41 |
-
def tokenize(
|
|
|
|
|
|
|
| 42 |
if not text:
|
| 43 |
return []
|
| 44 |
out: List[str] = []
|
|
@@ -58,13 +60,19 @@ def tokenize(text: str, tok, mode, target_pos_l1: List[str], ban_list: set, stop
|
|
| 58 |
def main():
|
| 59 |
log.info("フィールド別TF/トークン(tf_token.json)を生成します")
|
| 60 |
try:
|
| 61 |
-
target_pos_l1, target_fields, ban_list, stopwords, sudachi_config_path =
|
|
|
|
|
|
|
| 62 |
except Exception as e:
|
| 63 |
log.error(f"設定の読み込みに失敗しました: {e}")
|
| 64 |
sys.exit(1)
|
| 65 |
|
| 66 |
-
projects_path = get_file_path_from_config(
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
try:
|
| 70 |
with open(projects_path, encoding="utf-8") as f:
|
|
@@ -75,13 +83,13 @@ def main():
|
|
| 75 |
|
| 76 |
tok, mode = build_tokenizer(sudachi_config_path)
|
| 77 |
|
| 78 |
-
results: List[
|
| 79 |
|
| 80 |
for p in projects:
|
| 81 |
project_id = p.get("projectId")
|
| 82 |
|
| 83 |
# 各フィールドのトークン化とTF
|
| 84 |
-
field_objs: Dict[str,
|
| 85 |
doc_tf_counter: Counter = Counter()
|
| 86 |
doc_token_set: set = set()
|
| 87 |
|
|
@@ -89,15 +97,15 @@ def main():
|
|
| 89 |
text = p.get(field) or ""
|
| 90 |
toks = tokenize(str(text), tok, mode, target_pos_l1, ban_list, stopwords)
|
| 91 |
tf = Counter(toks)
|
| 92 |
-
field_objs[field] =
|
| 93 |
doc_tf_counter.update(tf)
|
| 94 |
doc_token_set.update(tf.keys())
|
| 95 |
|
| 96 |
# スキーマ Fields へ詰める(未定義フィールドは長さ0/空dictで埋める)
|
| 97 |
-
def get_field(name: str) ->
|
| 98 |
-
return field_objs.get(name,
|
| 99 |
|
| 100 |
-
fields_obj =
|
| 101 |
title=get_field("title"),
|
| 102 |
organization=get_field("organization"),
|
| 103 |
reading=get_field("reading"),
|
|
@@ -106,7 +114,7 @@ def main():
|
|
| 106 |
prCommentLong=get_field("prCommentLong"),
|
| 107 |
)
|
| 108 |
|
| 109 |
-
project_entry =
|
| 110 |
projectId=project_id,
|
| 111 |
fields=fields_obj,
|
| 112 |
tf=dict(doc_tf_counter),
|
|
|
|
| 10 |
|
| 11 |
from utils.logger import setup_logger
|
| 12 |
from utils.json import get_file_path_from_config, field_getter, json_dumps
|
| 13 |
+
from schemas import tf_token
|
| 14 |
|
| 15 |
log = setup_logger(__name__)
|
| 16 |
|
|
|
|
| 38 |
return tok, mode
|
| 39 |
|
| 40 |
|
| 41 |
+
def tokenize(
|
| 42 |
+
text: str, tok, mode, target_pos_l1: List[str], ban_list: set, stopwords: set
|
| 43 |
+
) -> List[str]:
|
| 44 |
if not text:
|
| 45 |
return []
|
| 46 |
out: List[str] = []
|
|
|
|
| 60 |
def main():
|
| 61 |
log.info("フィールド別TF/トークン(tf_token.json)を生成します")
|
| 62 |
try:
|
| 63 |
+
target_pos_l1, target_fields, ban_list, stopwords, sudachi_config_path = (
|
| 64 |
+
load_configs()
|
| 65 |
+
)
|
| 66 |
except Exception as e:
|
| 67 |
log.error(f"設定の読み込みに失敗しました: {e}")
|
| 68 |
sys.exit(1)
|
| 69 |
|
| 70 |
+
projects_path = get_file_path_from_config(
|
| 71 |
+
"projects.projects_json", "data/generated/projects.json"
|
| 72 |
+
)
|
| 73 |
+
output_path = get_file_path_from_config(
|
| 74 |
+
"bm25.tf_token", "data/generated/tf_token.json"
|
| 75 |
+
)
|
| 76 |
|
| 77 |
try:
|
| 78 |
with open(projects_path, encoding="utf-8") as f:
|
|
|
|
| 83 |
|
| 84 |
tok, mode = build_tokenizer(sudachi_config_path)
|
| 85 |
|
| 86 |
+
results: List[tf_token.Project] = []
|
| 87 |
|
| 88 |
for p in projects:
|
| 89 |
project_id = p.get("projectId")
|
| 90 |
|
| 91 |
# 各フィールドのトークン化とTF
|
| 92 |
+
field_objs: Dict[str, tf_token.TfOfField] = {}
|
| 93 |
doc_tf_counter: Counter = Counter()
|
| 94 |
doc_token_set: set = set()
|
| 95 |
|
|
|
|
| 97 |
text = p.get(field) or ""
|
| 98 |
toks = tokenize(str(text), tok, mode, target_pos_l1, ban_list, stopwords)
|
| 99 |
tf = Counter(toks)
|
| 100 |
+
field_objs[field] = tf_token.TfOfField(len=len(toks), tf=dict(tf))
|
| 101 |
doc_tf_counter.update(tf)
|
| 102 |
doc_token_set.update(tf.keys())
|
| 103 |
|
| 104 |
# スキーマ Fields へ詰める(未定義フィールドは長さ0/空dictで埋める)
|
| 105 |
+
def get_field(name: str) -> tf_token.TfOfField:
|
| 106 |
+
return field_objs.get(name, tf_token.TfOfField(len=0, tf={}))
|
| 107 |
|
| 108 |
+
fields_obj = tf_token.Fields(
|
| 109 |
title=get_field("title"),
|
| 110 |
organization=get_field("organization"),
|
| 111 |
reading=get_field("reading"),
|
|
|
|
| 114 |
prCommentLong=get_field("prCommentLong"),
|
| 115 |
)
|
| 116 |
|
| 117 |
+
project_entry = tf_token.Project(
|
| 118 |
projectId=project_id,
|
| 119 |
fields=fields_obj,
|
| 120 |
tf=dict(doc_tf_counter),
|