Movielens数据集内主要文件有三个:1.u.user 介绍用户的信息 2.u.item 介绍电影元数据 3.u.data 介绍用户对电影的评分数据
1.u.user的主要字段有:用户ID(user ID),年龄(age) ,性别(gender),职业(occupation),邮编(ZIPcode)五个属性。
2.u.item的主要字段有:电影id(movie id),电影标题(title),发行日期(release date),电影分类(category)
3.u.data的主要字段有:用户id(user id),电影id(movie id),评级(rating),时间戳(timestamp)
1.对于u.user数据文件,对于分类变量(用户ID,性别,职业,邮编)可以统计总数,对类别数量不多的特征可以统计各个类别所占比例(男女比例,职业比例);对于数值型变量(年龄)可以对连续型数据的分布做一个分析(箱线图,直方图)
pyspark
user_data = sc.textFile('file:///home/user/Sparklearning/u.user')
spark的文件读取默认是从hdfs文件系统中读取,如果要读取本地文件需要在路径前面加上file://。。。
user_data.first()
取出文件中的第一行返回到终端,对数据的形式有一个了解
统计用户人数,职业数
user_fields = user_data.map(lambda line: line.split('|'))
num_user = user_fields.map(lambda fields: fields[0]).distinct().count()
num_collection = user_fields.map(lambda fields: fields[3]).distinct().count()
print("User:%d,Occupation:%d"%(num_user,num_collection))
用matplotlib库来绘制连续变量age的数据分布情况
import matplotlib.pyplot as plt
ages = user_fields.map(lambda fiedls:int(fields[1])).collect()
plt.hist(ages,bins=20,color='lightblue',normed=True)
plt.xlabel('ages percent')
plt.ylabel('ages')
plt.show()
想了解职业的分布情况,通过条形图(bar)
count_by_occupation = user_fields.map(lambda fields: (fields[3],1)).reduceByKey(lambda x,y:x+y).collect()
x_axis = np.array([c[0] for c in count_by_occupation])
y_axis = np.array([c[1] for c in count_by_occupation])
由于通过collect()返回的数据并没有排序,希望在条形图中以各职业数从低到高进行呈现,通过numpy数组的性质来对数据进行排序
x_axis = x_axis[argsort(y_axis)]
y_axis = y_axis[argsort(y_axis)]
import matplotlib.pyplot as plt
pos = np.arrange(len(x_axis))
width = 1.0
设置x坐标轴的属性特征
ax = plt.axes()
ax.set_xticks(pos+(width/2))
ax.set_xticklabels(x_axis)
设置条形图
plt.bar(pos,y_axis,width,color='lightblue')
plt.xticks(rotation=30)
plt.show()
Bob WU划重点:spark提供了countByValue的便捷函数来替代先map在reduceByKey这两步操作,结果通过python的dict形式返回给终端。
count_by_occupation2 = user_fields.map(lambda fields:fields[3]).countByValue()
2.对于u.item数据集,重要特征有电影标题,电影发行日期,电影分类。对电影的总数进行一个统计,让然后可以对电影发行日期做进一步分析,研究电影发布的时间的分布。由于原始数据对于时间的数据不规则,需要对日期数据进行结构化。
movie_data = sc.textFile('file://..../u.item')
print(movie_data.first())
num_movies = movie_data.count()
print("Movies:%d" % num_movies)
def convert_year(x):
try:
return int(x[-4:])
except:
return 1900
movie_fields = movie_data.map(lambda line:line.split('|'))
years = movie_fields.map(lambda fields:fields[2]).map(lambda x:convert_year(X))
years_filtered = years.filter(lambda x:x != 1900)
movie_age = years_filtered.map(lambda yr:1998-yr).countByValue()
values = movie_ages.values()
bins = movie_ages.keys()
hist(values,bins,color='lightblue',normed=True)
plt.show()
3.对于u.data数据集,重要特征主要有用户ID,电影ID,评分,时间戳。
统计一下总评论数,可以计算一下评分的均值,可以分析一下评分的分布情况。
rating_data = sc.textFile('file://.../u.data')
print(rating_data.first())
num_rating = rating_data.count()
print("Ratings:%d"% num_rating)
计算一下评分的统计描述(总数,均值,标注差,最大值,最小值)
rating_data = rating_data.map(lambda line: line.split('\t'))
rating = rating_data.map(lambda fields:int(field[2]))
median_rating = np.median(rating.collect())
ratings_per_user = num_rating / num_users
rating_per_movie = num_rating / num_movies
rating.stats()
电影评分数据分布
count_by_rating = ratings.countByValue()
x_axis = np.array(count_by_rating.keys())
y_axis = np.array([float(c) for c in count_by_rating.values()]
y_axis_normed = y_axis/y_axis.sum()
pos = np.arange(len(x_axis))
width = 1.0
ax = plt.axes()
ax.set_xticks(pos+(width/2))
ax.set_xticklabels(x_axis)
plt.bar(pos,y_axis_normed,width,color='lightblue')
plt.xticks(rotation=30)
plt.show()
用户评分次数的分布情况
user_rating_grouped = rating_data.map(lambda fields:(int(fields[0],int(fields[2]))).groupByKey()
user_rating_byuser = user_rating_grouped.map(lambda (k,v):(k,len(v)))
user_rating_byuser_local = user_rating_byuser.map(lambda (k,v):v).collect()
plt.hist(user_rating_byuser,bins=200,color='lightblue',normed=True)
plt.show()