Chishui-Chen commited on
Commit
70daced
·
verified ·
1 Parent(s): 9370eca

Delete scripts/data_processing/convert_data.py with huggingface_hub

Browse files
scripts/data_processing/convert_data.py DELETED
@@ -1,238 +0,0 @@
1
- import json
2
- import math
3
- import re
4
- from collections import defaultdict
5
- from tqdm import tqdm
6
- import ijson
7
-
8
- POSTS_FILE = 'data/Posts_fixed.json'
9
- COMMENTS_FILE = 'data/Comments.json'
10
- OUTPUT_FILE = 'commentr_sft_data.jsonl'
11
-
12
- MIN_LIKES = 2
13
- MIN_CHARS = 4
14
- MAX_CHARS = 500
15
- MIN_OUTPUT_CHARS = 4
16
-
17
- AD_KEYWORDS = ['加群', '代购', '兼职', '刷单', '推广', '合作', '商务', '广告', '引流', '私聊']
18
- SPAM_PATTERNS = [r'^[。\.]+$', r'^[!!]+$', r'^[??]+$', r'^…+$', r'^[^\w\u4e00-\u9fa5]+$']
19
-
20
- def remove_mentions(text):
21
- """去除@提及"""
22
- if not text:
23
- return ""
24
- return re.sub(r'@[\w\u4e00-\u9fa5]+', '', text).strip()
25
-
26
- def is_spam_content(text):
27
- """检测是否为垃圾内容"""
28
- if not text:
29
- return True
30
-
31
- text = text.strip()
32
-
33
- if len(text) < MIN_CHARS:
34
- return True
35
-
36
- for pattern in SPAM_PATTERNS:
37
- if re.match(pattern, text):
38
- return True
39
-
40
- unique_chars = len(set(text))
41
- if len(text) > 10 and unique_chars < 3:
42
- return True
43
-
44
- for keyword in AD_KEYWORDS:
45
- if keyword in text:
46
- return True
47
-
48
- emoji_count = len(re.findall(r'\[.*?\]', text))
49
- if emoji_count > 10:
50
- return True
51
-
52
- return False
53
-
54
- def is_low_quality_output(text):
55
- """检测低质量输出"""
56
- if not text:
57
- return True
58
-
59
- text = text.strip()
60
-
61
- if len(text) < MIN_OUTPUT_CHARS:
62
- return True
63
-
64
- text_clean = remove_mentions(text)
65
-
66
- if not text_clean or len(text_clean) < MIN_OUTPUT_CHARS:
67
- return True
68
-
69
- if re.match(r'^http', text):
70
- return True
71
-
72
- if re.match(r'^图片评论', text):
73
- return True
74
-
75
- emoji_only = re.sub(r'\[.*?\]', '', text_clean).strip()
76
- if not emoji_only:
77
- return True
78
-
79
- return False
80
-
81
- def calculate_quality_score(comment_item):
82
- """计算评论质量分数"""
83
- likes = comment_item.get('likes_count', 0)
84
- content = comment_item.get('content', '')
85
-
86
- score = math.log(likes + 1)
87
-
88
- if len(content) < 6:
89
- score *= 0.7
90
- elif len(content) > 20:
91
- score *= 1.2
92
-
93
- if '[' in content and ']' in content:
94
- score *= 1.05
95
-
96
- return round(score, 4)
97
-
98
- def clean_text(text):
99
- """文本清洗"""
100
- if not text:
101
- return ""
102
- text = text.replace('\n', ' ').replace('\r', ' ').strip()
103
- text = remove_mentions(text)
104
- return text
105
-
106
- def format_prompt(post_data, parent_comment=None):
107
- """构建输入 Prompt"""
108
- post_content = clean_text(post_data.get('content', ''))
109
-
110
- img_tag = ""
111
- pic_num = post_data.get('pic_num', 0)
112
- if pic_num > 0:
113
- img_tag = f" [包含{pic_num}张图片]"
114
-
115
- prompt = f"{post_content}{img_tag}"
116
-
117
- if parent_comment:
118
- parent_text = clean_text(parent_comment.get('content', ''))
119
- if parent_text:
120
- prompt += f"\n\n(该用户回复了评论:{parent_text})"
121
-
122
- return prompt
123
-
124
- def load_posts_minimal(needed_post_ids):
125
- """流式加载帖子数据,只保留必要字段"""
126
- print("3. 正在加载 Posts 数据(仅需要的帖子)...")
127
- posts_map = {}
128
- try:
129
- with open(POSTS_FILE, 'r', encoding='utf-8') as f:
130
- for post in tqdm(ijson.items(f, 'item'), desc="Loading Posts"):
131
- mblogid = post.get('mblogid')
132
- if mblogid and mblogid in needed_post_ids:
133
- posts_map[mblogid] = {
134
- 'content': post.get('content', ''),
135
- 'pic_num': post.get('pic_num', 0)
136
- }
137
- print(f" 已加载 {len(posts_map)} 条帖子。")
138
- except FileNotFoundError:
139
- print(f"错误: 找不到文件 {POSTS_FILE}")
140
- return None
141
- return posts_map
142
-
143
- def main():
144
- print("1. 正在处理 Comments,收集有效评论...")
145
- valid_comments = []
146
- skipped_content = 0
147
- skipped_likes = 0
148
- skipped_output = 0
149
-
150
- with open(COMMENTS_FILE, 'r', encoding='utf-8') as f_in:
151
- for comment in tqdm(ijson.items(f_in, 'item'), desc="Processing Comments"):
152
- post_id = comment.get('root_post_mblogid')
153
- if not post_id:
154
- continue
155
-
156
- content = clean_text(comment.get('content', ''))
157
- likes = comment.get('likes_count', 0)
158
-
159
- if is_spam_content(content):
160
- skipped_content += 1
161
- continue
162
-
163
- if likes < MIN_LIKES:
164
- skipped_likes += 1
165
- continue
166
-
167
- if is_low_quality_output(content):
168
- skipped_output += 1
169
- continue
170
-
171
- valid_comments.append(comment)
172
-
173
- print(f" 有效评论: {len(valid_comments)} 条")
174
-
175
- print("2. 正在收集需要的 post_id...")
176
- needed_post_ids = set()
177
- for comment in valid_comments:
178
- needed_post_ids.add(comment.get('root_post_mblogid'))
179
- print(f" 需要 {len(needed_post_ids)} 个帖子")
180
-
181
- posts_map = load_posts_minimal(needed_post_ids)
182
-
183
- if not posts_map:
184
- return
185
-
186
- print("4. 正在去重(每个帖子保留最高赞评论)...")
187
- post_comments_map = defaultdict(list)
188
- skipped_post = 0
189
-
190
- for comment in valid_comments:
191
- post_id = comment.get('root_post_mblogid')
192
- if post_id in posts_map:
193
- post_comments_map[post_id].append(comment)
194
- else:
195
- skipped_post += 1
196
-
197
- valid_count = 0
198
- with open(OUTPUT_FILE, 'w', encoding='utf-8') as f_out:
199
- for post_id, comments in tqdm(post_comments_map.items(), desc="Deduplicating"):
200
- best_comment = max(comments, key=lambda x: x.get('likes_count', 0))
201
-
202
- target_post = posts_map[post_id]
203
- parent_comment_info = best_comment.get('reply_comment')
204
-
205
- input_text = format_prompt(target_post, parent_comment_info)
206
-
207
- output_text = clean_text(best_comment.get('content', ''))
208
-
209
- quality_score = calculate_quality_score(best_comment)
210
-
211
- data_entry = {
212
- "instruction": "根据帖子内容进行回复。",
213
- "input": input_text,
214
- "output": output_text,
215
- "meta": {
216
- "likes": best_comment.get('likes_count', 0),
217
- "quality_score": quality_score,
218
- "post_id": post_id,
219
- "comment_id": best_comment.get('_id')
220
- }
221
- }
222
-
223
- f_out.write(json.dumps(data_entry, ensure_ascii=False) + '\n')
224
- valid_count += 1
225
-
226
- print("="*50)
227
- print(f"处理完成!")
228
- print(f"生成文件: {OUTPUT_FILE}")
229
- print(f"有效数据: {valid_count} 条")
230
- print(f"过滤统计:")
231
- print(f" - 垃圾内容: {skipped_content} 条")
232
- print(f" - 无效帖子: {skipped_post} 条")
233
- print(f" - 低赞评论: {skipped_likes} 条")
234
- print(f" - 低质量输出: {skipped_output} 条")
235
- print("="*50)
236
-
237
- if __name__ == "__main__":
238
- main()