用户数据处理
用户数据文件user.dat中的数据格式为:UserID::Gender::Age::Occupation::Zip-code。存储形式如下图所示:
上图中,每一行表示一个用户的数据,以
隔开,第一列到最后一列分别表示UserID、Gender、Age、Occupation、Zip-code。各数据对应关系如下:
数据类别 | 数据说明 | 数据示例 |
---|---|---|
UserID | 每个用户的数字代号 | 1、2、3等序号 |
Gender | F表示女性,M表示男性 | F或M |
Age | 用数字表示各个年龄段 | - 1: “Under 18” - 18: “18-24” - 25: “25-34” - 35: “35-44” - 45: “45-49” - 50: “50-55” - 56: “56+” |
Occupation | 用数字表示不同职业 | - 0: “other” or not specified - 1: “academic/educator” - 2: “artist” - 3: “clerical/admin” - 4: “college/grad student” - 5: “customer service” - 6: “doctor/health care” - 7: “executive/managerial” - 8: “farmer” - 9: “homemaker” - 10: “K-12 student” - 11: “lawyer” - 12: “programmer” - 13: “retired” - 14: “sales/marketing” - 15: “scientist” - 16: “self-employed” - 17: “technician/engineer” - 18: “tradesman/craftsman” - 19: “unemployed” - 20: “writer” |
zip-code | 邮政编码,与用户所处的地理位置有关。 在本次实验中,不使用这个数据。 | 48067 |
比如82::M::25::17::48380表示ID为82的用户,性别为男,年龄为25-34岁,职业为technician/engineer。
首先,读取用户信息文件中的数据:
# 解压数据集
!cd work && unzip -o -q ml-1m.zip
import numpy as np
usr_file = "./work/ml-1m/users.dat"
# 打开文件,读取所有行到data中
with open(usr_file, 'r') as f:
data = f.readlines()
# 打印data的数据长度、第一条数据、数据类型
print("data 数据长度是:",len(data))
print("第一条数据是:", data[0])
print("数据类型:", type(data[0]))
- data 数据长度是: 6040
- 第一条数据是: 1::F::1::10::48067
- 数据类型: <class 'str'>
观察以上结果,用户数据一共有6040条,数据以
分隔,是字符串类型。为了方便后续数据读取,区分用户的ID、年龄、职业等数据,一个简单的方式是将数据存储到字典中。另外在自然语言处理章节中我们了解到,文本数据无法直接输入到神经网络中进行计算,所以需要将字符串类型的数据转换成数字类型。 另外,用户的性别F、M是字母数据,这里需要转换成数字表示。
我们定义如下函数实现字母转数字,将性别M、F转成数字0、1表示。
def gender2num(gender):
return 1 if gender == 'F' else 0
print("性别M用数字 {} 表示".format(gender2num('M')))
print("性别F用数字 {} 表示".format(gender2num('F')))
- 性别M用数字 0 表示
- 性别F用数字 1 表示
接下来把用户数据的字符串类型的数据转成数字类型,并存储到字典中,实现如下:
usr_info = {}
max_usr_id = 0
#按行索引数据
for item in data:
# 去除每一行中和数据无关的部分
item = item.strip().split("::")
usr_id = item[0]
# 将字符数据转成数字并保存在字典中
usr_info[usr_id] = {'usr_id': int(usr_id),
'gender': gender2num(item[1]),
'age': int(item[2]),
'job': int(item[3])}
max_usr_id = max(max_usr_id, int(usr_id))
print("用户ID为3的用户数据是:", usr_info['3'])
- 用户ID为3的用户数据是: {'usr_id': 3, 'gender': 0, 'age': 25, 'job': 15}
至此,我们完成了用户数据的处理,完整的代码如下:
import numpy as np
def get_usr_info(path):
# 性别转换函数,M-0, F-1
def gender2num(gender):
return 1 if gender == 'F' else 0
# 打开文件,读取所有行到data中
with open(path, 'r') as f:
data = f.readlines()
# 建立用户信息的字典
use_info = {}
max_usr_id = 0
#按行索引数据
for item in data:
# 去除每一行中和数据无关的部分
item = item.strip().split("::")
usr_id = item[0]
# 将字符数据转成数字并保存在字典中
use_info[usr_id] = {'usr_id': int(usr_id),
'gender': gender2num(item[1]),
'age': int(item[2]),
'job': int(item[3])}
max_usr_id = max(max_usr_id, int(usr_id))
return use_info, max_usr_id
usr_file = "./work/ml-1m/users.dat"
usr_info, max_usr_id = get_usr_info(usr_file)
print("用户数量:", len(usr_info))
print("最大用户ID:", max_usr_id)
print("第1个用户的信息是:", usr_info['1'])
- 用户数量: 6040
- 最大用户ID: 6040
- 第1个用户的信息是: {'usr_id': 1, 'gender': 1, 'age': 1, 'job': 10}
从上面的结果可以得出,一共有6040个用户,其中ID为1的用户信息是{‘usr_id’: [1], ‘gender’: [1], ‘age’: [1], ‘job’: [10]},表示用户的性别序号是1(女),年龄序号是1(Under 18),职业序号是10(K-12 student),都已处理成数字类型。