用户数据处理

用户数据文件user.dat中的数据格式为:UserID::Gender::Age::Occupation::Zip-code。存储形式如下图所示:

用户数据处理 - 图1

上图中,每一行表示一个用户的数据,以

用户数据处理 - 图2 隔开,第一列到最后一列分别表示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。

首先,读取用户信息文件中的数据:

  1. # 解压数据集
  2. !cd work && unzip -o -q ml-1m.zip
  1. import numpy as np
  2. usr_file = "./work/ml-1m/users.dat"
  3. # 打开文件,读取所有行到data中
  4. with open(usr_file, 'r') as f:
  5. data = f.readlines()
  6. # 打印data的数据长度、第一条数据、数据类型
  7. print("data 数据长度是:",len(data))
  8. print("第一条数据是:", data[0])
  9. print("数据类型:", type(data[0]))
  1. data 数据长度是: 6040
  2. 第一条数据是: 1::F::1::10::48067
  3.  
  4. 数据类型: <class 'str'>

观察以上结果,用户数据一共有6040条,数据以

用户数据处理 - 图3 分隔,是字符串类型。为了方便后续数据读取,区分用户的ID、年龄、职业等数据,一个简单的方式是将数据存储到字典中。另外在自然语言处理章节中我们了解到,文本数据无法直接输入到神经网络中进行计算,所以需要将字符串类型的数据转换成数字类型。 另外,用户的性别F、M是字母数据,这里需要转换成数字表示。

我们定义如下函数实现字母转数字,将性别M、F转成数字0、1表示。

  1. def gender2num(gender):
  2. return 1 if gender == 'F' else 0
  3. print("性别M用数字 {} 表示".format(gender2num('M')))
  4. print("性别F用数字 {} 表示".format(gender2num('F')))
  1. 性别M用数字 0 表示
  2. 性别F用数字 1 表示

接下来把用户数据的字符串类型的数据转成数字类型,并存储到字典中,实现如下:

  1. usr_info = {}
  2. max_usr_id = 0
  3. #按行索引数据
  4. for item in data:
  5. # 去除每一行中和数据无关的部分
  6. item = item.strip().split("::")
  7. usr_id = item[0]
  8. # 将字符数据转成数字并保存在字典中
  9. usr_info[usr_id] = {'usr_id': int(usr_id),
  10. 'gender': gender2num(item[1]),
  11. 'age': int(item[2]),
  12. 'job': int(item[3])}
  13. max_usr_id = max(max_usr_id, int(usr_id))
  14. print("用户ID为3的用户数据是:", usr_info['3'])
  1. 用户ID3的用户数据是: {'usr_id': 3, 'gender': 0, 'age': 25, 'job': 15}

至此,我们完成了用户数据的处理,完整的代码如下:

  1. import numpy as np
  2. def get_usr_info(path):
  3. # 性别转换函数,M-0, F-1
  4. def gender2num(gender):
  5. return 1 if gender == 'F' else 0
  6. # 打开文件,读取所有行到data中
  7. with open(path, 'r') as f:
  8. data = f.readlines()
  9. # 建立用户信息的字典
  10. use_info = {}
  11. max_usr_id = 0
  12. #按行索引数据
  13. for item in data:
  14. # 去除每一行中和数据无关的部分
  15. item = item.strip().split("::")
  16. usr_id = item[0]
  17. # 将字符数据转成数字并保存在字典中
  18. use_info[usr_id] = {'usr_id': int(usr_id),
  19. 'gender': gender2num(item[1]),
  20. 'age': int(item[2]),
  21. 'job': int(item[3])}
  22. max_usr_id = max(max_usr_id, int(usr_id))
  23. return use_info, max_usr_id
  24. usr_file = "./work/ml-1m/users.dat"
  25. usr_info, max_usr_id = get_usr_info(usr_file)
  26. print("用户数量:", len(usr_info))
  27. print("最大用户ID:", max_usr_id)
  28. print("第1个用户的信息是:", usr_info['1'])
  1. 用户数量: 6040
  2. 最大用户ID: 6040
  3. 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),都已处理成数字类型。