Spark机器学习实战(二)电影评分数据获取与可视化

Spark机器学习实战(二)电影评分数据获取与可视化

这个系列要完成的是一个电影服务提供网站的大数据分析,包括推荐系统等等。

一个机器学习系统的主要步骤为:数据获取与存储 => 数据清理与转换 => 模型训练与测试回路 => 模型部署与整合 => 模型监控与反馈

在这一部分中,我们做的就是机器学习的前两步,首先获取数据(数据来源为MovieLens数据集),之后对数据作简要分析并可视化数据,为进一步的工作做准备。

文章中列出了关键代码,完整代码见我的github repository,这篇文章的代码在chapter03/movielens_analysis.py

第1步:数据集下载

我们使用的是MovieLens 100k数据集,它包含了100000条用户对电影的点评(1分到5分)。数据集主要包含这么几个部分。

用户列表u.user,包含用户年龄,性别,职业,邮编信息

1|24|M|technician|85711
2|53|F|other|94043
3|23|M|writer|32067
4|24|M|technician|43537
...

电影列表u.item,包含了电影的基本信息

1|Toy Story (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Toy%20Story%20(1995)|0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0
2|GoldenEye (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?GoldenEye%20(1995)|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0
...

点评列表u.data,包含了用户编号,电影编号,评分,时间戳

196 242 3   881250949
186 302 3   891717742
22  377 1   878887116
244 51  2   880606923

数据集不大也不小,非常适合作机器学习算法,而且本地运行也非常快速。

我们把数据集下载下来并解压,把解压路径放在变量PATH中。

第2步:用户数值统计

我们使用最基本的RDD操作,来对u.user数据的做一些统计,包括:用户人数,性别数量,职业数量,不同邮编数量,非常简单,看了下面的代码就可以理解。

注意,以下代码为Python代码,为什么?因为Python Spark尽管运行速度不及Scala,然而数据可视化非常方便,因此这里用python。

运行代码的方式有两种:

  1. 使用Python Spark交互式编程,那么可以省去SparkContext的实例化
$ $SPARK_HOME/bin/pyspark
  1. 编写python代码,并使用spark-submit工具
$ $SPARK_HOME/bin/spark-submit myapp.py

直接上代码:

from pyspark import SparkContext
import matplotlib.pyplot as plt
import numpy as np

sc = SparkContext("local", "Movielens Analysis")
sc.setLogLevel("ERROR") 
PATH = "..."

## 1. Do some statistics
user_data = sc.textFile("%s/ml-100k/u.user" % PATH)
user_fields = user_data.map(lambda line: line.split('|'))
num_users = user_fields.count()
num_genders = user_fields.map(lambda fields: fields[2]).distinct().count()
num_occupations = user_fields.map(lambda fields: fields[3]).distinct().count()
num_zipcodes = user_fields.map(lambda fields: fields[4]).distinct().count()
print("Users:%d, genders:%d, occupations:%d, ZIP codes:%d" 
    %(num_users, num_genders, num_occupations, num_zipcodes))

稍作解释,首先读取数据集,随后从对应位置取出相应数据,如职业位于第4栏,distinct()可以去除重复数据,最后的count()为行为操作,返回不重复的职业数量。

运行后结果为:

Users:943, genders:2, occupations:21, ZIP codes:795

意味着我们一共有来自21种不同职业的943位用户对电影作了评价

第3步:用户年龄分布直方图

数据可视化是数据分析中很重要的一部分,先对数据集可视化可以让我们对数据集有一个完整的把握。那么数据可视化一个比较方便的Python库就是matplotlib。本文不会讲解该库的用法,官方文档中有不少例子很方便学习。

## 2. Draw histgrams of age
ages = user_fields.map(lambda fields: int(fields[1])).collect()
fig1 = plt.figure()
plt.hist(ages, bins = 20, edgecolor='black')
plt.title("Age histogram")
plt.xlabel("Age")
plt.ylabel("Number")

当然这种作图方式不是很好,因为ages包含了所有年龄信息,而直方图统计是交给Python执行的,最好的方式是把相同年龄的人的数量统计交给reduceByKey(),countByKey()这类函数。

作图结果如下:

年龄分布

第4步:职业分布

大致上与年龄分布的处理方式是一致的,只是横坐标不是数据而是职业名称,而且需要提前作一下排序。

## 3. Draw job distribution
occupations = user_fields.map(lambda 
    fields: (fields[3], 1)).reduceByKey(lambda 
    x, y: x + y).sortBy(lambda x: x[1]).collect()
fig2 = plt.figure(figsize=(9, 5), dpi=100)
x_axis = [occu[0] for occu in occupations]
y_axis = [occu[1] for occu in occupations]
pos = np.arange(len(x_axis))
width = 1.0
ax = plt.axes()
ax.set_xticks(pos + 0.5)
ax.set_xticklabels(x_axis)
plt.bar(pos, y_axis, width, edgecolor='black')
plt.xticks(rotation=30)
plt.ylabel("Number")
plt.title("Job distribution")

主要看RDD操作,首先把职业map成(occupation, 1)的键值对,随后用reduceByKey()可以实现不同职业数量的求和,再对数量进行排序sortBy(),最后行为操作collect()取出数据。

职业分布

第5步:其他各种可视化与统计

电影年龄统计,统计值为距离1998年的距离,即1990年的电影计为8岁。

电影年龄

用户评分统计,统计了最高分,最低分,中位数,平均数,平均每人评分电影数量,以及平均每部电影评价数量。

Min rating:1, max rating:5, average rating:3.53, median rating:4
Average # of rating per user: 106.0
Average # of rating per movie: 59.5

之后还有电影评分分布,可以看到4分的评分是最多的。

电影评分分布

用户评价电影数量排行,数据有点多,显示得不是很好。

每位用户评分电影数量
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容