File size: 5,378 Bytes
8ffebd2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67f0e42
 
8ffebd2
67f0e42
8ffebd2
67f0e42
8ffebd2
 
67f0e42
8ffebd2
67f0e42
 
 
 
 
 
 
 
 
 
 
 
8ffebd2
 
 
 
 
 
 
 
67f0e42
 
 
8ffebd2
 
 
 
 
67f0e42
 
8ffebd2
67f0e42
8ffebd2
67f0e42
 
8ffebd2
67f0e42
 
8ffebd2
67f0e42
 
8ffebd2
67f0e42
 
8ffebd2
67f0e42
8ffebd2
67f0e42
8ffebd2
67f0e42
8ffebd2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67f0e42
8ffebd2
 
 
 
 
 
 
 
 
 
67f0e42
8ffebd2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67f0e42
8ffebd2
 
67f0e42
8ffebd2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
# coding: utf-8

import pandas as pd 
import numpy as np 
from supabase import create_client, Client

# Your Supabase project details
URL = "https://oflclzbsbgkadqiagxqk.supabase.co"  # Supabase project URL
KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9mbGNsemJzYmdrYWRxaWFneHFrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDY0OTY3OTIsImV4cCI6MjAyMjA3Mjc5Mn0.2IGuSFqHbNp75vs-LskGjK0fw3ypqbiHJ9MKAAaYE8s"                    # Supabase API key
supabase: Client = create_client(URL, KEY)

def convert_table_to_pandas_dataframe(supabase, table_name):
    # Retrieve data from Supabase
    data = supabase.table(table_name).select("*").execute()
        
    # Convert to DataFrame
    df = pd.DataFrame(data.data)

    return df

books_df = convert_table_to_pandas_dataframe(supabase, "books")

pd.set_option('display.max_colwidth', 50)
pd.set_option('display.max_columns', None)

books_df.head(5)

books_df['combined'] = books_df['description'] + ' ' + books_df['title'] + ' ' + books_df['author_name']


# Content-based recommender

# Trong khai phá dữ liệu văn bản (text mining), thuật ngữ TF-IDF (term frequency - inverse document frequency) là một phương thức thống kê được biết đến rộng rãi nhất để xác định độ quan trọng của một từ trong đoạn văn bản trong một tập nhiều đoạn văn bản khác nhau. 
# 
# TF (Term Frequency): là tần suất xuất hiện của một từ trong một đoạn văn bản.
# TF(t) = f(t,d)/T
# (t là từ, f(t,d) là tần suất xuất hiện từ t trong đoạn d, T là tổng số từ trong đoạn văn T)
# 
# IDF (Inverse Document Frequency): tính toán độ quan trọng của một từ. Khi tính toán TF, mỗi từ đều quan trọng như nhau, nhưng có một số từ trong tiếng Anh như "is", "of", "that",... xuất hiện khá nhiều nhưng lại rất ít quan trọng. Vì vậy, chúng ta cần một phương thức bù trừ những từ xuất hiện nhiều lần và tăng độ quan trọng của những từ ít xuất hiện những có ý nghĩa đặc biệt cho một số đoạn văn bản hơn bằng cách tính IDF.
# 
# IDF(t) = log(N/∣t∈D:t∈d∣) 
# (N là tổng số đoạn văn bản)
# 
# TF-IDF(t) = TF(t) * IDF(t)

#Import TfIdfVectorizer from scikit-learn
from sklearn.feature_extraction.text import TfidfVectorizer

#Define a TF-IDF Vectorizer Object. Remove all english stop words such as 'the', 'a'
tfidf = TfidfVectorizer(stop_words='english')

#Construct the required TF-IDF matrix by fitting and transforming the data
tfidf_matrix = tfidf.fit_transform(books_df['combined'])

feature_names = tfidf.get_feature_names() 

#Output the shape of tfidf_matrix
tfidf_matrix.shape


# 20183 -> total document in the corpus
# 141956 -> total distinct terms in the corpus 

feature_names[2000:2500]

# Assuming 'tfidf_matrix' is your TF-IDF matrix
# Assuming 'document_index' is the index of the document you want to calculate the total terms for

# Get the TF-IDF vector for the specified document
document_tfidf_vector = tfidf_matrix[10]

# Sum up the TF-IDF weights for all terms in the document
total_terms_in_document = document_tfidf_vector.sum()

print("Document vector: ", tfidf_matrix[10])
print("Total terms in document {}: {}".format(10, total_terms_in_document))

tfidf

print(tfidf_matrix[0].shape)

# Cosine similarity function for comparing every two documents
# Import linear_kernel
from sklearn.metrics.pairwise import linear_kernel

# Compute the cosine similarity matrix
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)

indices = pd.Series(books_df.index, index=books_df['title']).drop_duplicates()

def get_original_book_id(title):
    return books_df.loc[books_df['title'] == title, 'id'].values[0]

# Function that takes in movie title as input and outputs most similar movies
def get_top_five_recommendations(title, cosine_sim=cosine_sim):
    # Get the index of the movie that matches the title
    idx = indices[title]

    # Get the pairwsie similarity scores of all movies with that movie
    sim_scores = list(enumerate(cosine_sim[idx]))
    
    # Sort the movies based on the similarity scores
    sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)

    # Get the scores of the 10 most similar movies
    sim_scores = sim_scores[:11]

    # Get the movie indices
    book_indices = [i[0] for i in sim_scores]

#     # Return the top 10 most similar movies
#     return books_df['title'].iloc[book_indices]

    ids = []
    for title in books_df['title'].iloc[book_indices]:
        ids.append(get_original_book_id(title))
    ids.pop(0)
    return ids

get_top_five_recommendations('Walls of Ash')

books_df[books_df['id'].isin(get_top_five_recommendations('Walls of Ash'))]['url']


from flask import Flask, jsonify, request
from flask_ngrok import run_with_ngrok

app = Flask(__name__)
run_with_ngrok(app)  # Start ngrok when app is run

import json
@app.route('/predict/<int:id>', methods=['GET'])
def predict(id):
    title = books_df[books_df['id'] == id]['title'].values[0]
    print(title)
    prediction_result = [int(x) for x in get_top_five_recommendations(title)]
    return json.dumps(prediction_result)

from waitress import serve

if __name__ == '__main__': 
    serve(app, host="0.0.0.0", port=8080)