资讯详情

资讯详情

基于Hadoop伪分布式的电影网站用户性别预测与离线特征工程实战

简介这份教案面向大数据技术类相关专业师生围绕《Hadoop大数据开发基础》第6章项目案例展开帮助读者在真实场景中掌握KNN分类算法与MapReduce分布式编程的结合应用。内容涵盖KNN算法原理与实现步骤、MapReduce编程逻辑、分类算法评价指标以及电影网站用户性别预测的完整项目流程包括数据预处理、模型建立、结果评价与K值寻优并配有引导性、探究性和拓展性问题供课堂讨论。资源包为1个PDF文件约24KB结构紧凑适合作为48学时课程中9学时的实验教学参考。目前已有1078人学习下载读者可借此理清MapReduce连接多份数据、清洗缺失值与异常值、划分训练验证测试集、实现KNN分类模型及评价分类效果的关键思路适合需要将理论落地为项目实践的大数据学习者。1. 电影网站用户性别预测从 Hadoop 伪分布式到离线特征工程的一条完整链路电影网站的用户画像里性别是最常被拿来做推荐冷启动的字段之一。注册表单里那一栏很多人不填或者随手选一个于是运营侧就会问能不能靠行为日志把性别补出来这个标题讲的正是这件事——用 Hadoop 生态做一套离线批处理把电影网站的用户行为日志清洗成特征再跑一个性别预测模型。它解决的不是模型多准而是数据从哪来、怎么在集群上跑通、特征怎么落盘。适合谁看正在做 hadoop 课程设计、需要交一份能跑通的电影网站数据分析作业的学生以及刚接手离线数仓、要拿一个真实场景练手的初中级大数据开发。整套东西在单机伪分布式上就能跑不需要真集群但流程和集群版一致后面换到多节点只是改配置。下面按环境 → 数据 → 特征 → 模型 → 避坑的顺序拆开讲。2. 伪分布式环境与电影网站日志的落地准备2.1 为什么先搭伪分布式而不是直接上集群很多人一上来就想搞 hadoop 集群搭建三台虚拟机、免密、HA 全配一遍结果卡在 DataNode 起不来三天没写一行分析代码。我的建议是先用伪分布式把逻辑跑通NameNode、DataNode、ResourceManager、NodeManager 全在一台机器上HDFS 和 YARN 的行为和真集群几乎一致唯一区别是副本数和并发度。等代码稳定了再把core-site.xml、hdfs-site.xml里的地址换成真集群的业务代码一行不用改。伪分布式对内存的要求不高4GB 内存的虚拟机就能跑但要把 YARN 的容器内存调小否则一个任务申请 2GB 直接卡死。下面这套配置是我在 4GB 虚拟机上反复验证过的。2.2 最小可用的伪分布式配置先确认 JDK 和 SSH 本机免密这两步几乎所有 hadoop 安装与配置教程都会讲这里只给关键命令# 本机免密伪分布式也需要否则 start-dfs.sh 会反复要密码 ssh-keygen -t rsa -P -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys ssh localhost echo ok # 能打印 ok 才算通core-site.xml只改两处fs.defaultFS指向本机 9000 端口hadoop.tmp.dir指到一个磁盘空间够的目录configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/opt/module/hadoop/data/tmp/value /property /configurationhdfs-site.xml把副本数设成 1伪分布式只有一个 DataNode设 3 会一直报副本不足configuration property namedfs.replication/name value1/value /property /configurationyarn-site.xml里最关键的是把容器内存压下来否则 4GB 机器跑不动 MapReduceconfiguration property nameyarn.nodemanager.resource.memory-mb/name value2048/value /property property nameyarn.scheduler.maximum-allocation-mb/name value1024/value /property /configuration参数说明resource-memory-mb是 NodeManager 能分给容器的总内存maximum-allocation-mb是单个容器上限。两个值要满足单容器上限 ≤ 总内存否则提交任务时直接抛InvalidResourceRequestException。格式化并启动hdfs namenode -format # 只在第一次执行重复格式化会丢数据 start-dfs.sh start-yarn.sh jps # 应看到 NameNode/DataNode/ResourceManager/NodeManagerjps里少进程是新手最常见的翻车点先看日志目录logs/下对应.log文件的最后几十行八成是端口占用或内存不足。2.3 电影网站日志的字段设计电影网站的行为日志一般有三类用户表user_id、注册性别、年龄、评分表user_id、movie_id、rating、timestamp、浏览表user_id、movie_id、停留时长、点击次数。性别预测的标签来自用户表里填了性别的那部分人特征来自评分和浏览行为。把这三份数据放到 HDFS 上hdfs dfs -mkdir -p /movie/input hdfs dfs -put users.csv /movie/input/ hdfs dfs -put ratings.csv /movie/input/ hdfs dfs -put views.csv /movie/input/ hdfs dfs -ls /movie/input常见做法是把原始 CSV 先落到 HDFS再用 Hive 建外部表指向它这样清洗逻辑用 SQL 写比手写 MapReduce 快得多。如果你的环境里还没装 Hive也可以先用 MapReduce 或 Spark 读 CSV但特征聚合这一步用 SQL 会省很多事。3. 用 Hive 做行为特征聚合把日志变成性别可用的向量3.1 特征到底该取哪些性别预测不是靠单条记录而是靠这个用户长期偏好什么。经验上区分度最高的几类特征评分均值女性用户打分普遍偏高、评分方差男性用户两极分化更明显、高分电影的类型分布爱情/动作占比、活跃时段深夜活跃比例、浏览停留时长。这些都能从评分表和浏览表聚合出来按 user_id 分组一行一个用户。标签处理上有个坑用户表里性别字段可能是男/女/M/F/1/0/未知混着来必须先归一化把未知的整行丢掉否则训练集里混进噪声标签模型学出来的东西没法解释。3.2 建外部表并清洗标签-- 用户表把性别归一化成 0/1未知的过滤掉 CREATE EXTERNAL TABLE ods_users ( user_id STRING, gender STRING, age INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY , STORED AS TEXTFILE LOCATION /movie/input/users.csv; -- 清洗后落到明细表只保留性别明确的用户 CREATE TABLE dwd_user_label AS SELECT user_id, CASE WHEN lower(trim(gender)) IN (m,male,男,1) THEN 1 WHEN lower(trim(gender)) IN (f,female,女,0) THEN 0 ELSE NULL END AS label FROM ods_users WHERE lower(trim(gender)) IN (m,male,男,1,f,female,女,0);逻辑说明CASE WHEN把各种写法统一成 1男和 0女WHERE子句把无法识别的行直接排除。参数上注意trim和lower要一起用日志里经常有 Male 这种带空格和大小写混杂的值只做其中一个会漏。3.3 聚合评分与浏览特征-- 评分特征均值、方差、评分数 CREATE TABLE dwd_rating_feat AS SELECT user_id, count(*) AS rating_cnt, avg(rating) AS rating_avg, variance(rating) AS rating_var, max(rating) - min(rating) AS rating_range FROM ods_ratings GROUP BY user_id; -- 浏览特征总停留、平均停留、深夜活跃比例 CREATE TABLE dwd_view_feat AS SELECT user_id, sum(duration) AS view_total, avg(duration) AS view_avg, sum(CASE WHEN hour(ts) 23 OR hour(ts) 5 THEN 1 ELSE 0 END) / count(*) AS night_ratio FROM ods_views GROUP BY user_id;参数说明variance是 Hive 内置聚合函数直接给方差不用自己算平方和。night_ratio用整数除法在部分 Hive 版本里会截断成 0稳妥写法是乘 1.0 转浮点sum(...) * 1.0 / count(*)。这一步跑完把三张表按 user_id join 起来就是训练宽表CREATE TABLE dws_user_feature AS SELECT l.user_id, l.label, r.rating_cnt, r.rating_avg, r.rating_var, r.rating_range, v.view_total, v.view_avg, v.night_ratio FROM dwd_user_label l LEFT JOIN dwd_rating_feat r ON l.user_id r.user_id LEFT JOIN dwd_view_feat v ON l.user_id v.user_id;用LEFT JOIN而不是JOIN是因为有些用户只浏览不评分内连接会把他们丢掉样本量白白少一截。join 完把结果导出到本地或 HDFS供后面建模用hive -e SELECT * FROM dws_user_feature user_feature.tsv4. 训练性别预测模型从宽表到可解释的基线4.1 为什么先做逻辑回归而不是直接上深度模型性别预测这种二分类特征就十来个样本量通常几万到几十万逻辑回归的准确率往往和复杂模型差不了几个点但可解释性强——你能直接看系数说评分均值越高越可能是女性。先跑一个基线知道数据本身能到多少分再决定要不要上 XGBoost 或神经网络。很多课程设计翻车就翻在直接上深度模型调参调到怀疑人生最后连基线都没跑出来。4.2 用 pandas sklearn 跑通基线import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import StandardScaler from sklearn.metrics import classification_report # 读 Hive 导出的宽表缺失值用 0 填充未评分用户 df pd.read_csv(user_feature.tsv, sep\t) df df.fillna(0) feat_cols [rating_cnt, rating_avg, rating_var, rating_range, view_total, view_avg, night_ratio] X df[feat_cols].values y df[label].values # 标准化逻辑回归对量纲敏感view_total 动辄上万不缩放会压过其他特征 scaler StandardScaler() X scaler.fit_transform(X) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy) clf LogisticRegression(max_iter1000, class_weightbalanced) clf.fit(X_train, y_train) print(classification_report(y_test, clf.predict(X_test)))逻辑说明fillna(0)处理未评分/未浏览用户StandardScaler做标准化stratifyy保证训练测试集里男女比例一致class_weightbalanced应对性别样本不均衡。参数上max_iter默认 100 在特征多时经常不收敛调到 1000 稳妥。跑完看classification_report如果某一类 recall 特别低多半是样本不均衡先回去查数据分布别急着换模型。4.3 特征重要性的快速验证逻辑回归的系数可以直接看方向for name, coef in zip(feat_cols, clf.coef_[0]): print(f{name:15s} {coef:.3f})系数为正表示该特征越大越偏向 label1。如果night_ratio系数接近 0说明深夜活跃对性别没区分度可以从特征里删掉减少过拟合。这一步是很多人跳过的但它能帮你判断特征工程到底有没有用。5. 避坑与排查伪分布式跑电影日志最容易翻的五个地方5.1 现象任务卡在 ACCEPTED 不动原因YARN 容器内存配置超过 NodeManager 可用内存或者yarn.nodemanager.resource.memory-mb设得比物理内存还大。解决把maximum-allocation-mb调到 1024 以下resource-memory-mb不超过物理内存的 70%重启 YARN 再提交。5.2 现象Hive 查询报错 Vertex failed 或内存溢出原因默认 MapReduce 任务内存不够join 大表时尤其明显。解决提交前设置set mapreduce.map.memory.mb1024; set mapreduce.reduce.memory.mb1024;或者改用hive.auto.convert.jointrue让小表走 MapJoin。5.3 现象性别标签归一化后样本只剩一半原因原始日志里性别字段大量为空或写成保密未知WHERE过滤把这些人全丢了。解决先统计各取值的数量再决定过滤规则如果明确标签太少考虑用半监督或只对有标签用户建模别硬凑。5.4 现象模型准确率 90% 但预测全是同一类原因性别样本严重不均衡模型学会了全猜多数类。解决看classification_report里少数类的 recall用class_weightbalanced或对少数类过采样别只看 accuracy。5.5 现象重复格式化 NameNode 后数据全没了原因hdfs namenode -format会重建元数据原 DataNode 上的块对不上。解决格式化只在首次安装时做一次之后要重置就先把dfs.namenode.name.dir和dfs.datanode.data.dir目录清空再格式化别在跑着数据的集群上随手执行。6. 把单机流程搬到集群几个真正省时间的技巧伪分布式跑通之后往真集群迁移时业务代码基本不用动要改的是配置和资源申请。我一般会先把core-site.xml里的fs.defaultFS换成集群 NameNode 地址hdfs-site.xml副本数改回 3然后重点调 YARN 的资源队列。集群上最容易忽略的是数据本地性如果 HDFS 块和计算节点不在同一台机器任务会走网络拉数据速度差好几倍。提交任务时用mapreduce.job.reduce.slowstart.completedmaps0.8让 reduce 早点启动能省不少等待时间。验证迁移是否成功不要只看任务成功要对比单机和集群跑出来的dws_user_feature行数和几个聚合值是否一致。我吃过一次亏集群上 Hive 的variance因为版本差异返回了不同精度导致特征分布偏移模型准确率掉了三个点查了半天才发现是函数行为不一致。所以跨环境一定要做数据对账别信任务成功就是对的。最后一个习惯每次改完配置或 SQL先把中间表count(*)和几个关键字段的min/max/avg打出来存一份出问题时能快速定位是哪一步开始偏的。这套流程不复杂难的是每一步都留下可对比的痕迹。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →