Jasur05 commited on
Commit
a3ac22a
·
1 Parent(s): acaf595
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
AI-powered-Book-Recommender ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit 199ada43ed60008f6a21c012a4d1b2c922ce8ad4
__pycache__/g_UI.cpython-310.pyc ADDED
Binary file (3.61 kB). View file
 
__pycache__/gradio.cpython-310.pyc ADDED
Binary file (3.61 kB). View file
 
__pycache__/gradio_UI.cpython-310.pyc ADDED
Binary file (3.62 kB). View file
 
books.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:38608249125de795a50a352c8cba7ccb4ee79d6a379628f6d100921faa6de14e
3
+ size 1559650
books_cleaned.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3a94b63957a665628ac24987fff5c27219e18374cb6d1d43ecac864125e7b6fe
3
+ size 6467384
books_with_categories.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4c5149a2a65e0b9656d0262ba18cc67280922cebaee19b203a75d114f6315e76
3
+ size 6520188
books_with_emotions.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ca2aa2c7b41fd373a47ac8d7ca255fa8135c1c64e14b1ae84d4ffde674138be7
3
+ size 7238781
data-exploration.ipynb ADDED
File without changes
g_UI.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+
4
+
5
+ from langchain_community.document_loaders import TextLoader
6
+ from langchain_openai import OpenAIEmbeddings
7
+ from langchain_text_splitters import CharacterTextSplitter
8
+ from langchain_chroma import Chroma
9
+
10
+ from langchain.embeddings import HuggingFaceEmbeddings
11
+
12
+ model_name = "sentence-transformers/all-MiniLM-L6-v2"
13
+ HF_embedding = HuggingFaceEmbeddings(model_name=model_name)
14
+
15
+
16
+
17
+ import gradio as gr
18
+
19
+
20
+ books = pd.read_csv("books_with_emotions.csv")
21
+ books["large_thumbnail"] = books["thumbnail"] + "&fife=w800"
22
+ books["large_thumbnail"] = np.where(
23
+ books["large_thumbnail"].isna(),
24
+ "cover_coming.jpg",
25
+ books["large_thumbnail"],
26
+ )
27
+
28
+ raw_documents = TextLoader("tagged_description.txt").load()
29
+ text_splitter = CharacterTextSplitter(separator="\n", chunk_size=0, chunk_overlap=0)
30
+ documents = text_splitter.split_documents(raw_documents)
31
+ db_books = Chroma.from_documents(documents, HF_embedding)
32
+
33
+ def retrieve_semantic_recommendations(
34
+ query:str,
35
+ category: str = None,
36
+ tone:str = None,
37
+ initial_top_k: int=50,
38
+ final_top_k: int=16
39
+
40
+ ):
41
+ recs = db_books.similarity_search(query, k=initial_top_k)
42
+ books_list = [int(rec.page_content.strip('"').split()[0]) for rec in recs]
43
+ book_recs = books[books["isbn13"].isin(books_list)].head(final_top_k)
44
+
45
+ if category != "All":
46
+ book_recs = book_recs[book_recs["simple_categories"] == category].head(final_top_k)
47
+ else:
48
+ book_recs = book_recs.head(final_top_k)
49
+
50
+ if tone == "Happy":
51
+ book_recs.sort_values(by="joy", ascending=False, inplace=True)
52
+ elif tone == "Surprising":
53
+ book_recs.sort_values(by="surprise", ascending=False, inplace=True)
54
+ elif tone == "Angry":
55
+ book_recs.sort_values(by="anger", ascending=False, inplace=True)
56
+ elif tone == "Suspenseful":
57
+ book_recs.sort_values(by="fear", ascending=False, inplace=True)
58
+ elif tone == "Sad":
59
+ book_recs.sort_values(by="sadness", ascending=False, inplace=True)
60
+
61
+ return book_recs
62
+
63
+ def recommend_books(
64
+ query: str,
65
+ category: str,
66
+ tone: str
67
+ ):
68
+ recommendations = retrieve_semantic_recommendations(query, category, tone)
69
+ results = []
70
+
71
+ for _, row in recommendations.iterrows():
72
+ description = row["description"]
73
+ truncated_desc_split = description.split()
74
+ truncated_description = " ".join(truncated_desc_split[:30]) + "..."
75
+
76
+ authors_split = row["authors"].split(";")
77
+ if len(authors_split) == 2:
78
+ authors_str = f"{authors_split[0]} and {authors_split[1]}"
79
+ elif len(authors_split) > 2:
80
+ authors_str = f"{', '.join(authors_split[:-1])}, and {authors_split[-1]}"
81
+ else:
82
+ authors_str = row["authors"]
83
+
84
+ caption = f"{row['title']} by {authors_str}: {truncated_description}"
85
+ results.append((row["large_thumbnail"], caption))
86
+ return results
87
+
88
+ categories = ["All"] + sorted(books["simple_categories"].unique())
89
+ tones = ["All"] + ["Happy", "Surprising", "Angry", "Suspenseful", "Sad"]
90
+
91
+ with gr.Blocks(theme = gr.themes.Glass()) as dashboard:
92
+ gr.Markdown("# Your AI-powered Book recommender")
93
+
94
+ with gr.Row():
95
+ user_query = gr.Textbox(label = "Please enter a description about the book:",
96
+ placeholder = "e.g., A book exploring human resilience ")
97
+ category_dropdown = gr.Dropdown(choices = categories, label = "Select a category:", value = "All")
98
+ tone_dropdown = gr.Dropdown(choices = tones, label = "Select an emotional tone:", value = "All")
99
+ submit_button = gr.Button("Find recommendations")
100
+
101
+ gr.Markdown("## Recommendations")
102
+ output = gr.Gallery(label = "Recommended books", columns = 8, rows = 2)
103
+
104
+ submit_button.click(fn = recommend_books,
105
+ inputs = [user_query, category_dropdown, tone_dropdown],
106
+ outputs = output)
107
+
108
+
109
+ if __name__ == "__main__":
110
+ dashboard.launch(share=True)
111
+
sentiment-analysis.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
tagged_description.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ec902e249d79948f8031e7e521315a2a17157d96ca084891321b4fbdc2622e3
3
+ size 2641649
vector-search.ipynb ADDED
File without changes
work.ipynb ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 3,
6
+ "id": "3e1d6318",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import pandas as pd\n",
11
+ "import numpy as np\n",
12
+ "from sklearn.feature_extraction.text import TfidfVectorizer\n",
13
+ "from sklearn.metrics.pairwise import linear_kernel\n",
14
+ "import plotly.express as px\n",
15
+ "import plotly.graph_objects as go"
16
+ ]
17
+ },
18
+ {
19
+ "cell_type": "code",
20
+ "execution_count": 5,
21
+ "id": "1d8722fa",
22
+ "metadata": {},
23
+ "outputs": [
24
+ {
25
+ "name": "stdout",
26
+ "output_type": "stream",
27
+ "text": [
28
+ " bookID title \\\n",
29
+ "0 1 Harry Potter and the Half-Blood Prince (Harry ... \n",
30
+ "1 2 Harry Potter and the Order of the Phoenix (Har... \n",
31
+ "2 4 Harry Potter and the Chamber of Secrets (Harry... \n",
32
+ "3 5 Harry Potter and the Prisoner of Azkaban (Harr... \n",
33
+ "4 8 Harry Potter Boxed Set Books 1-5 (Harry Potte... \n",
34
+ "\n",
35
+ " authors average_rating isbn isbn13 \\\n",
36
+ "0 J.K. Rowling/Mary GrandPré 4.57 0439785960 9780439785969 \n",
37
+ "1 J.K. Rowling/Mary GrandPré 4.49 0439358078 9780439358071 \n",
38
+ "2 J.K. Rowling 4.42 0439554896 9780439554893 \n",
39
+ "3 J.K. Rowling/Mary GrandPré 4.56 043965548X 9780439655484 \n",
40
+ "4 J.K. Rowling/Mary GrandPré 4.78 0439682584 9780439682589 \n",
41
+ "\n",
42
+ " language_code num_pages ratings_count text_reviews_count \\\n",
43
+ "0 eng 652 2095690 27591 \n",
44
+ "1 eng 870 2153167 29221 \n",
45
+ "2 eng 352 6333 244 \n",
46
+ "3 eng 435 2339585 36325 \n",
47
+ "4 eng 2690 41428 164 \n",
48
+ "\n",
49
+ " publication_date publisher \n",
50
+ "0 9/16/2006 Scholastic Inc. \n",
51
+ "1 9/1/2004 Scholastic Inc. \n",
52
+ "2 11/1/2003 Scholastic \n",
53
+ "3 5/1/2004 Scholastic Inc. \n",
54
+ "4 9/13/2004 Scholastic \n"
55
+ ]
56
+ }
57
+ ],
58
+ "source": [
59
+ "data = pd.read_csv(\"books.csv\", on_bad_lines='skip')\n",
60
+ "print(data.head())"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "code",
65
+ "execution_count": 6,
66
+ "id": "29eaf0ad",
67
+ "metadata": {},
68
+ "outputs": [
69
+ {
70
+ "name": "stdout",
71
+ "output_type": "stream",
72
+ "text": [
73
+ "<class 'pandas.core.frame.DataFrame'>\n",
74
+ "RangeIndex: 11123 entries, 0 to 11122\n",
75
+ "Data columns (total 12 columns):\n",
76
+ " # Column Non-Null Count Dtype \n",
77
+ "--- ------ -------------- ----- \n",
78
+ " 0 bookID 11123 non-null int64 \n",
79
+ " 1 title 11123 non-null object \n",
80
+ " 2 authors 11123 non-null object \n",
81
+ " 3 average_rating 11123 non-null float64\n",
82
+ " 4 isbn 11123 non-null object \n",
83
+ " 5 isbn13 11123 non-null int64 \n",
84
+ " 6 language_code 11123 non-null object \n",
85
+ " 7 num_pages 11123 non-null int64 \n",
86
+ " 8 ratings_count 11123 non-null int64 \n",
87
+ " 9 text_reviews_count 11123 non-null int64 \n",
88
+ " 10 publication_date 11123 non-null object \n",
89
+ " 11 publisher 11123 non-null object \n",
90
+ "dtypes: float64(1), int64(5), object(6)\n",
91
+ "memory usage: 1.0+ MB\n"
92
+ ]
93
+ }
94
+ ],
95
+ "source": [
96
+ "data.info()"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": 8,
102
+ "id": "1cc05570",
103
+ "metadata": {},
104
+ "outputs": [
105
+ {
106
+ "ename": "ValueError",
107
+ "evalue": "Mime type rendering requires nbformat>=4.2.0 but it is not installed",
108
+ "output_type": "error",
109
+ "traceback": [
110
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
111
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
112
+ "Cell \u001b[0;32mIn[8], line 6\u001b[0m\n\u001b[1;32m 4\u001b[0m fig\u001b[38;5;241m.\u001b[39mupdate_xaxes(title_text\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAverage Rating\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 5\u001b[0m fig\u001b[38;5;241m.\u001b[39mupdate_yaxes(title_text\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFrequency\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m----> 6\u001b[0m \u001b[43mfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshow\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
113
+ "File \u001b[0;32m~/Documents/github repos/Book_rec_system/.venv/lib/python3.10/site-packages/plotly/basedatatypes.py:3420\u001b[0m, in \u001b[0;36mBaseFigure.show\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3387\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 3388\u001b[0m \u001b[38;5;124;03mShow a figure using either the default renderer(s) or the renderer(s)\u001b[39;00m\n\u001b[1;32m 3389\u001b[0m \u001b[38;5;124;03mspecified by the renderer argument\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 3416\u001b[0m \u001b[38;5;124;03mNone\u001b[39;00m\n\u001b[1;32m 3417\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 3418\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mplotly\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mio\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mpio\u001b[39;00m\n\u001b[0;32m-> 3420\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mpio\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshow\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
114
+ "File \u001b[0;32m~/Documents/github repos/Book_rec_system/.venv/lib/python3.10/site-packages/plotly/io/_renderers.py:415\u001b[0m, in \u001b[0;36mshow\u001b[0;34m(fig, renderer, validate, **kwargs)\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 411\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMime type rendering requires ipython but it is not installed\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 412\u001b[0m )\n\u001b[1;32m 414\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m nbformat \u001b[38;5;129;01mor\u001b[39;00m Version(nbformat\u001b[38;5;241m.\u001b[39m__version__) \u001b[38;5;241m<\u001b[39m Version(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m4.2.0\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 415\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 416\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMime type rendering requires nbformat>=4.2.0 but it is not installed\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 417\u001b[0m )\n\u001b[1;32m 419\u001b[0m display_jupyter_version_warnings()\n\u001b[1;32m 421\u001b[0m ipython_display\u001b[38;5;241m.\u001b[39mdisplay(bundle, raw\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n",
115
+ "\u001b[0;31mValueError\u001b[0m: Mime type rendering requires nbformat>=4.2.0 but it is not installed"
116
+ ]
117
+ }
118
+ ],
119
+ "source": [
120
+ "fig = px.histogram(data, x='average_rating', \n",
121
+ " nbins=30, \n",
122
+ " title='Distribution of Average Ratings')\n",
123
+ "fig.update_xaxes(title_text='Average Rating')\n",
124
+ "fig.update_yaxes(title_text='Frequency')\n",
125
+ "fig.show()"
126
+ ]
127
+ },
128
+ {
129
+ "cell_type": "code",
130
+ "execution_count": null,
131
+ "id": "a0686419",
132
+ "metadata": {},
133
+ "outputs": [],
134
+ "source": []
135
+ },
136
+ {
137
+ "cell_type": "code",
138
+ "execution_count": null,
139
+ "id": "192cc248",
140
+ "metadata": {},
141
+ "outputs": [],
142
+ "source": []
143
+ },
144
+ {
145
+ "cell_type": "code",
146
+ "execution_count": null,
147
+ "id": "412c1b95",
148
+ "metadata": {},
149
+ "outputs": [],
150
+ "source": []
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": null,
155
+ "id": "792c4d40",
156
+ "metadata": {},
157
+ "outputs": [],
158
+ "source": []
159
+ }
160
+ ],
161
+ "metadata": {
162
+ "kernelspec": {
163
+ "display_name": ".venv",
164
+ "language": "python",
165
+ "name": "python3"
166
+ },
167
+ "language_info": {
168
+ "codemirror_mode": {
169
+ "name": "ipython",
170
+ "version": 3
171
+ },
172
+ "file_extension": ".py",
173
+ "mimetype": "text/x-python",
174
+ "name": "python",
175
+ "nbconvert_exporter": "python",
176
+ "pygments_lexer": "ipython3",
177
+ "version": "3.10.18"
178
+ }
179
+ },
180
+ "nbformat": 4,
181
+ "nbformat_minor": 5
182
+ }