167 KiB
games.csv - датасет игр из steam
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.read_csv("..//static//csv//games.csv")
Входные переменные: user_reviews (кол-во отзывов игроков; reviews в коде), price_original (цена на момент выхода; price в коде)
Выходная перменная: positive_ratio (отношение положительных отзывов к негативным; pos в коде)
from datetime import datetime as dt
from datetime import timedelta
import matplotlib.pyplot as plt
from skfuzzy import control as ctrl
import skfuzzy as fuzz
#входная переменная кол-ва отзывов с таким универсумом (от 0 до 100k)
reviews = ctrl.Antecedent(np.arange(0, 100000, 1), "reviews")
#входная переменная цены с таким универсумом (от 0 до 100 долларов)
price = ctrl.Antecedent(np.arange(0, 100, 0.01), "price")
#удалить пару игр, у которых цена больше 100 долларов, чтобы графики норм. были
df = df[df['price_original'] <= 100]
#удалить несколько игр, у которых больше 100k отзывов, чтобы графики норм. были
df = df[df['user_reviews'] <= 100000]
#выходная переменная позитивности с таким универсумом (от 0 до 100)
pos = ctrl.Consequent(np.arange(0, 100, 1), "pos")
Лингвистические переменные и их визуализация¶
#ЛИНГВИСТИЧЕСКАЯ ПЕР. КОЛ-ВО ОТЗЫВОВ
#автоматическое формирование нечёт. переменной отзывов, но с поправкой для many (s - ф-ия)
reviews.automf(3, variable_type="quant", names=['few', 'avg', 'many'])
reviews["few"] = fuzz.zmf(reviews.universe, 0, 10000)
reviews["many"] = fuzz.smf(reviews.universe, reviews.universe.max()/2, reviews.universe.max())
reviews.view()
#ЛИНГВИСТИЧЕСКАЯ ПЕР. ЦЕНА
#От 0 до 12 долларов можно считать дёшево (переводил на рубли)
#z-функция
price["cheap"] = fuzz.zmf(price.universe, 0, 12)
#от 5 до 22 долларов можно считать средне (переводил на рубли)
#треуг. ф-ия
# 5 - левая вершина треугольника
# 15 - верхняя вершина
# 22 - правая вершина
price["medium"] = fuzz.trimf(price.universe, [5, 16, 22])
#больше 15 долларов можно считать дорого (переводил на рубли)
#s-функция
price["expensive"] = fuzz.smf(price.universe, 15, price.universe.max())
price.view()
#ЛИНГВИСТИЧЕСКАЯ ПЕР. СООТНОШЕНИЕ ПОЛОЖ./НЕГАТИВ. ОТЗЫВОВ
pos.automf(5, variable_type="quant")
pos.view()
База нечётких правил¶
rule1 = ctrl.Rule(reviews['many'] & price['cheap'], pos['high'])
rule2 = ctrl.Rule(reviews['many'] & price['medium'], pos['high'])
rule3 = ctrl.Rule(reviews['many'] & price['expensive'], pos['high'])
rule4 = ctrl.Rule(reviews['few'] & price['cheap'], pos['high'])
rule5 = ctrl.Rule(reviews['few'] & price['medium'], pos['higher'])
rule6 = ctrl.Rule(reviews['few'] & price['expensive'], pos['average'])
rule7 = ctrl.Rule(reviews['avg'] & price['cheap'], pos['average'])
rule8 = ctrl.Rule(reviews['avg'] & price['medium'], pos['high'])
rule9 = ctrl.Rule(reviews['avg'] & price['expensive'], pos['average'])
fuzzy_rules = [
rule1,
rule2,
rule3,
rule4,
rule5,
rule6,
rule7,
rule8,
rule9
]
fuzzy_sys = ctrl.ControlSystemSimulation(ctrl.ControlSystem(fuzzy_rules))
def fuzzy_pred(row):
fuzzy_sys.input["reviews"] = row["user_reviews"]
fuzzy_sys.input["price"] = row["price_original"]
fuzzy_sys.compute()
return fuzzy_sys.output["pos"]
from sklearn.model_selection import train_test_split
#Тестирование нечеткой системы на тестовой выборке
# Разделение данных на обучающую и тестовую выборки
X = df[['user_reviews', 'price_original']]
y = df['positive_ratio']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
test = pd.concat([X_test, y_test], axis=1)
print(test)
result_test = test.copy()
result_test["positive_ratio_pred"] = result_test.apply(fuzzy_pred, axis=1)
result_test
#Оценка
import math
from sklearn import metrics
print(f"R^2 = {metrics.r2_score(test["positive_ratio"], result_test["positive_ratio_pred"])}")
print(f"RMSE = {math.sqrt(
metrics.mean_squared_error(test["positive_ratio"], result_test["positive_ratio_pred"])
)}")
Оценки показали, что построенная нечёткая система плохо справляется с предсказанием соотношения положительных отзывов к негативным.
Средняя квадратичная ошибка составляет примерно 20%, что является достаточно большой ошибкой для диапазона от 0 до 100.
Коэффициент детерминации получился отрицательным. Это означает, что система работает хуже, чем простое предсказание средним значением. Это говорит о том, что гипотезы о зависимости положительности отзывов от цены игры и количества отзывов, проявляемые в виде базы нечётких правил, неправильно отражают действительность.
Возможно, что распределение отношений положительных отзывов к отрицательным имеет скорее случайный характер, поэтому оно не может быть описано с хорошей точностью нечёткими правилами
P.S. Было сделано более 5 попыток улучшить показатели засчёт изменения графиков функций и правил, но коэф. детерминации каждый раз всё равно был отрицательным (ещё больше по модулю, чем в данный момент)