MoviesLens.py

MoviesLens.py

此项目用到的数据集是MoviesLens数据集,其中包括用户评分、电影信息等数据。MoviesLens.py是进行数据的预处理文件。下面是对数据预处理流程代码的详解过程。
首先,涉及到的库如下所示

import csv
import re
import pandas as pd
from surprise import Reader
from surprise import Dataset
from collections import defaultdict
import os
import sys

其中我们较为不熟悉的是surprise库,用到的Reader和Dataset类都是为了让数据集适配之后的训练过程,在此就不详细介绍此库。如果想了解这两个类的参数配置,请点击ReaderDataset去做相应的了解。
除此之外,collections中的defaultdict类是用来初始化字典的,如a = defaulydict(int)等。

loadMovieLensDataset函数

这个函数主要用于获取用户评价数据

    def loadMovieLensDataset(self):

        ratingsDataset = 0
        self.movieId_to_movieName = {}  # 将电影ID和电影名称一一对应的字典
        self.movieName_to_movieId = {}  # 将电影名称和电影ID一一对应的字典
        # 读取用户对电影评价的csv和作者自己对电影评价的csv并设置header
        df1 = pd.read_csv(self.rating_file_location, skiprows=1)
        df1.columns = ['user', 'item', 'rating', 'timestamp']
        df2 = pd.read_csv(self.my_rating_file_location, skiprows=1)
        df2.columns = ['user', 'item', 'rating', 'timestamp']
        frame = [df1, df2]
        ratingsData = pd.concat(frame, ignore_index=True)  # 将两个dataframe进行合并
        print(ratingsData.head())
        ratingsData.to_csv("ratings-Data.csv", index=False)

        ratingsData = ratingsData.astype({'user': str, 'item': str, 'rating': str, 'timestamp': str})
        print(ratingsData.tail())  # 打印数据的后五行数据
        # 将数据转化成surprise使用的数据形式
        reader = Reader(line_format='user item rating timestamp')
        ratingsDataset = Dataset.load_from_df(ratingsData[['user', 'item', 'rating']], reader)

        # 打开电影文件, 采用'ISO-8859-1'编码避免编码错误
        # 如果 csvfile 是文件对象,则应使用newline打开它。
        # 获取电影Id和名称的对应的两个字典
        with open(self.movies_file_location, newline='', encoding='ISO-8859-1') as csv_file:
            # 返回reader器对象,该对象将迭代给定csvfile中的行。
            movie_Reader = csv.reader(csv_file)
            next(movie_Reader)  # 跳过文件的第一行(标签)
            for row in movie_Reader:
                movieID = int(row[0])  # 获取电影的ID
                movieName = row[1]  # 获取电影名称
                # 将电影名称和Id进行对应,得到两个字典
                self.movieId_to_movieName[movieID] = movieName
                self.movieName_to_movieId[movieName] = movieID
        # 返回合并完并且修改好的数据表
        return ratingsDataset

getMovieName函数

此函数根据电影Id获取电影名称

    def getMovieName(self, movieID):
        if movieID in self.movieId_to_movieName:
            return self.movieId_to_movieName[movieID]
        else:
            return ""

getPopularityRanks函数

根据用户的评分获取电影受欢迎程度排行榜(被评分次数排行榜)

    def getPopularityRanks(self):
        ratings = defaultdict(int)  # 电影被评次数字典
        rankings = defaultdict(int)  # 电影受欢迎排行榜字典
        with open(self.new_rating_csv, newline='') as cvsfile:
            ratingReader = csv.reader(cvsfile)
            next(ratingReader)
            for row in ratingReader:
                movieID = int(row[1])
                ratings[movieID] += 1  # 电影ID出现一次,被评次数加一
        rank = 1  # 初始排位第一名
        # 根据rating的被评次数给rating字典进行排序(升序)
        for movieID, _ in sorted(ratings.items(), key=lambda x: x[1], reverse=True):
            # 根据排序依次排名
            rankings[movieID] = rank
            rank += 1
        return rankings

getGenres函数

根据电影分类标签获取向量化的标签

    def getGenres(self):
        genres = defaultdict(list)  # 每个电影分类标签列表字典
        genreIDs = {}  # 电影ID和电影分类标签(数字形式)对照字典
        maxGenreID = 0  # 电影分类标签数量
        with open(self.movies_file_location, newline='', encoding='ISO-8859-1') as csvfile:
            movieReader = csv.reader(csvfile)
            next(movieReader)  # Skip header line
            for row in movieReader:
                movieID = int(row[0])
                genreList = row[2].split('|')  # 获取每一部电影的多个分类标签
                genreIDList = []  # 每个电影拥有的分类标签列表
                for genre in genreList:
                    if genre in genreIDs:  # 如果genre存在于已有的分类标签
                        genreID = genreIDs[genre]  # 将genreID赋值为该标签对应的数字
                    else:  # 如果不存在
                        genreID = maxGenreID  # 把一个新的数字类别赋值给genreID
                        genreIDs[genre] = genreID  # 添加新的类别对照进入对照字典
                        maxGenreID += 1  # 类别数量加一
                    genreIDList.append(genreID)  # 更新每个电影拥有的分类标签列表(数字形式)
                genres[movieID] = genreIDList  # 获得每个电影分类标签列表字典
        # 将数字形式的分类标签列表转换成0、1表示的矩阵
        for (movieID, genreIDList) in genres.items():
            bitfield = [0] * maxGenreID  # 创建一个类别数量长度的行向量
            for genreID in genreIDList:  # 遍历拥有的类别列表(数字列表),以此来确定行向量的哪些位置赋值为1
                bitfield[genreID] = 1
            genres[movieID] = bitfield  # 将标签字典换成标签行向量

        return genres

getYears函数

获取电影年份

    def getYears(self):
        expToMatch = re.compile(r"(?:\((\d{4})\))?\s*$")  # 取出年份的正则表达式
        years = defaultdict(int)
        with open(self.movies_file_location, newline='', encoding='ISO-8859-1') as csvfile:
            movieReader = csv.reader(csvfile)
            next(movieReader)
            for row in movieReader:
                movieId = int(row[0])
                title = row[1]
                rawYear = expToMatch.search(title)  # 在电影标题中根据正则表达式搜索年份
                year = rawYear.group(1)  # 获取第二个括号匹配的内容
                if year:
                    years[movieId] = int(year)
        return years
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值