diff --git a/engine.py b/engine.py index c5504cb..9292ef6 100644 --- a/engine.py +++ b/engine.py @@ -2,64 +2,72 @@ from simpful import * FS = FuzzySystem() -# Define fuzzy sets for the variable # Define fuzzy sets for the variable +# Define fuzzy sets for the variable # RELEASE_YEAR release_year_newer = TriangleFuzzySet(-68, -68, 0, term="newer") release_year_similar = TriangleFuzzySet(-68, 0, 68, term="similar") release_year_older = TriangleFuzzySet(0, 68, 68, term="older") -FS.add_linguistic_variable("RELEASE_YEAR", LinguisticVariable( [release_year_newer, release_year_similar, release_year_older], universe_of_discourse=[-136, 136] )) +FS.add_linguistic_variable("RELEASE_YEAR", + LinguisticVariable([release_year_newer, release_year_similar, release_year_older], + universe_of_discourse=[-136, 136])) # RUNTIME runtime_shorter = TriangleFuzzySet(-238, -238, 0, term="shorter") runtime_similar = TriangleFuzzySet(-238, 0, 238, term="similar") runtime_longer = TriangleFuzzySet(0, 238, 238, term="longer") -FS.add_linguistic_variable("RUNTIME", LinguisticVariable( [runtime_shorter, runtime_similar, runtime_longer], universe_of_discourse=[-476, 476] )) +FS.add_linguistic_variable("RUNTIME", LinguisticVariable([runtime_shorter, runtime_similar, runtime_longer], + universe_of_discourse=[-476, 476])) # SEASONS seasons_less = TriangleFuzzySet(-42, -42, 0, term="less") seasons_similar = TriangleFuzzySet(-42, 0, 42, term="similar") seasons_more = TriangleFuzzySet(0, 42, 42, term="more") -FS.add_linguistic_variable("SEASONS", LinguisticVariable( [seasons_less, seasons_similar, seasons_more], universe_of_discourse=[-84, 84] )) +FS.add_linguistic_variable("SEASONS", LinguisticVariable([seasons_less, seasons_similar, seasons_more], + universe_of_discourse=[-84, 84])) # GENRES genres_different = TriangleFuzzySet(-100, -100, 0, term="different") genres_similar = TriangleFuzzySet(-100, 0, 100, term="similar") genres_same = TriangleFuzzySet(0, 100, 100, term="same") -FS.add_linguistic_variable("GENRES", LinguisticVariable( [genres_different, genres_similar, genres_same], universe_of_discourse=[-200, 200] )) +FS.add_linguistic_variable("GENRES", LinguisticVariable([genres_different, genres_similar, genres_same], + universe_of_discourse=[-200, 200])) # EMOTIONS emotions_different = TriangleFuzzySet(-4, -4, 0, term="different") emotions_similar = TriangleFuzzySet(-4, 0, 4, term="similar") emotions_same = TriangleFuzzySet(0, 4, 4, term="same") -FS.add_linguistic_variable("EMOTIONS", LinguisticVariable( [emotions_different, emotions_similar, emotions_same], universe_of_discourse=[-8, 8] )) +FS.add_linguistic_variable("EMOTIONS", LinguisticVariable([emotions_different, emotions_similar, emotions_same], + universe_of_discourse=[-8, 8])) -# RECOMENDATION -low_recomendation = TriangleFuzzySet(0, 0, 50, term="low_recomendation") -medium_recomendation = TriangleFuzzySet(0, 50, 100, term="medium_recomendation") -high_recomendation = TriangleFuzzySet(0, 100, 100, term="high_recomendation") -FS.add_linguistic_variable("RECOMENDATION", LinguisticVariable( [low_recomendation, medium_recomendation, high_recomendation], universe_of_discourse=[0, 200] )) +# RECOMMENDATION +low_recommendation = TriangleFuzzySet(0, 0, 50, term="low_recommendation") +medium_recommendation = TriangleFuzzySet(0, 50, 100, term="medium_recommendation") +high_recommendation = TriangleFuzzySet(0, 100, 100, term="high_recommendation") +FS.add_linguistic_variable("RECOMMENDATION", + LinguisticVariable([low_recommendation, medium_recommendation, high_recommendation], + universe_of_discourse=[0, 200])) # RULES -RULE1 = "IF (RELEASE_YEAR IS older) AND (RUNTIME IS longer) AND (SEASONS IS more) THEN (RECOMENDATION IS low_recomendation)" -RULE2 = "IF (EMOTIONS IS different) AND (GENRES IS different) THEN (RECOMENDATION IS low_recomendation)" -RULE3 = "IF (RELEASE_YEAR IS newer) AND (RUNTIME IS similar) AND (SEASONS IS less) THEN (RECOMENDATION IS medium_recomendation)" -RULE4 = "IF (EMOTIONS IS similar) AND (GENRES IS similar) THEN (RECOMENDATION IS medium_recomendation)" -RULE5 = "IF (RELEASE_YEAR IS similar) AND (RUNTIME IS similar) AND (SEASONS IS similar) AND (EMOTIONS IS same) AND (GENRES IS same) THEN (RECOMENDATION IS high_recomendation)" +RULE1 = "IF (RELEASE_YEAR IS older) AND (RUNTIME IS longer) AND (SEASONS IS more) THEN (RECOMMENDATION IS low_recommendation)" +RULE2 = "IF (EMOTIONS IS different) AND (GENRES IS different) THEN (RECOMMENDATION IS low_recommendation)" +RULE3 = "IF (RELEASE_YEAR IS newer) AND (RUNTIME IS similar) AND (SEASONS IS less) THEN (RECOMMENDATION IS medium_recommendation)" +RULE4 = "IF (EMOTIONS IS similar) AND (GENRES IS similar) THEN (RECOMMENDATION IS medium_recommendation)" +RULE5 = "IF (RELEASE_YEAR IS similar) AND (RUNTIME IS similar) AND (SEASONS IS similar) AND (EMOTIONS IS same) AND (GENRES IS same) THEN (RECOMMENDATION IS high_recommendation)" # Z regułami trzeba eksperymentować, można porównywać ze scorem dla sprawdzania skuteczności FS.add_rules([RULE1, RULE2, RULE3, RULE4, RULE5]) -FS.set_variable("RELEASE_YEAR", -12.0) -FS.set_variable("RUNTIME", -10.0) -FS.set_variable("SEASONS", -2.0) -FS.set_variable("GENRES", 50.0) -FS.set_variable("EMOTIONS", 1.0) +# FS.set_variable("RELEASE_YEAR", -12.0) +# FS.set_variable("RUNTIME", -10.0) +# FS.set_variable("SEASONS", -2.0) +# FS.set_variable("GENRES", 50.0) +# FS.set_variable("EMOTIONS", 1.0) +# +# print(FS.inference(["RECOMMENDATION"])) -print(FS.inference(["RECOMENDATION"])) - -FS.produce_figure(outputfile='visualize_terms.pdf') \ No newline at end of file +# FS.produce_figure(outputfile='visualize_terms.pdf') diff --git a/main.py b/main.py new file mode 100644 index 0000000..a4f70d7 --- /dev/null +++ b/main.py @@ -0,0 +1,61 @@ +""" +!pip install scikit-learn +!pip install pandas +!pip install fastapi +!pip install "uvicorn[standard]" +!uvicorn main:app --reload +""" + +import numpy as np +import pandas as pd +from fastapi import FastAPI +from scipy.spatial.distance import cosine +from sklearn.preprocessing import MultiLabelBinarizer + +from engine import FS + +app = FastAPI() +data = pd.DataFrame() + + +@app.on_event('startup') +async def startup_event(): + global data + data = pd.read_csv('processed_data.csv', index_col='id', converters={'genres': pd.eval}) + all_genres = data.genres.explode().unique() + mlb = MultiLabelBinarizer() + mlb.fit([all_genres]) + data['genres'] = data['genres'].apply(lambda x: mlb.transform([x])[0]) + data['emotions'] = data[['Happy', 'Angry', 'Surprise', 'Sad', 'Fear']].values.tolist() + + +@app.get('/score/{first_id}/{second_id}') +def rec_score(first_id: str, second_id: str): + try: + first = data.loc[first_id] + except KeyError: + return {'error': f'{first_id} is not a valid id'} + try: + second = data.loc[second_id] + except KeyError: + return {'error': f'{second_id} is not a valid id'} + + year_diff = int(first['release_year'] - second['release_year']) + FS.set_variable('RELEASE_YEAR', year_diff) + + runtime_diff = int(first['runtime'] - second['runtime']) + FS.set_variable('RUNTIME', runtime_diff) + + if not (np.isnan(first['seasons']) or np.isnan(second['seasons'])): + season_diff = int(first['seasons'] - second['seasons']) + FS.set_variable('SEASONS', season_diff) + else: + FS.set_variable('SEASONS', 0) + + genre_diff = 1 - cosine(first['genres'], second['genres']) + FS.set_variable('GENRES', genre_diff) + + emotion_diff = 1 - cosine(first['emotions'], second['emotions']) + FS.set_variable('EMOTIONS', emotion_diff) + + return {'score': FS.inference(['RECOMMENDATION'])}