手把手教你用Python处理Amazon Review Dataset的JSON文件:从数据清洗到特征工程实战

发布时间:2026/6/2 2:32:11

手把手教你用Python处理Amazon Review Dataset的JSON文件:从数据清洗到特征工程实战 手把手教你用Python处理Amazon Review Dataset的JSON文件从数据清洗到特征工程实战面对Amazon Review Dataset这类包含复杂嵌套结构的JSON数据许多数据分析师常陷入数据沼泽——原始文件中的related字段多层嵌套、salesRank字典结构混乱、时间戳格式不统一等问题往往让初步探索变成一场噩梦。本文将用工程化的思维带你从原始JSON文件出发逐步拆解数据清洗与特征构建的全流程最终产出可直接用于机器学习建模的结构化特征。1. 高效读取与初步探索避开JSON解析的常见陷阱处理Amazon Review Dataset的第一步不是直接写代码而是理解数据的基本结构。以meta_Electronics.json为例每行是一个独立的JSON对象这种格式被称为JSON Lines.jsonl。直接使用pandas.read_json()会遇到报错因为这不是标准JSON数组格式。1.1 优化读取方案对比方法优点缺点适用场景jsonlines库内存友好支持流式读取需额外安装超大文件(10GB)pandas.read_json原生支持一行代码搞定内存消耗大中小型文件(2GB)ijson迭代解析极低内存占用解析速度慢内存受限环境推荐使用jsonlines进行安全读取import jsonlines import pandas as pd def read_jsonl(file_path, chunk_size10000): chunks [] with jsonlines.open(file_path) as reader: chunk [] for obj in reader: chunk.append(obj) if len(chunk) chunk_size: chunks.append(pd.DataFrame(chunk)) chunk [] if chunk: # 处理剩余记录 chunks.append(pd.DataFrame(chunk)) return pd.concat(chunks, ignore_indexTrue) electronics_meta read_jsonl(meta_Electronics.json)注意当处理Electronics_5.json等评论数据时建议先采样1万行测试代码避免因字段不一致导致后续处理失败。1.2 关键字段诊断检查执行以下诊断脚本快速发现数据问题def diagnose_data(df): # 检查缺失值 missing df.isnull().sum().sort_values(ascendingFalse) # 检查嵌套字段 nested [col for col in df.columns if isinstance(df[col].iloc[0], (dict, list))] return { missing_values: missing[missing 0].to_dict(), nested_columns: nested, sample_nested: {col: df[col].iloc[0] for col in nested[:3]} } diagnose_data(electronics_meta)典型输出会揭示如salesRank字段的字典结构、related中的多层列表等需要特殊处理的嵌套字段。2. 深度清洗嵌套结构从混乱到规整2.1 展平related商品关系网络原始related字段包含also_bought、also_viewed等关系网络直接展平会丢失图结构信息。我们采用关系计数图特征提取的策略from collections import Counter def expand_related(df): # 初始化结果列 df[also_bought_count] 0 df[also_viewed_count] 0 for idx, row in df.dropna(subset[related]).iterrows(): related row[related] if also_bought in related: df.at[idx, also_bought_count] len(related[also_bought]) if also_viewed in related: df.at[idx, also_viewed_count] len(related[also_viewed]) # 添加关系密度特征 df[relation_density] df[also_bought_count] / (df[also_viewed_count] 1) return df electronics_meta expand_related(electronics_meta)2.2 解析salesRank销售排名salesRank字段是嵌套字典存储商品在不同类别的排名。我们提取最优排名和所属类别def process_sales_rank(df): df[top_sales_rank] None df[top_rank_category] None for idx, row in df.dropna(subset[salesRank]).iterrows(): ranks row[salesRank] if isinstance(ranks, dict): min_rank min(ranks.values()) best_cat [k for k, v in ranks.items() if v min_rank][0] df.at[idx, top_sales_rank] min_rank df.at[idx, top_rank_category] best_cat return df electronics_meta process_sales_rank(electronics_meta)3. 评论数据的高级特征工程评论数据Electronics_5.json包含更丰富的行为特征。我们首先用相同方法读取数据reviews read_jsonl(Electronics_5.json)3.1 计算动态好评率helpful字段格式为[有帮助票数, 总票数]我们构建三个衍生特征def process_helpful(df): df[helpful_votes] df[helpful].apply(lambda x: x[0] if isinstance(x, list) else 0) df[total_votes] df[helpful].apply(lambda x: x[1] if isinstance(x, list) else 0) df[helpful_ratio] df[helpful_votes] / (df[total_votes] 1e-6) # 避免除零 return df reviews process_helpful(reviews)3.2 时间特征的多维度解析reviewTime字段包含宝贵的时间模式信息from datetime import datetime def extract_time_features(df): df[parsed_time] pd.to_datetime(df[reviewTime], format%m %d, %Y) df[review_year] df[parsed_time].dt.year df[review_month] df[parsed_time].dt.month df[review_day] df[parsed_time].dt.day df[day_of_week] df[parsed_time].dt.dayofweek df[is_weekend] df[day_of_week].isin([5,6]).astype(int) return df reviews extract_time_features(reviews)4. 构建商品-评论联合特征体系4.1 商品维度特征聚合计算每个商品的评论统计量product_stats reviews.groupby(asin).agg({ overall: [mean, count, std], helpful_ratio: mean, review_year: [min, max] }).reset_index() product_stats.columns [ asin, avg_rating, review_count, rating_std, avg_helpfulness, first_review_year, last_review_year ]4.2 合并商品元数据full_product_data electronics_meta.merge( product_stats, onasin, howleft ) # 计算商品活跃度 full_product_data[review_per_year] full_product_data[review_count] / ( full_product_data[last_review_year] - full_product_data[first_review_year] 1 )4.3 构建关系图特征NetworkX实战利用related字段构建商品关系图import networkx as nx def build_product_graph(df): G nx.Graph() for _, row in df.dropna(subset[related]).iterrows(): source row[asin] if also_bought in row[related]: for target in row[related][also_bought]: G.add_edge(source, target) return G product_graph build_product_graph(electronics_meta) # 计算节点中心性 degree_centrality nx.degree_centrality(product_graph) betweenness nx.betweenness_centrality(product_graph, k100) # 采样计算 # 添加到特征表 full_product_data[degree_centrality] full_product_data[asin].map(degree_centrality) full_product_data[betweenness] full_product_data[asin].map(betweenness)5. 特征选择与存储优化5.1 关键特征矩阵最终得到的特征可分为几大类商品静态特征price, brand, categories关系网络特征also_bought_count, degree_centrality时间动态特征first_review_year, review_per_year评论质量特征avg_helpfulness, rating_std5.2 存储为Parquet格式相比CSVParquet格式更适合保存处理后的特征full_product_data.to_parquet(electronics_features.parquet, indexFalse) reviews.to_parquet(electronics_reviews.parquet, indexFalse)实际项目中处理一个50GB的原始JSON数据集经过上述流程后特征文件通常能压缩到3-5GB且读取速度提升5倍以上。我曾在一个推荐系统项目中应用这套流程使特征准备时间从原来的6小时缩短到40分钟同时发现商品关系图的介数中心性特征对提升推荐效果有显著作用。

相关新闻