基于聚类的推荐算法笔记——以豆瓣电影为例(二)(附源代码)

第一章 聚类算法介绍
基于聚类的推荐算法笔记一

第二章 数据介绍
基于聚类的推荐算法笔记二

第三章 实现推荐算法
基于聚类的推荐算法笔记三

第四章 评价推荐算法
基于聚类的推荐算法笔记四


前言

本文记载一下本科毕设所研究的课题步骤以及一些细节,由于此次毕设对于推荐领域很感兴趣,发表一些浅显见解,希望大佬们不吝赐教。


以下介绍一下本次实验使用的数据,全部数据源于豆瓣,使用Selenium+Chromedriver爬取,具体数据后续会开源到git上。

仓库

一、豆瓣页面分析

1.1具体实现

需要爬取豆瓣用户的用户名、还有其历史观影记录。查看豆瓣页面,利用selenium+Chromedriver进行爬取。
(具体代码参照基于Selenium+Chromedriver的豆瓣爬虫,直接获取数据可以去仓库

1.2遇到的问题

  1. 自动登录
  2. 选定目标用户
#自动登录实现代码
from selenium import webdriver  
import time 
import sys
import pickle 
import csv
from selenium.webdriver import ActionChains
def login(): 
    #profile=webdriver.FirefoxOptions()
    #profile.add_argument('-headless') #设置无头模式
    chromedriver='./chromedriver'#找到驱动目录
    driver = webdriver.Chrome(chromedriver) #运行驱动
    driver.get("https://www.douban.com")
    #豆瓣页面登录默认手机号验证码,需要切换到账号密码位置
    driver.switch_to.frame(driver.find_elements_by_tag_name('iframe')[0])
    #利用豆瓣页面框架对账号密码登录进行定位
    action = driver.find_element_by_xpath("/html/body/div[1]/div[1]/ul[1]/li[2]")
    ActionChains(driver).move_to_element(action).click(action).perform()  
    #定位账号输入位置
    driver.find_element_by_xpath("//*[@id='username']").send_keys("手机号")
    time.sleep(1)
    #定位密码输入位置
    driver.find_element_by_xpath("//*[@id='password']").send_keys("密码")
    time.sleep(1)
    #定位登录按钮位置
    driver.find_element_by_xpath("/html/body/div[1]/div[2]/div[1]/div[5]/a").click()
    time.sleep(5)
if __name__ == '__main__': 
    login()

二、数据分析

2.1具体实现

    爬取下来的数据属性如下:用户id、用户名、电影序号、电影id、电影名、评分、电影链接、种类1、种类2、种类3、平均评分。
    实验中使用不同类别在用户观影记录中的占比作为描述用户的属性偏好,对原始数据进行预处理,剩余属性:用户id、电影id、电影名、种类1、种类2、种类3。
    在豆瓣中一共有18种电影类型:在这里插入图片描述
统计每位用户观看这18种电影的占比作为用户向量。
在这里插入图片描述

#统计用户类型数量实现代码:
from pandas import DataFrame
import csv
import xlwt
import pandas as pd
import numpy as np

data = pd.read_csv("D:\\experiment\\第三次豆瓣\\测试3\\train\\实验数据_clear.csv")#路径
#print(data)

#二维矩阵存每个用户观看不同类别的数量
namedic={"其他": 0, "剧情": 1,"喜剧": 2,"动作": 3,"爱情": 4,"科幻": 5,"动画": 6,"悬疑": 7,"惊悚": 8,"恐怖": 9,"犯罪": 10,"传记": 11,"历史": 12,"战争": 13,"西部": 14,"奇幻": 15,"冒险": 16,"纪录片": 17,"武侠": 18,"#": 19}
user_movie_list = np.zeros((182,20))
print(user_movie_list)
i=0
j=0
for index, row in data.iterrows():
    #print(index) # 输出每行的索引值
    #print(row[0])
    if row[0] == i+1:
        user_movie_list[i][namedic.get(row[3], 0)] += 1
        user_movie_list[i][namedic.get(row[4], 0)] += 1
        user_movie_list[i][namedic.get(row[5], 0)] += 1
    else:
        i+=1
        if row[0] == i + 1:
            user_movie_list[i][namedic.get(row[3], 0)] += 1
            user_movie_list[i][namedic.get(row[4], 0)] += 1
            user_movie_list[i][namedic.get(row[5], 0)] += 1
print(user_movie_list)
lieming=["其他","剧情","喜剧","动作","爱情","科幻","动画","悬疑","惊悚","恐怖","犯罪","传记","历史","战争","西部","奇幻","冒险" ,"纪录片","武侠","#"]
user_category = pd.DataFrame(columns=lieming,data=user_movie_list)
user_category.to_csv('D:\\experiment\\第三次豆瓣\\测试3\\train\\douban_user_category.csv', index=False,encoding='utf-8')#输出文件

计算占比使用exce工具即可。

2.2遇到的问题

  1. 上述得到的用户向量有18维,不能放到第一篇写到的聚类算法中。

解决:对数据进行降维,实验中降至2维方便画图和理解。
降维使用sklearn库中的PCA函数,传入数据和指定维数即可。

#coding=utf-8
#PCA降维
import numpy as np
from sklearn.decomposition import PCA
import pandas as pd

points = []

data = pd.read_csv("D:\\experiment\\第三次豆瓣\\测试3\\train\\douban_user_category.csv", encoding='gbk')
train_data = np.array(data)
#print(train_data)
all_list=train_data.tolist()#转换list
#print(all_list)

for item in all_list:#在文件中18维向量对应19-36位
    point = [item[19], item[20], item[21], item[22], item[23], item[24], item[25], item[26], item[27], item[28],
             item[29], item[30], item[31], item[32], item[33], item[34], item[35], item[36]]
    points.append(point)

#print(type(points))#每个点存入列表
points = np.array(points)#转化为数组形式
#print(points)

pca = PCA(n_components=2)   #降到2维
pca.fit(points)                  #训练
newPoints=pca.fit_transform(points)   #降维后的数据
# PCA(copy=True, n_components=2, whiten=False)
print("前两维的贡献率分别为:", pca.explained_variance_ratio_)  #输出贡献率
print("-----------------------")
print(newPoints)                  #输出降维后的数据
zuobiao = pd.DataFrame(newPoints)
zuobiao.to_csv('D:\\experiment\\第三次豆瓣\\测试3\\train\\douban_train_zuobiao.csv', index=False,encoding='utf-8')

总结

得到数据需要仔细观察数据间的关系,加加减减乘乘除除又能得到新数据。本次实验仅使用的用户观影记录中的类别属性,对于推荐算法来说属性较少,可能难以达到高精度推荐。

(详细代码以及数据请看仓库CSND资源

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐