Магальник отчет инфа 3 сем лаба 1
.docx
ФЕДЕРАЛЬНОЕ
АГЕНСТВО ВОЗДУШНОГО ТРАНСПОРТА
(РОСАВИАЦИЯ)
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ ГРАЖДАНСКОЙ АВИАЦИИ» (МГТУ ГА)
Кафедра вычислительных машин, комплексов, сетей и систем.
Лабораторная работа защищена с оценкой ____________________
____________________
(подпись преподавателя, дата)
ЛАБОРАТОРНАЯ РАБОТА №1
по дисциплине «Методы машинного обучения и нейронные сети».
Тема: «Разработка модели на основе классического алгоритма машинного обучения»
Выполнила студентка группы ИС2-1
Магальник Екатерина Борисовна
Руководитель: Романчева Нина Ивановна
МОСКВА – 2023
Цель работы.
Изучить классический алгоритм машинного обучения и на его основе построить модель, которая осуществляет обработку файла с транзакциями и определяет, какие из них являются мошенническими, а какие нет.
Ход работы.
Листинг программы:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import RobustScaler import seaborn as sns import matplotlib.patches as mpatches import time from sklearn.model_selection import train_test_split from sklearn.model_selection import StratifiedKFold import collections from collections import Counter import warnings warnings.filterwarnings("ignore") df = pd.read_csv('creditcard.csv') df.describe() df.isnull().sum().max()
df.info()
df.columns
print('Обычные транзакции составляют', round(df['Class'].value_counts()[0]/len(df) * 100,2), '% данных') print('Мошеннические транзакции составляют', round(df['Class'].value_counts()[1]/len(df) * 100,2), '% данных') colors = ["#0101DF", "#DF0101"] sns.countplot( data=df, palette=colors) # строим гистограмму целевой переменной plt.title('Распределение классов \n (0: Не мошенник || 1: Мошенник)', fontsize=14) fig, ax = plt.subplots(1, 2, figsize=(18,4)) amount_val = df['Amount'].values time_val = df['Time'].values sns.distplot(amount_val, ax=ax[0], color='r', bins = 50) # строим график распределения суммы транзакций ax[0].set_title('Распределение сумм транзакций', fontsize=14) ax[0].set_xlim([min(amount_val), 5000]) #ax[0].set_xlim([min(amount_val), max(amount_val)]) sns.distplot(time_val, ax=ax[1], color='b') # строим график распределения времени транзакций ax[1].set_title('Распределение времени транзакций', fontsize=14) ax[1].set_xlim([min(time_val), max(time_val)]) plt.show() # Поскольку большая часть наших данных уже масштабирована, мы должны масштабировать столбцы, # которые остались (Amount и Time) rob_scaler = RobustScaler() # Менее чувствителен к выбросам, чем просто стандартизация df['scaled_amount'] = rob_scaler.fit_transform(df['Amount'].values.reshape(-1,1))# ВАШ КОД ЗДЕСЬ df['scaled_time'] = rob_scaler.fit_transform(df['Time'].values.reshape(-1,1)) # ВАШ КОД ЗДЕСЬ df.drop(['Time','Amount'], axis=1, inplace=True) scaled_amount = df['scaled_amount'] scaled_time = df['scaled_time'] df.drop(['scaled_amount', 'scaled_time'], axis=1, inplace=True) df.insert(0, 'scaled_amount', scaled_amount) df.insert(1, 'scaled_time', scaled_time) df.head() X = df.drop('Class', axis=1) y = df['Class'] skf = StratifiedKFold(n_splits=5, random_state=None, shuffle=False) # Выполним разбиение на 5 фолдов for train_index, test_index in skf.split(X, y): original_Xtrain, original_Xtest = X.iloc[train_index], X.iloc[test_index] original_ytrain, original_ytest = y.iloc[train_index], y.iloc[test_index] original_Xtrain = original_Xtrain.values original_Xtest = original_Xtest.values original_ytrain = original_ytrain.values original_ytest = original_ytest.values train_unique_label, train_counts_label = np.unique(original_ytrain, return_counts=True) test_unique_label, test_counts_label = np.unique(original_ytest, return_counts=True) print('Распределение классов: \n') print("Обучающий набор:", train_counts_label/ len(original_ytrain)) print("Тестовый набор:", test_counts_label/ len(original_ytest)) df = df.sample(frac=1) fraud_df = df.loc[df['Class'] == 1] non_fraud_df = df.loc[df['Class'] == 0][:492] # ВАШ КОД ЗДЕСЬ # берем последние 492 транзакции normal_distributed_df = pd.concat([fraud_df, non_fraud_df]) # Перемешивание строк датасета new_df = normal_distributed_df.sample(frac=1, random_state=42) print(new_df.shape) new_df.head() print('Распределение классов в подвыборке') print(new_df['Class'].value_counts()/len(new_df)) sns.countplot(data=new_df, palette=colors) # проверяем снова распределение целевой переменной plt.title('Распределение классов', fontsize=14) plt.show() f, ax = plt.subplots(1, 1, figsize=(20, 24)) # Построим матрицу корреляций sub_sample_corr = new_df.corr() sns.heatmap(sub_sample_corr, cmap = 'coolwarm_r', annot_kws={'size':20}, ax=ax)# ВАШ КОД ЗДЕСЬ ax.set_title("Матрица корреляций сбалансированной подвыборки") plt.show() # ВАШ КОД ЗДЕСЬ
Обработка данных происходит за счет ряда библиотек: numpy, pandas, matplotlib.pyplot, sklearn.preprocessing (метод RobustScaler), seaborn, matplotlib.patches, time, sklearn.model_selection (методы train_test_split, StratifiedKFold), collections (метод Counter), warnings.
Есть два варианта для подключения файла для его последующей обработки. Первый вариант:
from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive
df = pd.read_csv('/content/creditcard.csv') #https://drive.google.com/file/d/1jKkW4AFLLyn3dNeoJOxBkBAPsdeRR8xi/view?usp=sharing
#pd.read_csv('/content/drive/MyDrive/Зимняя школа 2023 Сбер/01 02 23/creditcard.csv')
df.head()
Здесь происходит загрузка данных по ссылке с Google диска. В данном случае мы не используем такое подключение, потому что эта библиотека в Python не работает. Вместо этого мы скачиваем файл из Google диска по ссылке, который называется creditcard.csv. Второй вариант:
#ЕСЛИ НЕ ПОЛУЧАЕТСЯ С ДИСКОМ
"""
# Скачаем архив с данными при помощи команды gdown (второй аргумент -- это не ссылка на файл!)
# file_id = 1jKkW4AFLLyn3dNeoJOxBkBAPsdeRR8xi
! gdown https://drive.google.com/uc?id=1jKkW4AFLLyn3dNeoJOxBkBAPsdeRR8xi
df = pd.read_csv('creditcard.csv')
"""
Далее мы проводим небольшой описательный анализ, используя функции обработки датафрейма:
df.describe()
df.isnull().sum().max()
df.info()
df.columns
Index(['Time', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6', 'V7', 'V8', 'V9', 'V10', 'V11', 'V12', 'V13', 'V14', 'V15', 'V16', 'V17', 'V18', 'V19', 'V20', 'V21', 'V22', 'V23', 'V24', 'V25', 'V26', 'V27', 'V28', 'Amount', 'Class'], dtype='object')
Далее мы рассчитываем процент обычных и мошеннических транзакций.
print('Обычные транзакции составляют', round(df['Class'].value_counts()[0]/len(df) * 100,2), '% данных')
print('Мошеннические транзакции составляют', round(df['Class'].value_counts()[1]/len(df) * 100,2), '% данных')
Обычные транзакции составляют 99.83 % данных
Мошеннические транзакции составляют 0.17 % данных
Построим график распределения классов на тестовом наборе:
colors = ["#0101DF", "#DF0101"]
sns.countplot(data=df, palette=colors) # строим гистограмму целевой переменной
plt.title('Распределение классов \n (0: Не мошенник || 1: Мошенник)', fontsize=14)
Далее строим графики распределения сумм транзакций и распределения времени транзакций:
fig, ax = plt.subplots(1, 2, figsize=(18,4))
amount_val = df['Amount'].values
time_val = df['Time'].values
sns.distplot(amount_val, ax=ax[0], color='r', bins = 50) # строим график распределения суммы транзакций
ax[0].set_title('Распределение сумм транзакций', fontsize=14)
ax[0].set_xlim([min(amount_val), 5000])
#ax[0].set_xlim([min(amount_val), max(amount_val)])
sns.distplot(time_val, ax=ax[1], color='b') # строим график распределения времени транзакций
ax[1].set_title('Распределение времени транзакций', fontsize=14)
ax[1].set_xlim([min(time_val), max(time_val)])
plt.show()
Так как нам необходимо нормализовать данные для более качественной обработки мы масштабируем столбцы Amount и Time:
rob_scaler = RobustScaler() # Менее чувствителен к выбросам, чем просто стандартизация
df['scaled_amount'] = rob_scaler.fit_transform(df['Amount'].values.reshape(-1,1))
df['scaled_time'] = rob_scaler.fit_transform(df['Time'].values.reshape(-1,1))
df.drop(['Time','Amount'], axis=1, inplace=True)
scaled_amount = df['scaled_amount']
scaled_time = df['scaled_time']
df.drop(['scaled_amount', 'scaled_time'], axis=1, inplace=True)
df.insert(0, 'scaled_amount', scaled_amount)
df.insert(1, 'scaled_time', scaled_time)
df.head()
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold
X = df.drop('Class', axis=1)
y = df['Class']
skf = StratifiedKFold(n_splits=5, random_state=None, shuffle=False)
# Выполним разбиение на 5 фолдов
for train_index, test_index in skf.split(X, y):
original_Xtrain, original_Xtest = X.iloc[train_index], X.iloc[test_index]
original_ytrain, original_ytest = y.iloc[train_index], y.iloc[test_index]
original_Xtrain = original_Xtrain.values
original_Xtest = original_Xtest.values
original_ytrain = original_ytrain.values
original_ytest = original_ytest.values
train_unique_label, train_counts_label = np.unique(original_ytrain, return_counts=True)
test_unique_label, test_counts_label = np.unique(original_ytest, return_counts=True)
print('Распределение классов: \n')
print("Обучающий набор:", train_counts_label/ len(original_ytrain))
print("Тестовый набор:", test_counts_label/ len(original_ytest))
Распределение классов:
Обучающий набор: [0.99827076 0.00172924]
Тестовый набор: [0.99827952 0.00172048]
Воспользуемся методом Random Under-Sampling. Поскольку наши классы сильно не сбалансированы, мы должны сделать их эквивалентными, чтобы получить нормальное распределение классов. Перемешаем данные перед созданием подвыборок:
df = df.sample(frac=1)
fraud_df = df.loc[df['Class'] == 1]
non_fraud_df = df.loc[df['Class'] == 0][:492] # берем последние 492 транзакции
normal_distributed_df = pd.concat([fraud_df, non_fraud_df])
# Перемешивание строк датасета
new_df = normal_distributed_df.sample(frac=1, random_state=42)
print(new_df.shape)
new_df.head()
(984, 31)
Посчитаем распределение классов в подвыборке:
print('Распределение классов в подвыборке')
print(new_df['Class'].value_counts()/len(new_df))
sns.countplot(data=new_df, palette=colors) # проверяем снова распределение целевой переменной
plt.title('Распределение классов', fontsize=14)
plt.show()
И, наконец, построим матрицу корреляции:
f, ax = plt.subplots(1, 1, figsize=(20, 24))
# Построим матрицу корреляций
sub_sample_corr = new_df.corr()
sns.heatmap(sub_sample_corr, cmap = 'coolwarm_r', annot_kws={'size':20}, ax=ax)
ax.set_title("Матрица корреляций сбалансированной подвыборки")
plt.show()
