数据预处理 demo
对load的数据进行数据预处理,比如去除电影名中的年份、将用户性别用0-1表示、用户年龄段用0~6来表示等等
数据预处理
- UserID、Occupation和MovieID不用变。
- Gender字段:需要将‘F’和‘M’转换成0和1。
- Age字段:要转成7个连续数字0~6。
- Genres字段:是分类字段,要转成数字。首先将Genres中的类别转成字符串到数字的字典,然后再将每个电影的Genres字段转成数字列表,因为有些电影是多个Genres的组合。
- Title字段:处理方式跟Genres字段一样,首先创建文本到数字的字典,然后将Title中的描述转成数字的列表。另外Title中的年份也需要去掉。
- Genres和Title字段需要将长度统一,这样在神经网络中方便处理。空白部分用‘< PAD >’对应的数字填充。
构建数据处理的对象,默认初始化,三个数据集的路径,方便调用访问:
class MovieRecommend():
def __init__(self):
self.UserDataPath = './ml-1m/users.dat'
self.MoviesDataPath = './ml-1m/movies.dat'
self.RatingsDataPath = './,1-1m/ratings.dat'
对用户数据进行预处理
如上
- Gender字段:需要将‘F’和‘M’转换成0和1。
- Age字段:要转成7个连续数字0~6。
def load_user_data(self):
'''
load & preprocessing dataset from file
'''
users_title = ['UserID', 'Gender', 'Age', 'JobID', 'Zip-code']
users = pd.read_csv(self.UserDataPath, sep='::', header=None, names=users_title, engine='python')
# change the 'gender' expression from dataset
gender_map = {'F':0, 'M':1}
users['Gender'] = users['Gender'].map(gender_map)
# change the 'Age' expression, {1: 0, 18: 1, 25: 2, 35: 3, 45: 4, 50: 5, 56: 6}
age_map = {val:ii for ii,val in enumerate(sorted(set(list(users['Age']))))}
users['Age'] = users['Age'].map(age_map)
return users
处理前的数据:
(env) PS F:\movie_recommender> & f:/movie_recommender/env/Scripts/python.exe f:/movie_recommender/test.py
UserID Gender Age JobID Zip-code
0 1 F 1 10 48067
1 2 M 56 16 70072
2 3 M 25 15 55117
3 4 M 45 7 02460
4 5 M 25 20 55455
... ... ... ... ... ...
6035 6036 F 25 15 32603
6036 6037 F 45 1 76006
6037 6038 F 56 1 14706
6038 6039 F 45 0 01060
6039 6040 M 25 6 11106
[6040 rows x 5 columns]
处理后的数据:
(env) PS F:\movie_recommender> & f:/movie_recommender/env/Scripts/python.exe f:/movie_recommender/test.py
UserID Gender Age JobID Zip-code
0 1 0 0 10 48067
1 2 1 6 16 70072
2 3 1 2 15 55117
3 4 1 4 7 02460
4 5 1 2 20 55455
... ... ... ... ... ...
6035 6036 0 2 15 32603
6036 6037 0 4 1 76006
6037 6038 0 6 1 14706
6038 6039 0 4 0 01060
6039 6040 1 2 6 11106
[6040 rows x 5 columns]
对电影数据进行预处理
- Title字段:处理方式跟Genres字段一样,首先创建文本到数字的字典,然后将Title中的描述转成数字的列表。另外Title中的年份也需要去掉。
- Genres字段:是分类字段,要转成数字。首先将Genres中的类别转成字符串到数字的字典,然后再将每个电影的Genres字段转成数字列表,因为有些电影是多个Genres的组合。
- Genres和Title字段需要将长度统一,这样在神经网络中方便处理。空白部分用‘< PAD >’对应的数字填充。
去除title中的年份:
# Remove the 'year' from Title
pattern = re.compile(r'^(.*)\((\d+)\)$')
title_map = {val:pattern.match(val).group(1) for ii,val in enumerate(set(movies['Title']))}
movies['Title'] = movies['Title'].map(title_map)
将电影种类转化为数字字典:
genres_set = set()
for val in movies['Genres'].str.split('|'):# movies genres are separated via '|'
genres_set.update(val)# store all genres
genres_set.add('<PAD>')
genres2int = {val:ii for ii,val in enumerate(genres_set)}
所有种类:
{'Horror', 'Action', 'Mystery', 'Film-Noir', 'Western', 'Drama', 'Crime', 'Fantasy', 'Musical', "Children's", 'Documentary', '<PAD>', 'Romance', 'Sci-Fi', 'Animation', 'Comedy', 'Adventure', 'Thriller', 'War'}
转化为数字字典genres2int
:
{'Adventure': 0, 'Documentary': 1, 'Film-Noir': 2, "Children's": 3, 'War': 4, 'Sci-Fi': 5, 'Romance': 6, 'Comedy': 7, '<PAD>': 8, 'Thriller': 9, 'Horror': 10, 'Western': 11, 'Drama': 12, 'Action': 13, 'Crime': 14, 'Animation': 15, 'Fantasy': 16, 'Mystery': 17, 'Musical': 18}
将电影种类转化为一个固定长度18的lis,不够的用<PAD>
来补上,部分数据,由于我们生成的数字字典是动态的,再每一次运行的0~17都不一样,比如这一次运行<PAD>
表示为8,但是下一次可能是10,查看movies数据集更改后的结果:
MovieID Title Genres
0 1 Toy Story [11, 17, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ...
1 2 Jumanji [14, 17, 10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ...
2 3 Grumpier Old Men [16, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
3 4 Waiting to Exhale [16, 18, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6...
4 5 Father of the Bride Part II [16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
... ... ... ...
3878 3948 Meet the Parents [16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
3879 3949 Requiem for a Dream [18, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
3880 3950 Tigerland [18, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
3881 3951 Two Family House [18, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
3882 3952 Contender, The [18, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6...
对于title的处理,因为电影名是几个单词几个单词组成的,我们先用简单的处理方式处理一下:
将所有标题中出现的单词,组成过一个set:
, 'Jerry', 'Prince', 'Joe,', 'Richie', 'Mutters', 'Darkness,', 'Vanities', 'Bell,', 'Traffic', 'Jakob', 'Pride', 'Short', 'Romy', 'Got', 'Supper,', 'Wicked', 'Tender', 'del', 'European', 'Deuce', 'Criminels)', 'Crockett,', 'Monte', 'Tigerland', 'belle,', 'Fool', '蒫ole', 'Mall', 'Ozona', 'Purple,', 'Dudley', 'Gigolo', 'Duck', 'Troopers', 'Sleepwalkers', 'Wolves', 'Nuts', '(Zerkalo)', 'Dollhouse', 'Inheritors,', 'Tetsuo', 'Plutonium', 'Good,', 'Cujo',
'(Rekopis', 'Railroad', "It's", 'FairyTale:', 'Paulie', 'Couple,', 'Mighty', 'Just', 'Brothers,', 'Logo', 'Associate,', 'Babyfever', 'Cruise', "Can't",
'Cats', 'Sensibility', 'Half', 'Transit', 'Lives', 'Conformista)', 'Plan', 'Faith', 'Saboteur', 'Bowl,', 'pianista', 'May', 'Turkish', 'Hush', 'Thunderball', 'Alaska', 'Farm', 'Hedd', 'ni', "Fishin'", 'Witness', 'Ruby', 'Scent', '(Se7en)', 'Sunday', 'Passi', 'Swing', 'Assignment,', 'Bits', 'Time', 'Phantoms', 'Verdict,', 'Chapter,', "I'll", 'peor', 'Bloody', 'Mercury', 'Endurance', 'Face', 'Stonewall', 'Stock', 'John', 'Les', 'Place', 'Turtle', 'Prisoner,', 'Ice', 'Love!', 'Choice', 'Fletch', 'Romancing', 'Happy,', 'Gloria', 'Notorious', 'Me,', '鰃a)', 'Lifeboat', 'Peak', 'Ruling', 'Crush,', 'Portrait', 'Extremities', 'SS', 'Rage', 'Sorority', 'Tron', '(Karakter)', 'Ed', 'Africa,', 'Roberts', '(Jing', 'Mifune', 'Jimmy,', 'Consequences,', 'Gambler,'
和转化文章分类的方法一样,我们生成一个15长度的list ,不够的用<PAD>
来补上,部分数据,同样:由于我们生成的数字字典是动态的,再每一次运行的0~17都不一样,比如这一次运行<PAD>
表示为8。
代码:
# convert movies_title to a list of fixed-length, 15 in length
title_count = 15
title_map = {val:[title2int[row] for row in val.split()] for ii,val in enumerate(set(movies['Title']))}
for key in title_map:
for cnt in range(title_count - len(title_map[key])):
title_map[key].insert(len(title_map[key]) + cnt,title2int['<PAD>'])
movies['Title'] = movies['Title'].map(title_map)
return movies
运行效果:
(env) PS F:\movie_recommender> & f:/movie_recommender/env/Scripts/python.exe f:/movie_recommender/test.py
MovieID Title Genres
0 1 [4581, 1639, 1792, 1792, 1792, 1792, 1792, 179... [17, 18, 5, 13, 13, 13, 13, 13, 13, 13, 13, 13...
1 2 [3920, 1792, 1792, 1792, 1792, 1792, 1792, 179... [16, 18, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13...
2 3 [3661, 537, 1011, 1792, 1792, 1792, 1792, 1792... [5, 11, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
3 4 [4026, 2962, 5003, 1792, 1792, 1792, 1792, 179... [5, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,...
4 5 [3996, 2973, 4394, 4317, 3618, 2947, 1792, 179... [5, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
... ... ... ...
3878 3948 [1800, 4394, 5012, 1792, 1792, 1792, 1792, 179... [5, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
3879 3949 [298, 4143, 3656, 5191, 1792, 1792, 1792, 1792... [1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
3880 3950 [3178, 1792, 1792, 1792, 1792, 1792, 1792, 179... [1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
3881 3951 [1513, 2135, 2105, 1792, 1792, 1792, 1792, 179... [1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13...
3882 3952 [3063, 2235, 1792, 1792, 1792, 1792, 1792, 179... [1, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,...
[3883 rows x 3 columns]
本作品采用《CC 协议》,转载必须注明作者和本文链接
文章!!首发于我的博客Stray_Camel(^U^)ノ~YO。
推荐文章: