| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #!/usr/bin/env python
- """
- 补充下载缺失的领域数据
- """
- import os
- import re
- import json
- from pathlib import Path
- from typing import List
- os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
- from datasets import load_dataset
- def preprocess_text(text: str, lang: str = "en", min_len: int = 30, max_len: int = 300) -> str | None:
- text = text.strip()
- if not text:
- return None
- if lang == "en":
- text = re.sub(r'[^\w\s.,!?;:()"\']', '', text)
- words = text.split()
- if len(words) < min_len or len(words) > max_len:
- return None
- return ' '.join(words[:max_len]).strip()
- return None
- def save_corpus(texts: List[str], domain: str) -> bool:
- if not texts:
- return False
- output_path = Path(f"database/corpus/{domain}/texts.jsonl")
- output_path.parent.mkdir(parents=True, exist_ok=True)
- with open(output_path, "w", encoding="utf-8") as f:
- for i, text in enumerate(texts):
- f.write(json.dumps({"text": text, "metadata": {"index": i, "domain": domain}}, ensure_ascii=False) + "\n")
- print(f" ✅ 已保存:{domain} ({len(texts)} 条)")
- return True
- def load_code(sample_num: int = 50) -> List[str]:
- """加载代码语料 - 使用无需认证的数据集"""
- corpus = []
- print("尝试加载 Python 代码...")
- # 尝试 1: cosmopedia openstax (数学/代码相关)
- try:
- ds = load_dataset("HuggingFaceTB/cosmopedia", "openstax", split="train", streaming=True)
- count = 0
- for item in ds:
- if count >= 500:
- break
- count += 1
- text = item.get("text", "")
- # 筛选包含代码示例的文本
- if text and ('import ' in text or 'def ' in text or 'class ' in text or 'print(' in text):
- lines = text.strip().split('\n')
- if 5 <= len(lines) <= 80:
- code_clean = '\n'.join(line[:120] for line in lines[:40])
- if code_clean and code_clean not in corpus:
- corpus.append(code_clean)
- if len(corpus) >= sample_num:
- break
- if corpus:
- print(f" cosmopedia openstax: {len(corpus)} 条")
- return corpus
- except Exception as e:
- print(f" cosmopedia openstax 失败:{e}")
- # 尝试 2: 使用 algorithmica 数据集
- print(" 尝试 algorithmica...")
- try:
- ds = load_dataset("Laurencie/algorithmica", split="train", streaming=True)
- count = 0
- for item in ds:
- if count >= 500:
- break
- count += 1
- code = item.get("code", "") or item.get("content", "")
- if code:
- lines = code.strip().split('\n')
- if 3 <= len(lines) <= 60:
- code_clean = '\n'.join(line[:120] for line in lines[:30])
- if code_clean and code_clean not in corpus:
- corpus.append(code_clean)
- if len(corpus) >= sample_num:
- break
- if corpus:
- print(f" algorithmica: {len(corpus)} 条")
- return corpus
- except Exception as e:
- print(f" algorithmica 失败:{e}")
- # 尝试 3: 使用 leetcode 问题
- print(" 尝试 leetcode-problems...")
- try:
- ds = load_dataset("xiaomingl2000/leetcode-medium-questions", split="train", streaming=True)
- count = 0
- for item in ds:
- if count >= 500:
- break
- count += 1
- # 提取问题和解答
- question = item.get("question", "")
- solution = item.get("solution", "")
- if question or solution:
- text = f"{question}\n\n{solution}" if solution else question
- processed = preprocess_text(str(text), lang="en")
- if processed and processed not in corpus:
- corpus.append(processed)
- if len(corpus) >= sample_num:
- break
- if corpus:
- print(f" leetcode: {len(corpus)} 条")
- return corpus
- except Exception as e:
- print(f" leetcode 失败:{e}")
- return corpus
- def load_academic(sample_num: int = 50) -> List[str]:
- """补充学术语料"""
- corpus = []
- print("加载学术语料...")
- try:
- ds = load_dataset("wikimedia/wikipedia", "20231101.en", split="train", streaming=True)
- science_keywords = ["algorithm", "neural network", "machine learning", "computer science", "mathematics",
- "statistics", "artificial intelligence", "physics", "chemistry", "biology", "quantum",
- "deep learning", "optimization", "data structure", "complexity"]
- count = 0
- for item in ds:
- if count >= 5000:
- break
- count += 1
- text = item.get("text", "")
- title = item.get("title", "")
- # 更严格的筛选
- if any(kw in title.lower() for kw in science_keywords):
- processed = preprocess_text(text, lang="en")
- if processed and processed not in corpus:
- corpus.append(processed)
- if len(corpus) >= sample_num:
- break
- print(f" 维基百科科学:{len(corpus)} 条")
- except Exception as e:
- print(f" 失败:{e}")
- return corpus
- def main():
- print("=" * 50)
- print("补充下载缺失的领域")
- print("=" * 50)
- # 补充 code (已有 20 条)
- print("\n[code] 补充到 50 条")
- code_path = Path("database/corpus/code/texts.jsonl")
- code_texts = []
- if code_path.exists():
- with open(code_path) as f:
- for line in f:
- code_texts.append(json.loads(line)["text"])
- print(f" 已有 {len(code_texts)} 条")
- if len(code_texts) < 50:
- need = 50 - len(code_texts)
- new_texts = load_code(need)
- for t in new_texts:
- if t not in code_texts:
- code_texts.append(t)
- save_corpus(code_texts[:50], "code")
- else:
- print(" 已足够,无需补充")
- # 补充 academic (已有 20 条)
- print("\n[academic] 补充到 50 条")
- academic_path = Path("database/corpus/academic/texts.jsonl")
- academic_texts = []
- if academic_path.exists():
- with open(academic_path) as f:
- for line in f:
- academic_texts.append(json.loads(line)["text"])
- print(f" 已有 {len(academic_texts)} 条")
- if len(academic_texts) < 50:
- need = 50 - len(academic_texts)
- new_texts = load_academic(need)
- for t in new_texts:
- if t not in academic_texts:
- academic_texts.append(t)
- save_corpus(academic_texts[:50], "academic")
- else:
- print(" 已足够,无需补充")
- print("\n" + "=" * 50)
- print("完成!")
- print("=" * 50)
- if __name__ == "__main__":
- main()
|