盒子
盒子
文章目录
  1. 流程
  2. 任务分配
  3. 爬虫
  4. 清洗,挖掘,分析
  5. 搭建
    1. 数据可视化展示
    2. 具体展示了啥
    3. 前端
    4. 后端
  6. 预测与推荐
    1. 预测
    2. 推荐
    3. 我理解的推荐
      1. 基于用户的推荐算法
      2. 基于内容的推荐算法
      3. 比较

大数据 demo (采集,处理,应用)复盘

流程

数据采集→数据处理→数据分析→应用

首先,通过爬虫抓取 51Job ,智联招聘等网站有关大数据的职位数据.通过爬虫得到的数据是非常乱的,即便我们在保存的时候已经尽量规定好了格式,所以要对数据进行清洗,把数据格式化.(也许后面还应该去除重复,错误的数据…)

现在我们得到一堆数据了,一方面我们可以对这些数据进行数据挖掘,找到数据间的高价值信息(比如说求职地对工资的影响啦什么的).其次,我们还可以根据这些信息,与用户的信息进行对比,预测用户的工资区间,为用户推荐工作什么的…

有了一堆高价值信息,要展现啊,而且还得与用户进行交互(以做预测,推荐).这一块通过搭建网站来实现.

任务分配

森林爬虫,波波老师数据分析,挖掘,我搭建网站.

爬虫

用的 jsoup.

可以对 51Job, 智联招聘这两个网站进行数据采集.设置了几个参数,可以与网站后台管理交互.

通过后台来管理爬虫爬取的频率,数据存放的目录什么的…

爬虫保存的文件的方式是每多少个数据生成一个 json 文件,文件名以 1.json,2.json …这样命名.(为了方便后续步骤)

清洗,挖掘,分析

这一块的细节我不是很清楚

搞了 3 台虚拟机(centos)搭建了个 Hadoop 集群.

一开始选择的是 Hadoop,后面发现 Hadoop 对离线计算支持的很好,要是搞实时计算,用 Spark 比较好.(也不知道具体情况.Spark 没用.)

使用 flume 监听爬虫采集的存放目录(理论上是可行的,不过没研究虚拟机怎么和本机目录交互,所以没搞.),当爬虫开始执行,该目录就不断生成职位数据,每当有新数据产生,flume就会把文件采集到hdfs中去储存.

在此,通过 Hadoop MapReduce 对离线数据进行清洗,得到优质的,格式化的数据.


然后我们把数据从 hdfs 导入 hive,进行数据挖掘.在这一步,我们首先对数据进行聚类,大致找出这些独立数据之前的联系,再通过手动筛选,剔除那些不符合我们预期的信息,再用已有数据对数据进行训练,以此得到精确度较高的聚类手段与符合期望的数据.(聚类了,但是剔除什么的没做…)


hive 可以把数据导入到数据库,我们把清洗后的职位数据导入到 MySql ,然后就能基本展现一些东西了…


这里和前台页面联系一下.

比如我们想在前台用直方图的形式展示求职地与工资的关系,如果我们在后端进行计算,每打开一次展示的页面就要计算一次,太耗费资源了(主要是显示太慢了,到时候录视频展示项目岂不是很尴尬.).

而且这类数据变动也不大,所以就在数据处理这一块先把这类信息计算出来,再导入数据库的某张表里.到时候显示就只需直接取表的数据,不用进行多余的计算了.

搭建

前端写的太差劲了.后台管理用的开源页面,还可以.

数据可视化展示

  • 图表展示 : ECharts
  • 表格展示 : Bootstrap Table

展示了啥?

具体展示了啥

工资 - 地区 关系

工资 - 学历 关系

岗位能力需求词云

基本的信息检索

前端

不过插件使用倒是熟练了不少,插件版本不兼容什么的问题也遇到一大堆.

jquery 插件到哪里下载呢

标签插件

表单验证插件

图表,表格插件

还有啥?

没了…

后端

采用 Spring Boot,idea 创建一个 Spring Boot 项目很简单,有 Spring Initializr.

写了一个小小的 demo,感觉用了不少东西,其实也没多少,都只局限于知道这个工具是干啥的的阶段.

  • 项目自动化构建工具:gradle

    ​ 源到 maven 仓库 找.

  • 权限管理:Spring Security

    用于判断登录用户的访问权限,比如区分普通会员和管理员之类的.想要自定义使用的话,好麻烦哦.

    之前记录了一些使用方式,还没写完…

    Java模板引擎:Thymeleaf

    想到如果数据全都通过 json 来传,模板的作用是不是就不大了?

  • 持久层框架:MyBatis

    怎么配置.

    mybatis-genetator 插件,用于自动把数据库里的表生成 bean(提供了 getter,setter的 java 类),Mapper(通过 mabatis 与数据库交互相关的接口,比如增删查这个表里的东西…没什么大用,只是节省了创建接口的时间,具体的 SQL 还得自己写.).

    数据库查询还用了分页插件 pagehelper …配合前端的表格插件,实现显示数据的分页功能.

  • debug 工具

    log4j2

  • fastjson

    SpringMVC 自带的 json 工具不够用…

值得一提的就是学会了写一个稍微有点复杂的 SQL 语句.(波波老师写的,模仿了一下,收获不少.)

其他的收获都是对工具的熟练…

预测与推荐

预测

这一步在后端来实现,不过波波老师写了一个 R 的脚本放在服务器,我直接远程调用.

原理是进行多元回归.

这里是用户传来的数据与 Hadoop 中数据交互计算…

Kmeans聚类:程序调用 mahout 算法库API实现

回归建模:工资(Y)~ 学历(X1)+求职地(X2)+ 岗位类别(X3)+经验(X4)+企业性质(X5)

推荐

怎么做推荐呢?实际开发过程中,我们一边学习推荐相关的知识,一边先按直觉做了几个 demo.

在第一个版本中,用模糊查询实现.根据用户的相关信息到数据查询.大概是因为逻辑判断太多了,速度非常慢.

第二个版本,尝试优化查询语句,建立索引.

第三个版本.因为前面已经通过多元回归计算出了用户的工资区间(虽然很不准确就是了),我们拍脑袋觉得对于一份工作来说,工资是很重要的,于是直接按工资区间到数据库查询…

前两个版本,模糊查询的推荐结果还不错,至少能一眼看出与用户的信息有关.但是速度实在太慢了.

第三个版本,因为前面做的预测结果本来就不准,所以效果更差劲…而且这个思路太想当然了.

但至少现在已经有这样一个功能模块了!!于是接着尝试真正的推荐.

我理解的推荐

因为水平不到位,不能从比较宏观的角度解释,下面都只是我在这个项目中的感受.所以,推荐以”推荐 Job”为例…

我理解的推荐,就是为用户建立一个模型——“我最喜欢的 Job”,系统不断优化这个模型,试图找到用户心中最中意的那个 Job.(这只是个理想化的模型,实际的系统当中可能并不存在)然后从系统中找出与这个模型最匹配的 Job,推荐给用户.

那么问题来了,计算机怎么判断用户是不是中意某个 Job 呢?

我们看看协同过滤算法中的基于用户的推荐算法.

基于用户的推荐算法

最简单的一种,如下:

1
2
小明 喜欢 A,B,C.
小红 喜欢 A,B,C,D.

我们发现小红的喜欢和小明的喜欢重叠度很高,小明可能也会喜欢 D,所以把 D 推荐给他.

但是这种判断的粒度太大了,再细一点可以这样:

1
2
3
4
5
小明 非常喜欢 A
小明 有点喜欢 B

小红 非常喜欢 B
小红 有点喜欢 A

在计算机中,可以简化为这样的三元组 < 用户 ID, 物品 ID, 用户偏好 > 表示:

1
2
3
4
5
6
用户   JobID   偏好值(权重)
小明 001 15
小明 002 0

小红 001 0
小红 002 15

那么这个偏好值怎么来呢?

肯定需要严格的算法…

我们可以粗略举个例子来理解,比如用户点击一次某个职位,我们假定他是被这个职位所吸引,把他与这个职位的权重相应增加.

这样在计算机内部就得到用户与 Job 的关系.

用这样的数值来量化之后,我们就可以通过做一些矩阵运算,根据用户自己的列表和别的用户的列表,把口味相似的用户关注的职位推荐给用户.

好了!暂且到这一步.

我们回过头来看,基于用户的推荐算法,需要满足两项.

  1. 用户(使用推荐功能的用户)的喜好
  2. 别的用户的喜好

这就是冷启动需要解决的问题.它不仅需要用户自己有信息,还需要别的用户有信息…

考虑到我们做的这个小项目根本不可能有那么多用户,测试起来也麻烦,看来这个方式不合适…

基于内容的推荐算法

基于用户的推荐算法,是通过比较各个用户的喜好,把别的用户关注的东西推荐给有共同喜好的用户.

而基于内容的推荐算法,就是把用户的喜好直接与 Job (物品)比较.

还是看个最简单的:

1
2
小红       喜欢 哲学书籍
《大问题》 是 哲学书籍

所以把《大问题》推荐给小红.

同样,我们可以更细粒度一点:

1
2
3
4
5
小红       非常喜欢   哲学书籍
小红 有点喜欢 小说

《大问题》 是 哲学书籍
《爱的教育》 是 小说

我们优先推荐《大问题》给小红…

而在计算机内,可能是这样表示的:

1
2
3
4
5
6
7
8
9
用户		标签		权重
小红 Java 10
小红 Web 9

Job 标签 权重
001 Java 0
001 Web 10
002 Java 10
002 Web 9

通过计算向量距离,得出用户和 Job 的相似度,生成推荐.

基于内容的推荐需要解决两个问题.

第一个仍然是冷启动,用户需要打上标签.我们考虑过根据用户的行为——历史记录,点击记录等来生成用户标签.不过都没时间做…

其实提到这个场景,我想到的是各种信息流 app,注册时让用户选择一堆感兴趣的话题,相当于打上标签.于是我也模仿这样做了个…

我们只做到了用户和某个标签产生联系,如标签 Hadoop , Java

存在数据库里 :

1
2
3
4
用户 ID		标签Id		有无 #标志用户有没有选择某个标签...
001 001 0
001 002 1
...

第二个问题就是提取出 Job 的标签,并且提取权重.

这个是重点也是难点…

从抽象的角度来看,Job 其实也只是一串文本描述的一样物品.

粗略地做,我们可以进行简单的词频统计…

常用的更标准的方式是使用 TF-IDF.

比较

SQL 模糊查询是基于元数据的推荐.比如推荐书,紧紧按出版年份来推荐是不太合适的.(大多数情况下)

而协同过滤,是基于标签,更合理些(理论上).

我们做出来的效果,感觉模糊查询似乎看起来科学点…至少能在推荐的结果找到我们的输入的信息.通过后面的方式得到的推荐结果(因为我们技术不到位的原因)看起来有点没头没脑…