文章目錄
- 一、總述
- 二、處理流程
-
- 1. 處理 users 資料
- 2. 處理 movies 資料
- 3. 處理 ratings 資料
- 4. 将 users、movies 和 ratings 資料合并
- 5. one-hot 處理
- 6. 完整代碼
一、總述
該文記錄處理 MovieLens-1m 資料集的步驟,首先分别處理使用者、電影和評分資料,接着将這三部分資料進行合并,最後 one-hot 處理。
二、處理流程
1. 處理 users 資料
users 資料描述:
使用者檔案有以下字段,分别是使用者ID、性别、年齡、職業和郵編( UserID::Gender::Age::Occupation::Zip-code )
處理思路:
- 将使用者性别 M、F 進行 label encoding 編碼
- 将年齡 label encoding 編碼
- 郵編取前3位
代碼:
# 處理使用者
users = pd.read_table('../../dataset/ml-1m/users.dat', sep='::', header=None, engine='python', encoding='utf-8').to_numpy()
# 處理使用者年齡和郵編
le = LabelEncoder()
users[:, 1] = le.fit_transform(users[:, 1]) # 将性别 label Encoding
for user in users: # 将年齡 Lable Encoding
if user[2] == 1:
user[2] = 0
elif user[2] == 18:
user[2] = 1
elif user[2] == 25:
user[2] = 2
elif user[2] == 35:
user[2] = 3
elif user[2] == 45:
user[2] = 4
elif user[2] == 50:
user[2] = 5
elif user[2] == 56:
user[2] = 6
user[4] = int(user[4][0:3]) - 1 # 取郵編的前3位
user[0] -= 1 // 從 0 開始
users 處理結果:

2. 處理 movies 資料
movies 資料描述:
電影檔案包含三個字段,分别是電影ID、電影名、電影類型( MovieID::Title::Genres )
處理思路:
将電影名稱删除,電影類型在合并users、movies和ratings之後做 one-hot 處理。
代碼:
# 處理電影
movies = pd.read_table('../../dataset/ml-1m/movies.dat', sep='::', header=None, engine='python', encoding='ISO-8859-1').to_numpy()
movies = np.delete(movies, 1, axis=1) # 删除電影名稱列
movies[:, 0] -= 1
movies 處理結果:
3. 處理 ratings 資料
ratings 資料描述:
電影評分檔案包含使用者ID、電影ID、評分和時間戳( UserID::MovieID::Rating::Timestamp )
處理思路:
- 将時間戳字段删除
- 将評分大于3的作為正樣本(記為1),評分小于等于3的作為負樣本(記為0)
代碼:
# 處理使用者評分
ratings = pd.read_table('../../dataset/ml-1m/ratings.dat', sep='::', header=None, engine='python', encoding='utf-8').to_numpy()[:, :3]
ratings[:, 0:2] -= 1
for i in range(len(ratings)):
ratings[i][2] = 1 if ratings[i][2] > 3 else 0
4. 将 users、movies 和 ratings 資料合并
代碼:
unames = ['userId', 'gender', 'age', 'occupation', 'zipCode']
mnames = ['movieId', 'genres']
rnames = ['userId', 'movieId', 'rating']
users = pd.DataFrame(users, columns=unames)
movies = pd.DataFrame(movies, columns=mnames)
ratings = pd.DataFrame(ratings, columns=rnames)
data = pd.merge(movies, ratings, on=['movieId'])
data = pd.merge(users, data, on=['userId'])
資料合并結果:
5. one-hot 處理
處理思路:
- 将電影類型單獨手動 one-hot 處理
- 然後将 data 中的電影類型删除,再做 one-hot 處理
代碼:
data = data.values // dataframe 轉 numpy
y = data[:, 7]
x = np.delete(data, -1, axis=1) # 将評分列删除
typelist = x[:, -1]
x = np.delete(x, -1, axis=1) # 将電影類型列删除
# 将電影類型 one-hot 編碼
genres = [] # 電影類型 ont-hot 編碼
genresDict = {'Action' : 0, 'Adventure' : 1, 'Animation' : 2, "Children's" : 3, 'Comedy' : 4, 'Crime' : 5, 'Documentary' : 6,
'Drama' : 7, 'Fantasy' : 8, 'Film-Noir' : 9, 'Horror' : 10, 'Musical' : 11, 'Mystery' : 12, 'Romance' : 13,
'Sci-Fi' : 14, 'Thriller' : 15, 'War' : 16, 'Western' : 17
}
for types in typelist:
strs = types.split('|')
tmp = np.zeros(18)
for str in strs:
tmp[genresDict[str]] = 1
genres.append(tmp)
genres = np.array(genres)
# 将 userId, gender, age, occupation, zipCode, movieId one-hot 編碼
encoder = OneHotEncoder(handle_unknown='ignore')
x = encoder.fit_transform(x).toarray()
x = np.concatenate((x, genres),axis=1)
x one-hot 結果:
y one-hot 結果:
6. 完整代碼
import numpy as np
import pandas as pd
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
# 處理使用者
users = pd.read_table('../../dataset/ml-1m/users.dat', sep='::', header=None, engine='python', encoding='utf-8').to_numpy()
# 處理使用者年齡和郵編
le = LabelEncoder()
users[:, 1] = le.fit_transform(users[:, 1]) # 将性别 label Encoding
for user in users: # 将年齡 Lable Encoding
if user[2] == 1:
user[2] = 0
elif user[2] == 18:
user[2] = 1
elif user[2] == 25:
user[2] = 2
elif user[2] == 35:
user[2] = 3
elif user[2] == 45:
user[2] = 4
elif user[2] == 50:
user[2] = 5
elif user[2] == 56:
user[2] = 6
user[4] = int(user[4][0:3]) - 1 # 取郵編的前3位
user[0] -= 1
# 處理電影
movies = pd.read_table('../../dataset/ml-1m/movies.dat', sep='::', header=None, engine='python', encoding='ISO-8859-1').to_numpy()
movies = np.delete(movies, 1, axis=1) # 删除電影名稱列
movies[:, 0] -= 1
# 處理使用者評分
ratings = pd.read_table('../../dataset/ml-1m/ratings.dat', sep='::', header=None, engine='python', encoding='utf-8').to_numpy()[:, :3]
ratings[:, 0:2] -= 1
for i in range(len(ratings)):
ratings[i][2] = 1 if ratings[i][2] > 3 else 0
unames = ['userId', 'gender', 'age', 'occupation', 'zipCode']
mnames = ['movieId', 'genres']
rnames = ['userId', 'movieId', 'rating']
users = pd.DataFrame(users, columns=unames)
movies = pd.DataFrame(movies, columns=mnames)
ratings = pd.DataFrame(ratings, columns=rnames)
data = pd.merge(movies, ratings, on=['movieId'])
data = pd.merge(users, data, on=['userId'])
data = data.values
y = data[:, 7]
x = np.delete(data, -1, axis=1) # 将評分列删除
typelist = x[:, -1]
x = np.delete(x, -1, axis=1) # 将電影類型列删除
# 将電影類型 one-hot 編碼
genres = [] # 電影類型 one-hot 編碼
genresDict = {'Action' : 0, 'Adventure' : 1, 'Animation' : 2, "Children's" : 3, 'Comedy' : 4, 'Crime' : 5, 'Documentary' : 6,
'Drama' : 7, 'Fantasy' : 8, 'Film-Noir' : 9, 'Horror' : 10, 'Musical' : 11, 'Mystery' : 12, 'Romance' : 13,
'Sci-Fi' : 14, 'Thriller' : 15, 'War' : 16, 'Western' : 17
}
for types in typelist:
strs = types.split('|')
tmp = np.zeros(18)
for str in strs:
tmp[genresDict[str]] = 1
genres.append(tmp)
genres = np.array(genres)
# 将 userId, gender, age, occupation, zipCode, movieId one-hot 編碼
encoder = OneHotEncoder(handle_unknown='ignore')
x = encoder.fit_transform(x).toarray()
x = np.concatenate((x, genres),axis=1)