data_processor.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from config import *
  2. import argparse
  3. import json
  4. from collections import Counter
  5. from pathlib import Path
  6. from utils import *
  7. #生成词表
  8. def generate_vocab(
  9. train_sample_path=TRAIN_SAMPLE_PATH,
  10. zh_vocab_path=ZH_VOCAB_PATH,
  11. en_vocab_path=EN_VOCAB_PATH,
  12. min_freq=2,
  13. ):
  14. if min_freq < 1:
  15. raise ValueError("min_freq 必须大于或等于1。")
  16. en_vocab = ['<pad>', '<unk>', '<sos>', '<eos>']
  17. zh_vocab = ['<pad>', '<unk>', '<sos>', '<eos>']
  18. zh_vocab_list = []
  19. en_vocab_list = []
  20. # 解析json文件
  21. with open(train_sample_path, encoding='utf-8') as file:
  22. lines = json.load(file)
  23. for en_sent, zh_sent in lines:
  24. # en_vocab_list += divided_en(en_sent)
  25. # zh_vocab_list += divided_zh(zh_sent)
  26. # 先统一为小写再统计,避免 The、the 等写入词表后变成重复项。
  27. # 同时过滤 Jieba 分词时可能产生的空白 token。
  28. en_vocab_list += [
  29. word.lower()
  30. for word in divided_en(en_sent)
  31. if word.strip()
  32. ]
  33. zh_vocab_list += [
  34. word.lower()
  35. for word in divided_zh(zh_sent)
  36. if word.strip()
  37. ]
  38. print('train_sample count:', len(lines))
  39. # 按次数生成词表,如果语料库够大,可以按最小次数,过滤掉生僻词。
  40. # MIN_FREQ = 2
  41. #统计列表中每个元素出现的次数,并按出现频率从高到低排序返回。
  42. # [('我', 3), ('爱', 2), ('你', 1)]
  43. zh_vocab_kv = Counter(zh_vocab_list).most_common()
  44. # zh_vocab += [k.lower() for k,v in zh_vocab_kv]
  45. zh_vocab += [
  46. word
  47. for word, count in zh_vocab_kv
  48. if count >= min_freq
  49. ]
  50. en_vocab_kv = Counter(en_vocab_list).most_common()
  51. # en_vocab += [k.lower() for k,v in en_vocab_kv]
  52. en_vocab += [
  53. word
  54. for word, count in en_vocab_kv
  55. if count >= min_freq
  56. ]
  57. print('en_vocab count:', len(en_vocab))
  58. print('zh_vocab count:', len(zh_vocab))
  59. print('min_freq:', min_freq)
  60. # 生成词表文件
  61. zh_vocab_path = Path(zh_vocab_path)
  62. en_vocab_path = Path(en_vocab_path)
  63. zh_vocab_path.parent.mkdir(parents=True, exist_ok=True)
  64. en_vocab_path.parent.mkdir(parents=True, exist_ok=True)
  65. with zh_vocab_path.open('w', encoding='utf-8') as file:
  66. file.write('\n'.join(zh_vocab))
  67. with en_vocab_path.open('w', encoding='utf-8') as file:
  68. file.write('\n'.join(en_vocab))
  69. print('en_vocab saved to:', en_vocab_path)
  70. print('zh_vocab saved to:', zh_vocab_path)
  71. if __name__ == '__main__':
  72. parser = argparse.ArgumentParser(description='根据训练集生成中英文词表。')
  73. parser.add_argument(
  74. '--train-path',
  75. default=TRAIN_SAMPLE_PATH,
  76. help='训练数据 JSON 路径。',
  77. )
  78. parser.add_argument(
  79. '--en-output',
  80. default=EN_VOCAB_PATH,
  81. help='英文词表输出路径。',
  82. )
  83. parser.add_argument(
  84. '--zh-output',
  85. default=ZH_VOCAB_PATH,
  86. help='中文词表输出路径。',
  87. )
  88. parser.add_argument(
  89. '--min-freq',
  90. type=int,
  91. default=2,
  92. help='进入词表所需的最低出现次数,默认值为2。',
  93. )
  94. args = parser.parse_args()
  95. generate_vocab(
  96. train_sample_path=args.train_path,
  97. zh_vocab_path=args.zh_output,
  98. en_vocab_path=args.en_output,
  99. min_freq=args.min_freq,
  100. )