AIM-PIbd-32-Petrushin-E-A/lab_2/lab2.ipynb
GokaPek e815e7ec87 2
2024-09-29 13:00:33 +04:00

180 KiB
Raw Blame History

Выгрузка в датафрейм первый набор (игры в Steam)

https://www.kaggle.com/datasets/wajihulhassan369/steam-games-dataset. Набор представляет собой данные об экшенах, доступных в Steam. Эта информация полезна для изучения игровых паттернов, моделирования цен и исследования корреляции между игровыми тегами и методами ценообразования. Этот набор позволяет провести предварительный анализ данных, построить модели машинного обучения или исследовать игровую индустрию. В наборе пресдтавлена дата, различные теги, рейтинг отзывов. Так можно понять, какие теги популярнее, что в играх людям нравится больше, изменилось ли качество игр со временем и т.д. Для бизнеса такой набор данных может быть полезен для прогнозирования, в разработку каки игр целесообразнее вкладываться. Так компания не потеряет деньги. Пример цели: Разработка игры на пк в нужную фазу рынка Входные данные: год выпуска, сумма продаж Целевой признак: продаваемость игр в текущей фазе рынка в сравнении с предыдущими.

In [31]:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv(".//static//csv//steam_cleaned.csv")
print(df.columns)
Index(['Name', 'Price', 'Release_date', 'Review_no', 'Review_type', 'Tags',
       'Description'],
      dtype='object')
In [32]:
# Преобразуем дату выпуска в формат datetime
df['Release_date'] = pd.to_datetime(df['Release_date'])

# Визуализация данных
plt.figure(figsize=(10, 6))
plt.scatter(df['Release_date'], df['Review_no'])
plt.xlabel('Release Date')
plt.ylabel('Review Number')
plt.title('Scatter Plot of Review Number vs Release Date')
plt.show()
No description has been provided for this image

При проверке на шум можно заметить выброс в 2014 году. количество обзоров там запредельное.

Все выбросы удалены путём определения порогов квантилями. Зашумленность не очень высокая. Покрытие данных высокое и подошло бы для поставленной задачи по актуальности.

In [34]:
# Преобразуем дату выпуска в формат datetime
df['Release_date'] = pd.to_datetime(df['Release_date'])

# Статистический анализ для определения выбросов
Q1 = df['Review_no'].quantile(0.25)
Q3 = df['Review_no'].quantile(0.75)
IQR = Q3 - Q1

# Определение порога для выбросов
threshold = 1.5 * IQR
outliers = (df['Review_no'] < (Q1 - threshold)) | (df['Review_no'] > (Q3 + threshold))

# Вывод выбросов
print("Выбросы:")
print(df[outliers])

# Обработка выбросов
# В данном случае мы заменим выбросы на медианное значение
median_review_no = df['Review_no'].median()
df.loc[outliers, 'Review_no'] = median_review_no

# Визуализация данных после обработки
plt.figure(figsize=(10, 6))
plt.scatter(df['Release_date'], df['Review_no'])
plt.xlabel('Release Date')
plt.ylabel('Review Number')
plt.title('Scatter Plot of Review Number vs Release Date (After Handling Outliers)')
plt.show()
Выбросы:
                                   Name  Price Release_date  Review_no  \
18                     GUNDAM BREAKER 4  59.99   2024-08-29     1846.0   
22                    LOCKDOWN Protocol   5.49   2024-07-22     2192.0   
34                          CarX Street  19.99   2024-08-29     4166.0   
45    Harry Potter: Quidditch Champions  25.99   2024-09-03     1216.0   
61                              SMITE 2  18.00   2024-08-27     1633.0   
...                                 ...    ...          ...        ...   
7695                   Dude Simulator 2   2.99   2018-07-28     1734.0   
7717     Golfing Over It with Alva Majo   2.39   2018-03-28     1367.0   
7740                   Dungeon Siege II   4.99   2005-08-16     2274.0   
7765                   Phantom Doctrine  12.99   2018-08-14     3538.0   
7768         NECROPOLIS: BRUTAL EDITION  19.99   2016-07-12     3668.0   

          Review_type                                               Tags  \
18      Very Positive  Action,Robots,Hack and Slash,RPG,Mechs,Action ...   
22      Very Positive  Multiplayer,Social Deduction,Conversation,Acti...   
34              Mixed  Racing,Open World,Automobile Sim,PvP,Multiplay...   
45    Mostly Positive  Action,Sports,Flight,Arcade,Third Person,Magic...   
61              Mixed  Action,MOBA,Third Person,Strategy,Adventure,Ca...   
...               ...                                                ...   
7695            Mixed  Life Sim,Indie,Simulation,Racing,Action,Advent...   
7717  Mostly Positive  Difficult,Physics,Golf,Platformer,Precision Pl...   
7740  Mostly Positive  RPG,Fantasy,Action RPG,Hack and Slash,Singlepl...   
7765  Mostly Positive  Turn-Based Tactics,Strategy,Cold War,Stealth,R...   
7768            Mixed  Souls-like,Action Roguelike,Co-op,Adventure,Ro...   

                                            Description  
18    Create your own ultimate Gundam in the newest ...  
22    A first person social deduction game, combinin...  
34    Conquer mountain roads, highways, and city str...  
45    Your next chapter takes flight! Immerse yourse...  
61    Become a god and wage war in SMITE 2, the Unre...  
...                                                 ...  
7695  Dude Simulator 2 is an open world sandbox game...  
7717         The higher you climb, the bigger the fall.  
7740                                                NaN  
7765  The year is 1983. The world teeters on the ver...  
7768  NECROPOLIS: BRUTAL EDITION is a major update f...  

[1049 rows x 7 columns]
No description has been provided for this image

Очистим от строк с пустыми значениями наш датасет

In [37]:
# Удаление строк с пропущенными значениями
df_dropna = df.dropna()

# Вывод количества удаленных строк
num_deleted_rows = len(df) - len(df_dropna)
print(f"\nКоличество удаленных строк: {num_deleted_rows}")

print("\nDataFrame после удаления строк с пропущенными значениями:")
print(df_dropna)
Количество удаленных строк: 515

DataFrame после удаления строк с пропущенными значениями:
                                                   Name  Price Release_date  \
0                                    Black Myth: Wukong  59.99   2024-08-20   
2                                      Counter-Strike 2   0.00   2012-08-21   
4                                    Grand Theft Auto V  10.48   2015-04-14   
5                                 Red Dead Redemption 2  17.99   2019-12-05   
6                                   PUBG: BATTLEGROUNDS   0.00   2017-12-21   
...                                                 ...    ...          ...   
7807  Monster Hunter World: Iceborne - MHW:I Monster...   2.99   2020-02-06   
7808                    Gene Shift Auto: Deluxe Edition   8.99   2022-11-28   
7809                                      Run Ralph Run   0.45   2021-03-03   
7810                                          Quadroids   6.19   2024-02-22   
7811                                           Divekick   4.99   2013-08-20   

      Review_no              Review_type  \
0         270.0  Overwhelmingly Positive   
2         270.0            Very Positive   
4         270.0            Very Positive   
5         270.0            Very Positive   
6         270.0                    Mixed   
...         ...                      ...   
7807       39.0                 Positive   
7808       16.0                 Positive   
7809       26.0          Mostly Positive   
7810       15.0                 Positive   
7811     1118.0            Very Positive   

                                                   Tags  \
0     Mythology,Action RPG,Action,Souls-like,RPG,Com...   
2     FPS,Shooter,Multiplayer,Competitive,Action,Tea...   
4     Open World,Action,Multiplayer,Crime,Automobile...   
5     Open World,Story Rich,Western,Adventure,Multip...   
6     Survival,Shooter,Battle Royale,Multiplayer,FPS...   
...                                                 ...   
7807                                             Action   
7808  Indie,Action,Free to Play,Battle Royale,Roguel...   
7809  Adventure,Action,Puzzle,Arcade,Platformer,Shoo...   
7810  Precision Platformer,Puzzle Platformer,2D Plat...   
7811  Fighting,Indie,2D Fighter,Parody ,Local Multip...   

                                            Description  
0     Black Myth: Wukong is an action RPG rooted in ...  
2     For over two decades, Counter-Strike has offer...  
4     Grand Theft Auto V for PC offers players the o...  
5     Winner of over 175 Game of the Year Awards and...  
6     Play PUBG: BATTLEGROUNDS for free.\n\nLand on ...  
...                                                 ...  
7807  A monster figure you can use to decorate your ...  
7808  Gene Shift Auto is a roguelike-inspired battle...  
7809    Ralph is a smart dinosaur, and a great shooter.  
7810  Quadroids is a single-player puzzle platformer...  
7811  Divekick is the worlds first two-button fight...  

[7297 rows x 7 columns]

Теперь создадим выборки.

In [2]:
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv(".//static//csv//steam_cleaned.csv")

train_df, temp_df = train_test_split(df, test_size=0.4, random_state=42)

# Разделение остатка на контрольную и тестовую выборки
val_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42)

# Проверка размеров выборок
print("Размер обучающей выборки:", len(train_df))
print("Размер контрольной выборки:", len(val_df))
print("Размер тестовой выборки:", len(test_df))

# Сохранение выборок в файлы (опционально)
train_df.to_csv(".//static//csv//train_data.csv", index=False)
val_df.to_csv(".//static//csv//val_data.csv", index=False)
test_df.to_csv(".//static//csv//test_data.csv", index=False)
Размер обучающей выборки: 4687
Размер контрольной выборки: 1562
Размер тестовой выборки: 1563

Проанализируем сбалансированность выборок

In [5]:
train_df = pd.read_csv(".//static//csv//train_data.csv")
val_df = pd.read_csv(".//static//csv//val_data.csv")
test_df = pd.read_csv(".//static//csv//test_data.csv")

# Оценка сбалансированности
def check_balance(df, name):
    counts = df['Review_type'].value_counts()
    print(f"Распределение Review_type в {name}:")
    print(counts)
    print(f"Процент положительных отзывов: {counts['Mostly Positive'] / len(df) * 100:.2f}%")
    print(f"Процент отрицательных отзывов: {counts['Overwhelmingly Positive'] / len(df) * 100:.2f}%")
    print()

# Определение необходимости аугментации данных
def need_augmentation(df):
    counts = df['Review_type'].value_counts()
    ratio = counts['Mostly Positive'] / counts['Overwhelmingly Positive']
    if ratio > 1.5 or ratio < 0.67:
        print("Необходима аугментация данных для балансировки классов.")
    else:
        print("Аугментация данных не требуется.")
        
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")



need_augmentation(train_df)
need_augmentation(val_df)
need_augmentation(test_df)
Распределение Review_type в обучающей выборке:
Review_type
Very Positive              2117
Mostly Positive             810
Mixed                       797
Positive                    710
Overwhelmingly Positive     209
Mostly Negative              15
Very Negative                 2
Overwhelmingly Negative       1
Name: count, dtype: int64
Процент положительных отзывов: 17.28%
Процент отрицательных отзывов: 4.46%

Распределение Review_type в контрольной выборке:
Review_type
Very Positive              708
Mostly Positive            290
Mixed                      241
Positive                   224
Overwhelmingly Positive     78
Mostly Negative              6
Very Negative                2
Name: count, dtype: int64
Процент положительных отзывов: 18.57%
Процент отрицательных отзывов: 4.99%

Распределение Review_type в тестовой выборке:
Review_type
Very Positive              713
Mostly Positive            276
Mixed                      253
Positive                   240
Overwhelmingly Positive     67
Mostly Negative              5
Very Negative                1
Name: count, dtype: int64
Процент положительных отзывов: 17.66%
Процент отрицательных отзывов: 4.29%

Необходима аугментация данных для балансировки классов.
Необходима аугментация данных для балансировки классов.
Необходима аугментация данных для балансировки классов.

По результатам анализа требуется приращение, соотношения отзывов вне допустимого диапазона

In [19]:
import pandas as pd
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
from sklearn.preprocessing import LabelEncoder

# Загрузка данных
train_df = pd.read_csv(".//static//csv//train_data.csv")
val_df = pd.read_csv(".//static//csv//val_data.csv")
test_df = pd.read_csv(".//static//csv//test_data.csv")

# Преобразование категориальных признаков в числовые
def encode(df):
    label_encoders = {}
    for column in df.select_dtypes(include=['object']).columns:
        if column != 'Review_type':  # Пропускаем целевую переменную
            le = LabelEncoder()
            df[column] = le.fit_transform(df[column])
            label_encoders[column] = le
    return label_encoders

# Преобразование целевой переменной в числовые значения
def encode_target(df):
    le = LabelEncoder()
    df['Review_type'] = le.fit_transform(df['Review_type'])
    return le

# Применение кодирования
label_encoders = encode(train_df)
encode(val_df)
encode(test_df)

# Кодирование целевой переменной
le_target = encode_target(train_df)
encode_target(val_df)
encode_target(test_df)

# Проверка типов данных
def check_data_types(df):
    for column in df.columns:
        if df[column].dtype == 'object':
            print(f"Столбец '{column}' содержит строковые данные.")

check_data_types(train_df)
check_data_types(val_df)
check_data_types(test_df)

# Функция для выполнения oversampling
def oversample(df):
    if 'Review_type' not in df.columns:
        print("Столбец 'Review_type' отсутствует.")
        return df
    
    X = df.drop('Review_type', axis=1)
    y = df['Review_type']
    
    oversampler = RandomOverSampler(random_state=42)
    X_resampled, y_resampled = oversampler.fit_resample(X, y)
    
    resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
    return resampled_df

# Функция для выполнения undersampling
def undersample(df):
    if 'Review_type' not in df.columns:
        print("Столбец 'Review_type' отсутствует.")
        return df
    
    X = df.drop('Review_type', axis=1)
    y = df['Review_type']
    
    undersampler = RandomUnderSampler(random_state=42)
    X_resampled, y_resampled = undersampler.fit_resample(X, y)
    
    resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
    return resampled_df

# Применение oversampling и undersampling к каждой выборке
train_df_oversampled = oversample(train_df)
val_df_oversampled = oversample(val_df)
test_df_oversampled = oversample(test_df)

train_df_undersampled = undersample(train_df)
val_df_undersampled = undersample(val_df)
test_df_undersampled = undersample(test_df)

# Обратное преобразование целевой переменной в строковые метки
def decode_target(df, le_target):
    df['Review_type'] = le_target.inverse_transform(df['Review_type'])

decode_target(train_df_oversampled, le_target)
decode_target(val_df_oversampled, le_target)
decode_target(test_df_oversampled, le_target)

decode_target(train_df_undersampled, le_target)
decode_target(val_df_undersampled, le_target)
decode_target(test_df_undersampled, le_target)

# Проверка результатов
def check_balance(df, name):
    if 'Review_type' not in df.columns:
        print(f"Столбец 'Review_type' отсутствует в {name}.")
        return
    
    counts = df['Review_type'].value_counts()
    print(f"Распределение Review_type в {name}:")
    print(counts)
    
    if 'Positive' in counts and 'Negative' in counts:
        print(f"Процент положительных отзывов: {counts['Positive'] / len(df) * 100:.2f}%")
        print(f"Процент отрицательных отзывов: {counts['Negative'] / len(df) * 100:.2f}%")
    else:
        print("Отсутствуют один или оба класса (Positive/Negative).")
    print()

# Проверка сбалансированности после oversampling
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")

# Проверка сбалансированности после undersampling
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")
Оверсэмплинг:
Распределение Review_type в обучающей выборке:
Review_type
Mostly Positive            2117
Mixed                      2117
Very Positive              2117
Positive                   2117
Overwhelmingly Positive    2117
Mostly Negative            2117
Very Negative              2117
Overwhelmingly Negative    2117
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

Распределение Review_type в контрольной выборке:
Review_type
Very Negative              708
Mostly Positive            708
Mixed                      708
Overwhelmingly Positive    708
Overwhelmingly Negative    708
Positive                   708
Mostly Negative            708
Very Positive              708
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

Распределение Review_type в тестовой выборке:
Review_type
Very Negative              713
Mostly Positive            713
Overwhelmingly Positive    713
Mixed                      713
Overwhelmingly Negative    713
Very Positive              713
Mostly Negative            713
Positive                   713
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

Андерсэмплинг:
Распределение Review_type в обучающей выборке:
Review_type
Mixed                      1
Mostly Negative            1
Mostly Positive            1
Overwhelmingly Negative    1
Overwhelmingly Positive    1
Positive                   1
Very Negative              1
Very Positive              1
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

Распределение Review_type в контрольной выборке:
Review_type
Mixed                      2
Mostly Negative            2
Mostly Positive            2
Overwhelmingly Negative    2
Overwhelmingly Positive    2
Positive                   2
Very Negative              2
Very Positive              2
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

Распределение Review_type в тестовой выборке:
Review_type
Mixed                      1
Mostly Negative            1
Mostly Positive            1
Overwhelmingly Negative    1
Overwhelmingly Positive    1
Positive                   1
Very Negative              1
Very Positive              1
Name: count, dtype: int64
Отсутствуют один или оба класса (Positive/Negative).

14,400 Classic Rock Tracks (with Spotify Data)

https://www.kaggle.com/datasets/thebumpkin/14400-classic-rock-tracks-with-spotify-data Этот набор данных, содержащий 1200 уникальных альбомов и 14 400 треков, представляет собой не просто коллекцию — это хроника эволюции классического рока. Каждый трек тщательно каталогизирован с 18 столбцами данных, включая ключевые метаданные, такие как название трека, исполнитель, альбом и год выпуска, наряду с функциями Spotify audio, которые позволяют получить представление о звуковом ландшафте этих неподвластных времени мелодий. Бизнес-цель может заключаться в улучшении стратегии маркетинга и продвижения музыкальных треков. Предположим как этот набор может быть полезен для бизнеса: Персонализированные рекомендации: Создание алгоритмов, которые будут рекомендовать пользователям музыку на основе их предпочтений. Цель технического проекта: Разработать и внедрить систему рекомендаций, которая будет предсказывать и рекомендовать пользователям музыкальные треки на основе их предпочтений и поведения. Входные данные: Данные о пользователях: Идентификатор пользователя, история прослушиваний, оценки треков, время прослушивания, частота прослушивания. Данные о треках: Атрибуты треков (название, исполнитель, альбом, год, длительность, танцевальность, энергичность, акустичность и т.д.). Данные о взаимодействии: Время и частота взаимодействия пользователя с определенными треками. Целевой признак: Рекомендации: Булева переменная, указывающая, должен ли конкретный трек быть рекомендован пользователю (1 - рекомендуется, 0 - не рекомендуется).

In [20]:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv(".//static//csv//UltimateClassicRock.csv")
print(df.columns)
Index(['Track', 'Artist', 'Album', 'Year', 'Duration', 'Time_Signature',
       'Danceability', 'Energy', 'Key', 'Loudness', 'Mode', 'Speechiness',
       'Acousticness', 'Instrumentalness', 'Liveness', 'Valence', 'Tempo',
       'Popularity'],
      dtype='object')