download_supplement.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #!/usr/bin/env python
  2. """
  3. 补充下载 academic 和 literature 到 200 条 - 宽松模式
  4. """
  5. import os
  6. import re
  7. import json
  8. from pathlib import Path
  9. from typing import List, Optional
  10. os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
  11. from datasets import load_dataset
  12. def preprocess_text(text: str, lang: str = "en", min_len: int = 20, max_len: int = 500) -> Optional[str]:
  13. """预处理文本 - 放宽长度限制"""
  14. text = text.strip()
  15. if not text:
  16. return None
  17. if lang == "en":
  18. text = re.sub(r'[^\w\s.,!?;:()"\']', '', text)
  19. words = text.split()
  20. if len(words) < min_len or len(words) > max_len:
  21. return None
  22. return ' '.join(words[:max_len]).strip()
  23. else:
  24. text = re.sub(r'[^\u4e00-\u9fff0-9.,!?;:()"\',,。!?、;:""()【】《》]', '', text)
  25. chars = list(text)
  26. if len(chars) < min_len or len(chars) > max_len:
  27. return None
  28. return ''.join(chars[:max_len]).strip()
  29. def save_corpus(texts: List[str], domain: str) -> bool:
  30. """保存语料到 JSONL 文件"""
  31. if not texts:
  32. return False
  33. output_path = Path(f"database/corpus/{domain}/texts.jsonl")
  34. output_path.parent.mkdir(parents=True, exist_ok=True)
  35. with open(output_path, "w", encoding="utf-8") as f:
  36. for i, text in enumerate(texts):
  37. f.write(json.dumps({"text": text, "metadata": {"index": i, "domain": domain}}, ensure_ascii=False) + "\n")
  38. print(f" ✅ 已保存:{domain} ({len(texts)} 条)")
  39. return True
  40. def load_academic(sample_num: int = 200) -> List[str]:
  41. """加载学术语料 - 宽松模式"""
  42. corpus = []
  43. print("加载维基百科文章(宽松模式)...")
  44. # 更广泛的科学/学术关键词
  45. science_keywords = [
  46. "algorithm", "neural", "machine learning", "computer", "math",
  47. "statistics", "artificial", "physics", "chemistry", "biology", "quantum",
  48. "deep learning", "optimization", "data", "complexity", "relativity",
  49. "thermodynamics", "electromagnetism", "genetics", "evolution", "ecosystem",
  50. "calculus", "topology", "algebra", "geometry", "probability", "enzyme", "protein",
  51. "dna", "rna", "cell", "molecule", "atom", "electron", "photon", "galaxy", "star",
  52. "science", "research", "theory", "analysis", "model", "system", "engineering"
  53. ]
  54. try:
  55. ds = load_dataset("wikimedia/wikipedia", "20231101.en", split="train", streaming=True)
  56. count = 0
  57. for item in ds:
  58. if count >= 10000:
  59. break
  60. count += 1
  61. text = item.get("text", "")
  62. title = item.get("title", "")
  63. # 宽松筛选:标题或内容前 300 字符包含关键词即可
  64. if any(kw in title.lower() or kw in text[:300].lower() for kw in science_keywords):
  65. processed = preprocess_text(text, lang="en", min_len=20, max_len=500)
  66. if processed and processed not in corpus:
  67. corpus.append(processed)
  68. if len(corpus) >= sample_num:
  69. break
  70. print(f" 成功提取 {len(corpus)} 篇学术文章")
  71. except Exception as e:
  72. print(f" 加载失败:{e}")
  73. return corpus
  74. def load_literature(sample_num: int = 200) -> List[str]:
  75. """加载文学语料 - 宽松模式"""
  76. corpus = []
  77. print("加载维基百科文章(宽松模式)...")
  78. # 更广泛的人文/文学关键词
  79. literature_keywords = [
  80. "novel", "poetry", "fiction", "literature", "shakespeare",
  81. "dickens", "austen", "tolkien", "hemingway", "orwell",
  82. "pride and prejudice", "great gatsby", "1984", "lord of the rings",
  83. "romeo and juliet", "hamlet", "macbeth", "jane eyre", "wuthering heights",
  84. "moby dick", "war and peace", "crime and punishment", "ulysses",
  85. "writer", "author", "book", "story", "character", "plot", "narrative",
  86. "prose", "verse", "sonnet", "drama", "tragedy", "comedy", "english literature",
  87. "art", "history", "philosophy", "culture", "music", "painting", "artist"
  88. ]
  89. try:
  90. ds = load_dataset("wikimedia/wikipedia", "20231101.en", split="train", streaming=True)
  91. count = 0
  92. for item in ds:
  93. if count >= 10000:
  94. break
  95. count += 1
  96. text = item.get("text", "")
  97. title = item.get("title", "")
  98. # 宽松筛选
  99. if any(kw in title.lower() or kw in text[:300].lower() for kw in literature_keywords):
  100. processed = preprocess_text(text, lang="en", min_len=20, max_len=500)
  101. if processed and processed not in corpus:
  102. corpus.append(processed)
  103. if len(corpus) >= sample_num:
  104. break
  105. print(f" 成功提取 {len(corpus)} 段文学文本")
  106. except Exception as e:
  107. print(f" 加载失败:{e}")
  108. return corpus
  109. def main():
  110. print("=" * 60)
  111. print("补充下载 academic 和 literature 到 200 条")
  112. print("=" * 60)
  113. print()
  114. # 补充 academic
  115. print("[academic]")
  116. academic_path = Path("database/corpus/academic/texts.jsonl")
  117. academic_texts = []
  118. if academic_path.exists():
  119. with open(academic_path) as f:
  120. for line in f:
  121. academic_texts.append(json.loads(line)["text"])
  122. print(f" 已有 {len(academic_texts)} 条")
  123. if len(academic_texts) < 200:
  124. need = 200 - len(academic_texts)
  125. print(f" 需要补充 {need} 条")
  126. new_texts = load_academic(need)
  127. for t in new_texts:
  128. if t not in academic_texts:
  129. academic_texts.append(t)
  130. save_corpus(academic_texts[:200], "academic")
  131. else:
  132. print(" 已足够,无需补充")
  133. print()
  134. # 补充 literature
  135. print("[literature]")
  136. literature_path = Path("database/corpus/literature/texts.jsonl")
  137. literature_texts = []
  138. if literature_path.exists():
  139. with open(literature_path) as f:
  140. for line in f:
  141. literature_texts.append(json.loads(line)["text"])
  142. print(f" 已有 {len(literature_texts)} 条")
  143. if len(literature_texts) < 200:
  144. need = 200 - len(literature_texts)
  145. print(f" 需要补充 {need} 条")
  146. new_texts = load_literature(need)
  147. for t in new_texts:
  148. if t not in literature_texts:
  149. literature_texts.append(t)
  150. save_corpus(literature_texts[:200], "literature")
  151. else:
  152. print(" 已足够,无需补充")
  153. print()
  154. print("=" * 60)
  155. print("完成!")
  156. print("=" * 60)
  157. if __name__ == "__main__":
  158. main()