音乐推荐系统
2019-07-17 本文已影响0人
潇萧之炎
# coding: utf-8
# In[1]:
import numpy as np
import json
import random
import time
import pickle
def random_sample_playlist(in_file, out_file, max_sample=10, seed=None):
"""
从给定的输入文件in_file中提取出最多max_sample条样本数据,并将其输入到out_file文件中
:param in_file:
:param out_file:
:param max_sample:
:param seed:
:return:
"""
# 设置给定的随机数种子
if seed:
random.seed(seed)
# 进行数据的随机抽取过程
with open(out_file, 'w', encoding='utf-8') as writer:
with open(in_file, 'r', encoding='utf-8') as reader:
count = 0
for line in reader:
if random.random() < 0.8:
writer.writelines(line)
count += 1
if count % 100 == 0:
print("已经抽取%d个歌单数据!!" % count)
if count >= max_sample:
break
print("实际抽取的总歌单数据为:%d条" % count)
def parse_playlist_2_song(playlist_json):
"""
将传入的json格式的歌单数据转换为具体的特征数据
:param playlist_json:
:return:
"""
try:
# 将字符串转换为json对象
data = json.loads(playlist_json)
print('data',data)
# 开始获取数据
result_data = data['result']
# 1. 获取歌单数据(用户id,歌单id,歌单名称,最近的更新时间,订阅数,播放数)
user_id = result_data['userId']
playlist_id = result_data['id']
playlist_name = result_data['name'].replace('\t', '')
playlist_subscribed_count = result_data['subscribedCount']
playlist_play_count = result_data['playCount']
playlist_update_time = result_data['updateTime']
# 2. 获取歌曲信息
song_info = ''
songs = result_data['tracks']
for song in songs:
# 歌曲id,歌曲名称,歌曲热度
song_id = song['id']
song_name = song['name'].replace('\t', '')
song_popularity = song['popularity']
song_info += '\t' + '::::'.join([str(song_id), song_name, str(song_popularity)])
return '##'.join(
[str(user_id), str(playlist_id), playlist_name, str(playlist_update_time), str(playlist_subscribed_count),
str(playlist_play_count)]) + song_info
except Exception as e:
return False
def parse_playlist_file(in_file, out_file):
"""
从给定的歌单原始数据文件中提取有关的特征数据,并将其保存到给定的输出文件中
:param in_file:
:param out_file:
:return:
"""
with open(out_file, 'w', encoding='utf-8') as writer:
with open(in_file, 'r', encoding='utf-8') as reader:
for line in reader:
# 1. 对当前的歌单数据line进行处理
result = parse_playlist_2_song(line)
# 2. 对于处理的结果进行判断,如果处理成功并且有值,那么直接输出
if result:
writer.writelines(result)
writer.writelines('\n')
else:
print("提取歌单主要特征数据失败:{}".format(line))
def is_last_time(update_time):
return int(time.time()) * 1000 - update_time < 31536000000
def parse_user_song_rating(user_id, update_time, subscribed_count, play_count, song_info):
"""
基于输入的参数,构建一个评分
:param user_id:
:param update_time:
:param subscribed_count:
:param play_count:
:param song_info:
:return:
"""
try:
# 提取特征
song_id, _, song_popularity = song_info.split('::::')
# 计算当前用户对于单个歌曲的评分
# TODO: 由于我们的数据原因,没法直接获取用用户对于歌曲的评分信息,那么将歌曲的热度作为评分值,并且结合播放次数、订阅次数、更新时间等做一个加权变化;并且我们只要这个歌单中存在这个歌曲,那么表示这个人对于这个歌曲是比较偏好的,所以评分一定是正向的,假设评分的取值范围[1~10], 那么认为原始数据中的评分一定是超过5分的
w = 1.0
if play_count > 10000 and subscribed_count > 1000 and is_last_time(update_time):
w = 1.1
elif play_count <= 10000 and subscribed_count <= 1000 and (not is_last_time(update_time)):
w = 0.9
rating = float(song_popularity) * w
# 首先将评分截断为[1,10], 如果评分超过10分,那么设置为10;如果低于1分,那么设置为1
rating = np.clip(rating / 10, 1.0, 10.0)
# 认为数据实在存在,那么一定是喜好的,所以评分一定是超过5分的
rating = ((rating - 1.0) / 9.0) * 5.0 + 5.0
return ','.join([user_id, song_id, str(rating)])
except:
return ''
def parse_user_song_rating_file(in_file, out_file):
"""
对输入的特征属性的文件内容进行用户-歌曲评分的构建,并将结果保存到out_file
:param in_file:
:param out_file:
:return:
"""
with open(out_file, 'w', encoding='utf-8') as writer:
with open(in_file, 'r', encoding='utf-8') as reader:
for line in reader:
# 获取歌单信息和歌单中的歌曲数据
contents = line.split('\t')
playlist_content, song_contents = contents[0], contents[1:]
# 获取具体的歌单数据
user_id, _, _, update_time, subscribed_count, play_count = playlist_content.split("##")
update_time = float(update_time)
subscribed_count = float(subscribed_count)
play_count = float(play_count)
# 获取当前用户user_id对于所有songs的分别的评分信息(user-song-rating)
user_song_info = map(
lambda song: parse_user_song_rating(user_id, update_time, subscribed_count, play_count, song),
song_contents)
user_song_info = filter(lambda t: len(t.split(',')) == 3, user_song_info)
# 输出数据
result = '\n'.join(user_song_info)
if result:
writer.writelines(result)
writer.writelines('\n')
def parse_playlist_song_rating(playlist_id, song_info):
"""
基于给定的数据,得到歌单-歌曲的评分值
:param playlist_id:
:param song_info:
:return:
"""
try:
# 提取歌曲信息
song_id, _, _ = song_info.split('::::')
# 在这里计算的评分矩阵主要是为了实现需求:计算歌单之间的相似度,然后将相似歌单作为当前歌单的推荐数据
# 可以认为如果两个歌单中,出现的歌曲的重复度越高,那么这两个歌单就越相似度;也就是说只要这两个歌单中的歌曲列表是一致的,那么就可以认为是歌单的相似的---->基于jaccard相似度计算 ---> 不需要考虑具体的评分值
rating = 1.0
return ','.join([playlist_id, song_id, str(rating)])
except:
return ''
def parse_playlist_song_rating_file(in_file, out_file):
"""
构建歌单-歌曲之间的评分矩阵
:param in_file:
:param out_file:
:return:
"""
with open(out_file, 'w', encoding='utf-8') as writer:
with open(in_file, 'r', encoding='utf-8') as reader:
for line in reader:
# 获取歌单信息和歌单中的歌曲数据
contents = line.split('\t')
playlist_content, song_contents = contents[0], contents[1:]
# 获取具体的歌单数据
_, playlist_id, _, _, _, _ = playlist_content.split("##")
# 获取当前歌单playlist_id对于所有songs的分别的评分信息(playlist-song-rating)
playlist_song_info = map(lambda song: parse_playlist_song_rating(playlist_id, song), song_contents)
playlist_song_info = filter(lambda t: len(t.split(',')) == 3, playlist_song_info)
# 输出数据
result = '\n'.join(playlist_song_info)
if result:
writer.writelines(result)
writer.writelines('\n')
def parse_playlist_song_id_2_name(in_file, out_playlist, out_song):
"""
提取id和name映射关系到文件中
:param in_file:
:param out_playlist:
:param out_song:
:return:
"""
# 歌单id和歌单名称的映射字典
playlist_id_2_name = {}
# 歌曲id和歌曲名称的映射字典
song_id_2_name = {}
# 从输入数据中进行处理
with open(in_file, 'r', encoding='utf-8') as reader:
for line in reader:
try:
# 划分数据
contents = line.split("\t")
try:
# 提取歌单id和歌单名称
_, playlist_id, playlist_name, _, _, _ = contents[0].split('##')
playlist_id_2_name[playlist_id] = playlist_name
# 提取歌曲id和歌曲名称
for song in contents[1:]:
try:
song_id, song_name, _ = song.split("::::")
song_id_2_name[song_id] = song_name
except:
print("Fetch the song id throw error:{}".format(song))
except:
print("Fetch the playlist id throw error:{}".format(contents[0]))
except:
print("Fetch error!")
# 输出数据
with open(out_playlist, 'wb') as playlist_writer:
pickle.dump(playlist_id_2_name, playlist_writer)
with open(out_song, 'wb') as song_writer:
pickle.dump(song_id_2_name, song_writer)
if __name__ == '__main__':
# all_music_playlist_file_path = 'D:/music/playlist_detail_music_all.json'
all_music_playlist_file_path = 'C:/我的电脑/文件下载/第五期推荐系统循环课/[20190118]_推荐系统:推荐系统概述/playlist_detail_music_all/playlist_detail_music_all.json'
# sample_playlist_file_pth = 'D:/music/playlist_detail_music_500.json'
sample_playlist_file_pth = 'C:/我的电脑/Python/推荐系统/数据/playlist_detail_music_500.json'
music_playlist_song_file_path = 'C:/我的电脑/Python/推荐系统/数据/163_music_playlist_song.txt'
music_user_song_rating_file_path = 'C:/我的电脑/Python/推荐系统/数据/163_music_user_song_rating.txt'
music_playlist_song_rating_file_path = 'C:/我的电脑/Python/推荐系统/数据/163_music_playlist_song_rating.txt'
playlist_id_2_name_file_path = 'C:/我的电脑/Python/推荐系统/数据/163_playlist_id_2_name.pkl'
song_id_2_name_file_path = 'C:/我的电脑/Python/推荐系统/数据/163_song_id_2_name.pkl'
# 1. 样本数据的抽取
random_sample_playlist(all_music_playlist_file_path, sample_playlist_file_pth, 500)
# 2. 特征属性的提取
parse_playlist_file(sample_playlist_file_pth, music_playlist_song_file_path)
# 3. 构建用户-歌曲评分矩阵
parse_user_song_rating_file(music_playlist_song_file_path, music_user_song_rating_file_path)
# 4. 构建歌单-歌曲评分矩阵
parse_playlist_song_rating_file(music_playlist_song_file_path, music_playlist_song_rating_file_path)
# 5. 提取id和name的映射
parse_playlist_song_id_2_name(music_playlist_song_file_path, playlist_id_2_name_file_path, song_id_2_name_file_path)
# -- encoding:utf-8 --
"""
模拟离线的模型训练过程
需求一:每天为每个用户产生20首歌曲的一个推荐列表,要求这二十首歌中不能出现该用户实际偏好的歌曲
需求二:当用户浏览某个歌单页面,给该用户推荐和当前歌单比较类似的5个其它歌单
TODO: 作业 --> 将保存磁盘的代码更改为保存数据库的代码,并且对推荐结果的应用在去稍微的理解理解。
Create by ibf on 19/1/23
"""
import pickle
import pymysql
import surprise
from surprise import KNNBaseline, SVD
from surprise import Dataset, Reader
def train_model1(in_file, out_file):
"""
针对需求一,使用给定的MovieLens格式的输入数据,进行模型构建,并将模型保存到对应的磁盘文件中
:param in_file:
:param out_file:
:return:
"""
# 1. 数据加载
reader = Reader(line_format='user item rating', sep=',', rating_scale=(1, 10))
data = Dataset.load_from_file(file_path=in_file, reader=reader)
# 2. 数据转换
trainset = data.build_full_trainset()
# 3. 模型构建
algo = SVD(n_factors=100, n_epochs=200, reg_all=0.2, lr_all=0.1)
# 4. 模型训练
algo.fit(trainset)
# 5. 模型持久化
surprise.dump.dump(out_file, algo=algo)
def fetch_recommend_list_by_model1_2_file(model_in_file, out_file, song_id_2_name, K=20):
"""
基于给定的模型,进行推荐列表的获取,并将推荐列表保存到磁盘中
:param model_in_file: 模型文件
:param out_file: 输出文件路径
:param song_id_2_name: 给定的一个词典,中间是歌曲id和歌曲名称的一个映射
:param K: 给定具体获取多少个推荐歌曲
:return:
"""
# 1. 加载模型
_, algo = surprise.dump.load(model_in_file)
# 2. 获取所有用户以及所有物品,并且对所有用户产生一个推荐列表,并将最终的推荐结果保存磁盘
result = {}
# a. 获取用户的总数目
total_users = algo.trainset.n_users
# b. 获取物品的总数目
total_items = algo.trainset.n_items
print("总用户数目:{}, 总物品数目:{}".format(total_users, total_items))
# c. 遍历所有用户以及所有物品产生推荐列表
for inner_user_id in range(total_users):
print("开始处理用户:{}".format(inner_user_id))
# -0. 初始化相关参数
top_k_list = []
count = 0
# 获取当前用户评分过的商品id所组成的列表
user_2_song_id_list = list(map(lambda t: t[0], algo.trainset.ur[inner_user_id]))
# -1. 将内部用户id转换为实际用户id
raw_user_id = algo.trainset.to_raw_uid(inner_user_id)
# -2. 获取当前用户对于所有物品的评分,然后获取评分最高的K个商品以及商品评分保存到列表中
for inner_item_id in range(total_items):
# 只有当当前物品不在用户的评分物品列表中的时候,我才计算预测评分信息。
if inner_item_id not in user_2_song_id_list:
# -a. 将内部的物品id转换为实际的物品id
raw_item_id = algo.trainset.to_raw_iid(inner_item_id)
# -b. 计算当前用户对于当前物品的评分
rating = algo.predict(raw_user_id, raw_item_id).est
# -c. 将当前用户对于当前物品的评分添加到临时列表中
# NOTE: top_k_list中最多保存rating最高的K个商品(如果列表中商品数目小于K个,那么当前商品直接添加;如果列表中商品数目多余K个,那么就根据大小进行操作)
if count < K:
top_k_list.append((raw_item_id, rating))
count += 1
else:
# --1. 对top_k_list做一个排序(按照rating评分排序)
top_k_list.sort(key=lambda t: t[1])
# --2. 获取top_k_list中评分最小的评分值(因为做了一个升序排列,最小的在第一个位置)
min_rating = top_k_list[0][1]
# --3. 如果当前的评分大于最小评分,那么最小评分所对应的商品从列表中删除,然后添加当前商品信息
if rating > min_rating:
top_k_list[0] = (raw_item_id, rating)
# -3. 将获取得到的推荐列表保存到字典中
top_k_list.sort(key=lambda t: t[1], reverse=True)
top_k_list = list(map(lambda t: (t[0], song_id_2_name[t[0]], t[1]), top_k_list))
result[raw_user_id] = top_k_list
# d. 将推荐结果保存到磁盘文件中
with open(out_file, 'wb') as writer:
pickle.dump(result, writer)
def fetch_recommend_list_by_model1_2_mysql(model_in_file, K=20):
"""
基于给定的模型,进行推荐列表的获取,并将推荐列表保存到磁盘中
:param model_in_file: 模型文件
:param K: 给定具体获取多少个推荐歌曲
:return:
"""
# 1. 加载模型
_, algo = surprise.dump.load(model_in_file)
# 数据持久化输出到数据库中
delete_sql = "delete from tb_user_recommend_song"
sql = "INSERT INTO tb_user_recommend_song(`user_id`, `song_id`, `rating`) values(%d, %d, %.4f)"
try:
with pymysql.connect(host='localhost', user='root', password='root',
port=3306, database='test', charset='utf8') as cursor:
# 清空数据库中的所有数据
cursor.execute(delete_sql)
# 2. 获取所有用户以及所有物品,并且对所有用户产生一个推荐列表,并将最终的推荐结果保存磁盘
# a. 获取用户的总数目
total_users = algo.trainset.n_users
# b. 获取物品的总数目
total_items = algo.trainset.n_items
print("总用户数目:{}, 总物品数目:{}".format(total_users, total_items))
# c. 遍历所有用户以及所有物品产生推荐列表
for inner_user_id in range(total_users):
print("开始处理用户:{}".format(inner_user_id))
# -0. 初始化相关参数
top_k_list = []
count = 0
# 获取当前用户评分过的商品id所组成的列表
user_2_song_id_list = list(map(lambda t: t[0], algo.trainset.ur[inner_user_id]))
# -1. 将内部用户id转换为实际用户id
raw_user_id = algo.trainset.to_raw_uid(inner_user_id)
# -2. 获取当前用户对于所有物品的评分,然后获取评分最高的K个商品以及商品评分保存到列表中
for inner_item_id in range(total_items):
# 只有当当前物品不在用户的评分物品列表中的时候,我才计算预测评分信息。
if inner_item_id not in user_2_song_id_list:
# -a. 将内部的物品id转换为实际的物品id
raw_item_id = algo.trainset.to_raw_iid(inner_item_id)
# -b. 计算当前用户对于当前物品的评分
rating = algo.predict(raw_user_id, raw_item_id).est
# -c. 将当前用户对于当前物品的评分添加到临时列表中
# NOTE: top_k_list中最多保存rating最高的K个商品(如果列表中商品数目小于K个,那么当前商品直接添加;如果列表中商品数目多余K个,那么就根据大小进行操作)
if count < K:
top_k_list.append((raw_item_id, rating))
count += 1
else:
# --1. 对top_k_list做一个排序(按照rating评分排序)
top_k_list.sort(key=lambda t: t[1])
# --2. 获取top_k_list中评分最小的评分值(因为做了一个升序排列,最小的在第一个位置)
min_rating = top_k_list[0][1]
# --3. 如果当前的评分大于最小评分,那么最小评分所对应的商品从列表中删除,然后添加当前商品信息
if rating > min_rating:
top_k_list[0] = (raw_item_id, rating)
# -3. 将获取得到的推荐列表保存到数据库中
int_user_id = int(raw_user_id)
for song_id, rating in top_k_list:
cursor.execute(sql % (int_user_id, int(song_id), rating))
except Exception as e:
print("ERROR!!!{}".format(e))
cursor.connection.rollback()
def train_model2(in_file, out_file):
"""
针对需求二,使用给定的MovieLens格式的输入数据,进行模型构建,并将模型保存到对应的磁盘文件中
:param in_file:
:param out_file:
:return:
"""
# 1. 数据加载
reader = Reader(line_format='user item rating', sep=',', rating_scale=(1, 1))
data = Dataset.load_from_file(file_path=in_file, reader=reader)
# 2. 数据转换
trainset = data.build_full_trainset()
# 3. 模型构建
sim_options = {
'name': 'jaccard', # 因为评分数据只有1分这个值,我们认为只要歌单(用户)具有相同的歌曲(物品),那么就认为歌单(用户)相似度 --> 所以不需要考虑具体的分值
'user_based': True
}
algo = KNNBaseline(k=10, sim_options=sim_options)
# 4. 模型训练
algo.fit(trainset)
# 5. 模型持久化
surprise.dump.dump(out_file, algo=algo)
def fetch_recommend_list_by_model2_2_file(model_in_file, out_file, playlist_id_2_name, K=5):
"""
基于给定的模型,进行推荐列表的获取,并将推荐列表保存到磁盘中
:param model_in_file: 模型文件
:param out_file: 输出文件路径
:param playlist_id_2_name: 给定的一个词典,中间是歌单id和歌单名称的一个映射
:param K: 给定具体获取多少个推荐歌单
:return:
"""
# 1. 加载模型
_, algo = surprise.dump.load(model_in_file)
# 2. 获取所有用户,并且对所有用户产生一个推荐列表<基于用户的相似度产生>,并将最终的推荐结果保存磁盘
# NOTE: 用户即歌单
result = {}
# a. 获取用户/歌单的总数目
total_playlist = algo.trainset.n_users
print("总歌单数目:{}".format(total_playlist))
# c. 遍历所有用户/歌单,获取和当前歌单最相似的K个歌单作为推荐结果
for inner_playlist_id1 in range(total_playlist):
print("开始处理歌单:{}".format(inner_playlist_id1))
# -0. 初始化相关参数
top_k_list = []
count = 0
# -1. 将内部歌单id转换为实际歌单id
raw_playlist_id1 = algo.trainset.to_raw_uid(inner_playlist_id1)
# -2. 从相似度矩阵中获取和当前歌单最相似的K个歌单保存到集合中
for inner_playlist_id2 in range(total_playlist):
# 内外两个歌单id不能一样
if inner_playlist_id1 != inner_playlist_id2:
# -a. 将内部歌单id转换为实际歌单id
raw_playlist_id2 = algo.trainset.to_raw_uid(inner_playlist_id2)
# -b. 获取两个歌单的相似度
sim = algo.sim[inner_playlist_id1, inner_playlist_id2]
# -c. 将当前两个歌单的相似度添加到临时列表中
# NOTE: top_k_list中最多保存sim最高的K个歌单(如果列表中歌单数目小于K个,那么当前歌单直接添加;如果列表中歌单数目多余K个,那么就根据大小进行操作)
if count < K:
top_k_list.append((raw_playlist_id2, sim))
count += 1
else:
# --1. 对top_k_list做一个排序(按照sim评分排序)
top_k_list.sort(key=lambda t: t[1])
# --2. 获取top_k_list中sim最小的sim值(因为做了一个升序排列,最小的在第一个位置)
min_sim = top_k_list[0][1]
# --3. 如果当前的sim大于最小sim,那么最小sim所对应的歌单从列表中删除,然后添加当前歌单信息
if sim > min_sim:
top_k_list[0] = (raw_playlist_id2, sim)
# -3. 将获取得到的推荐列表保存到字典中
top_k_list.sort(key=lambda t: t[1], reverse=True)
top_k_list = list(map(lambda t: (t[0], playlist_id_2_name[t[0]], t[1]), top_k_list))
result[raw_playlist_id1] = top_k_list
# d. 将推荐结果保存到磁盘文件中
with open(out_file, 'wb') as writer:
pickle.dump(result, writer)
def fetch_recommend_list_by_model2_2_mysql(model_in_file, K=5):
"""
基于给定的模型,进行推荐列表的获取,并将推荐列表保存到磁盘中
:param model_in_file: 模型文件
:param out_file: 输出文件路径
:param playlist_id_2_name: 给定的一个词典,中间是歌单id和歌单名称的一个映射
:param K: 给定具体获取多少个推荐歌单
:return:
"""
# 1. 加载模型
_, algo = surprise.dump.load(model_in_file)
delete_sql = "delete from tb_playlist_recommend_playlist"
sql = "INSERT INTO tb_playlist_recommend_playlist(`playlist_id`, `playlist_id2`, `sim`) values(%d, %d, %.4f)"
try:
with pymysql.connect(host='localhost', user='root', password='root',
port=3306, database='test', charset='utf8') as cursor:
# 清空数据库中的所有数据
cursor.execute(delete_sql)
# 2. 获取所有用户,并且对所有用户产生一个推荐列表<基于用户的相似度产生>,并将最终的推荐结果保存磁盘
# NOTE: 用户即歌单
# a. 获取用户/歌单的总数目
total_playlist = algo.trainset.n_users
print("总歌单数目:{}".format(total_playlist))
# c. 遍历所有用户/歌单,获取和当前歌单最相似的K个歌单作为推荐结果
for inner_playlist_id1 in range(total_playlist):
print("开始处理歌单:{}".format(inner_playlist_id1))
# -0. 初始化相关参数
top_k_list = []
count = 0
# -1. 将内部歌单id转换为实际歌单id
raw_playlist_id1 = algo.trainset.to_raw_uid(inner_playlist_id1)
# -2. 从相似度矩阵中获取和当前歌单最相似的K个歌单保存到集合中
for inner_playlist_id2 in range(total_playlist):
# 内外两个歌单id不能一样
if inner_playlist_id1 != inner_playlist_id2:
# -a. 将内部歌单id转换为实际歌单id
raw_playlist_id2 = algo.trainset.to_raw_uid(inner_playlist_id2)
# -b. 获取两个歌单的相似度
sim = algo.sim[inner_playlist_id1, inner_playlist_id2]
# -c. 将当前两个歌单的相似度添加到临时列表中
# NOTE: top_k_list中最多保存sim最高的K个歌单(如果列表中歌单数目小于K个,那么当前歌单直接添加;如果列表中歌单数目多余K个,那么就根据大小进行操作)
if count < K:
top_k_list.append((raw_playlist_id2, sim))
count += 1
else:
# --1. 对top_k_list做一个排序(按照sim评分排序)
top_k_list.sort(key=lambda t: t[1])
# --2. 获取top_k_list中sim最小的sim值(因为做了一个升序排列,最小的在第一个位置)
min_sim = top_k_list[0][1]
# --3. 如果当前的sim大于最小sim,那么最小sim所对应的歌单从列表中删除,然后添加当前歌单信息
if sim > min_sim:
top_k_list[0] = (raw_playlist_id2, sim)
# -3. 将获取得到的推荐列表保存到数据库中
int_playlist_id = int(raw_playlist_id1)
for playlist_id, sim in top_k_list:
cursor.execute(sql % (int_playlist_id, int(playlist_id), sim))
except Exception as e:
print("ERROR!!!{}".format(e))
cursor.connection.rollback()
if __name__ == '__main__':
music_user_song_rating_file_path = 'D:/music/163_music_user_song_rating.txt'
music_playlist_song_rating_file_path = 'D:/music/163_music_playlist_song_rating.txt'
playlist_id_2_name_file_path = 'D:/music/163_playlist_id_2_name.pkl'
song_id_2_name_file_path = 'D:/music/163_song_id_2_name.pkl'
model1_file_path = 'D:/music/model/m1.m'
model2_file_path = 'D:/music/model/m2.m'
model1_result_file_path = 'D:/music/model/r1.data'
model2_result_file_path = 'D:/music/model/r2.data'
train_model_flag = 2
if train_model_flag == 0:
print("进行模型训练.....")
print("开始需求一模型训练....")
train_model1(music_user_song_rating_file_path, model1_file_path)
print("开始需求二模型训练....")
train_model2(music_playlist_song_rating_file_path, model2_file_path)
print("模型训练完成!!!")
elif train_model_flag == 1:
print("进行推荐列表的获取操作(保存磁盘)....")
song_id_2_name = pickle.load(open(song_id_2_name_file_path, 'rb'))
playlist_id_2_name = pickle.load(open(playlist_id_2_name_file_path, 'rb'))
print(playlist_id_2_name.keys())
print("映射关系加载完成!!!")
print("开始产生需求一的推荐列表....")
fetch_recommend_list_by_model1_2_file(model1_file_path, model1_result_file_path, song_id_2_name)
print("开始产生需求二的推荐列表....")
fetch_recommend_list_by_model2_2_file(model2_file_path, model2_result_file_path, playlist_id_2_name)
print("推荐数据产生完成!!!!")
elif train_model_flag == 2:
print("进行推荐列表的生成操作(保存数据库)....")
print("开始产生需求一的推荐列表....")
fetch_recommend_list_by_model1_2_mysql(model1_file_path)
print("开始产生需求二的推荐列表....")
fetch_recommend_list_by_model2_2_mysql(model2_file_path)
print("推荐数据产生完成!!!!")