#
# tripadvisor.py
#
# Copyright (c) 2017 Junpei Kawamoto
#
# This file is part of rgmining-tripadvisor-dataset.
#
# rgmining-tripadvisor-dataset is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# rgmining-tripadvisor-dataset is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Foobar. If not, see <http://www.gnu.org/licenses/>.
#
# pylint: disable=invalid-name
"""This module provides a loading function of the Trip Advisor Dataset.
It also a helper function, :meth:`print_state`, to output a state of a graph
object.
To use both fuctions, the graph object must implement the
:ref:`graph interface <dataset-io:graph-interface>`.
"""
from __future__ import division
from contextlib import closing
import datetime
import json
from os.path import exists, join
import site
import sys
import tarfile
_DATE_FORMAT = "%B %d, %Y"
"""Data format in the dataset.
"""
def _files(tar):
"""Yields a file in the tar file.
"""
info = tar.next()
while info:
if info.isfile():
yield info
info = tar.next()
[docs]def load(graph):
"""Load the Trip Advisor dataset to a given graph object.
The graph object must implement the
:ref:`graph interface <dataset-io:graph-interface>`.
Args:
graph: an instance of bipartite graph.
Returns:
The graph instance *graph*.
"""
base = "TripAdvisorJson.tar.bz2"
path = join(".", base)
if not exists(path):
path = join(sys.prefix, "rgmining","data", base)
if not exists(path):
path = join(sys.prefix, "local", "rgmining","data", base)
if not exists(path):
path = join(site.getuserbase(), "rgmining","data", base)
R = {} # Reviewers dict.
with tarfile.open(path) as tar:
for info in _files(tar):
with closing(tar.extractfile(info)) as fp:
obj = json.load(fp)
target = obj["HotelInfo"]["HotelID"]
product = graph.new_product(name=target)
for r in obj["Reviews"]:
name = r["ReviewID"]
score = float(r["Ratings"]["Overall"]) / 5.
try:
date = datetime.datetime.strptime(
r["Date"], _DATE_FORMAT).strftime("%Y%m%d")
except ValueError:
date = None
if name not in R:
R[name] = graph.new_reviewer(name=name)
graph.add_review(R[name], product, score, date)
return graph
[docs]def print_state(g, i, output=sys.stdout):
"""Print a current state of a given graph.
This method outputs a current of a graph as a set of json objects.
Graph objects must have two properties, `reviewers` and `products`.
Those properties returns a set of reviewers and products respectively.
See the :ref:`graph interface <dataset-io:graph-interface>`
for more information.
In this output format, each line represents a reviewer or product object.
Reviewer objects are defined as ::
{
"iteration": <the iteration number given as i>
"reviewer":
{
"reviewer_id": <Reviewer's ID>
"score": <Anomalous score of the reviewer>
}
}
Product objects are defined as ::
{
"iteration": <the iteration number given as i>
"reviewer":
{
"product_id": <Product's ID>
"sumarry": <Summary of the reviews for the product>
}
}
Args:
g: Graph instance.
i: Iteration number.
output: A writable object (default: sys.stdout).
"""
for r in g.reviewers:
json.dump({
"iteration": i,
"reviewer": {
"reviewer_id": r.name,
"score": r.anomalous_score
}
}, output)
output.write("\n")
for p in g.products:
json.dump({
"iteration": i,
"product": {
"product_id": p.name,
"summary": float(str(p.summary))
}
}, output)
output.write("\n")