[+] A3 P3 Q1-2

This commit is contained in:
Hykilpikonna
2022-03-21 12:57:06 -04:00
parent ab207b3f31
commit 878e0df64b
3 changed files with 57 additions and 7 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ This file is Copyright (c) 2022 Mario Badr, David Liu, and Isaac Waller.
"""
from __future__ import annotations
import csv
from typing import Any
from typing import Any, Literal
# Make sure you've installed the necessary Python libraries (see assignment handout
# "Installing new libraries" section)
@@ -143,7 +143,7 @@ class Graph:
else:
raise ValueError
def get_all_vertices(self, kind: str = '') -> set:
def get_all_vertices(self, kind: Literal['', 'user', 'book'] = '') -> set:
"""Return a set of all vertex items in this graph.
If kind != '', only return the items of the given vertex kind.
+3 -3
View File
@@ -20,7 +20,7 @@ This file is Copyright (c) 2022 Mario Badr, David Liu, and Isaac Waller.
"""
from __future__ import annotations
import csv
from typing import Any, Union
from typing import Any, Union, Literal
from a3_part1 import Graph
@@ -175,7 +175,7 @@ class WeightedGraph(Graph):
# Part 2, Q2
############################################################################
def get_similarity_score(self, item1: Any, item2: Any,
score_type: str = 'unweighted') -> float:
score_type: Literal['unweighted', 'strict'] = 'unweighted') -> float:
"""Return the similarity score between the two given items in this graph.
score_type is one of 'unweighted' or 'strict', corresponding to the
@@ -194,7 +194,7 @@ class WeightedGraph(Graph):
return self._vertices[item1].similarity_score_strict(self._vertices[item2])
def recommend_books(self, book: str, limit: int,
score_type: str = 'unweighted') -> list[str]:
score_type: Literal['unweighted', 'strict'] = 'unweighted') -> list[str]:
"""Return a list of up to <limit> recommended books based on similarity to the given book.
score_type is one of 'unweighted' or 'strict', corresponding to the
+52 -2
View File
@@ -18,8 +18,9 @@ please consult our Course Syllabus.
This file is Copyright (c) 2022 Mario Badr, David Liu, and Isaac Waller.
"""
import random
from typing import Literal
from a3_part2_recommendations import WeightedGraph, load_weighted_review_graph
from a3_part2_recommendations import WeightedGraph
################################################################################
@@ -27,7 +28,7 @@ from a3_part2_recommendations import WeightedGraph, load_weighted_review_graph
################################################################################
def create_book_graph(review_graph: WeightedGraph,
threshold: float = 0.05,
score_type: str = 'unweighted') -> WeightedGraph:
score_type: Literal['unweighted', 'strict'] = 'unweighted') -> WeightedGraph:
"""Return a book graph based on the given review_graph.
The score_type parameter plays the same role as in WeightedGraph.get_similarity_score.
@@ -46,6 +47,28 @@ def create_book_graph(review_graph: WeightedGraph,
Preconditions:
- score_type in {'unweighted', 'strict'}
"""
# Add all books as vertices
book_graph = WeightedGraph()
book_names: set[str] = review_graph.get_all_vertices('book')
for b in book_names:
book_graph.add_vertex(b, 'book')
# Add all edges
for b1 in book_names:
for b2 in book_names:
if b1 == b2:
continue
# Calculate similarity score
score = review_graph.get_similarity_score(b1, b2, score_type)
if score <= threshold:
continue
# Add edge
book_graph.add_edge(b1, b2, score)
# Done
return book_graph
################################################################################
@@ -60,7 +83,21 @@ def cross_cluster_weight(book_graph: WeightedGraph, cluster1: set, cluster2: set
- cluster1 != set() and cluster2 != set()
- cluster1.isdisjoint(cluster2)
- Every item in cluster1 and cluster2 is a vertex in book_graph
>>> bg = WeightedGraph()
>>> for b in range(4): \
bg.add_vertex(f'B{b}', 'book')
>>> bg.add_edge('B0', 'B1', .5)
>>> bg.add_edge('B0', 'B2', .4)
>>> bg.add_edge('B1', 'B2', .3)
>>> bg.get_weight('B0', 'B1')
0.5
>>> cross_cluster_weight(bg, {'B0', 'B1'}, {'B2', 'B3'}) == (.4 + .3) / 4
True
"""
numerator = sum(book_graph.get_weight(v1, v2) for v1 in cluster1 for v2 in cluster2)
denominator = len(cluster1) * len(cluster2)
return numerator / denominator
################################################################################
@@ -151,3 +188,16 @@ if __name__ == '__main__':
'allowed-io': ['find_clusters_greedy', 'find_clusters_random'],
'max-nested-blocks': 4
})
# Q1 Test
# review_graph = load_weighted_review_graph('data/reviews_full.csv', 'data/book_names.csv')
# book_graph = create_book_graph(review_graph, 0.03)
# from a3_visualization import visualize_graph
# visualize_graph(book_graph)
# Q3 Test
# review_graph = load_weighted_review_graph('data/reviews_full.csv', 'data/book_names.csv')
# book_graph = create_book_graph(review_graph, threshold=0.01, score_type='strict')
# clusters = find_clusters_random(book_graph, 15)
# from a3_visualization import visualize_graph_clusters
# visualize_graph_clusters(book_graph, clusters)