Статистический анализ данных с помощью SKLEARN
Основная цель работы – это проведение регрессионного и корреляционного анализа на основе 10000 входных данных, которые являются файлами в формате json многоуровневой вложенности.
Для начала проведения работы понадобятся следующие импортируемые библиотеки и модули Python:
import pandas as pd
import json
import glob
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn import metrics
Для удобства дальнейшей работы объединю файлы в единый табличный формат (.csv).
Начинаю с создания класса и инициализации заранее в нём необходимых переменных:
class AnalyticsDatasets:
def __init__(self, file_name):
self.main_path = '/home/ files/'
self.analytics_path = '/home/analytics/'
self.file_name = file_name
self.main_column = 'Value'
В результате выполнения скрипта ожидаю получить файл в формате .csv, который содержит в себе 10000 строк. Добавляю метод для объединения данных в табличный формат, результат сохраняю в .csv файл:
def join_files(self, name_dir):
files = pd.DataFrame()
for file in glob.glob(self.main_path + name_dir + '/*'):
with open(file, 'r') as f:
data_out = json.loads(f.read())
outp = pd.io.json.json_normalize(data_out)
outp['file'] = file
files = files.append(outp)
files.to_csv(self.main_path + name_dir + '.csv',
encoding='utf-8', index=False)
Сформированные файлы выглядят следующим образом:
В скрипте предусмотрена многоуровневая вложенность json файлов: множественные значения преобразуются в список из значений следующего вида.
[51, 0, 0, 0] | 1 | [‘Североморск’, ‘-‘, ‘-‘, ‘-‘] | [’20’, ‘-‘, ‘-‘, ‘-‘] |
[77, 0, 0, 0] | 2 | [‘Москва’, ‘-‘, ‘-‘, ‘-‘] | [‘2,115’, ‘-‘, ‘-‘, ‘-‘] |
[77, 0, 0, 0] | 2 | [‘Москва’, ‘-‘, ‘-‘, ‘-‘] | [’89’, ‘-‘, ‘-‘, ‘-‘] |
В результате обработки скрипта формируется файл с размерностью 214 столбцов и 10000 строк.
Подготовка данных
Следующим шагом является предварительная подготовка данных для дальнейшего проведения двух видов анализа, а именно регрессионного и корреляционного анализа данных.
Для этого необходимо провести ряд этапов:
1) Разделение колонок с несколькими значениями
Списки значений в колонках не подходят для дальнейшей работы. Колонки вида списка [‘N’, ‘N’, ‘N’, ‘N’] следует разделить на несколько колонок, количество которых соответствует количеству значений в списке, например:
За разделение колонок будет отвечать следующий метод:
def split_columns(self):
df = pd.read_csv(self.main_path + 'outputs.csv', engine='python', encoding='utf-8')
names = list(df)
for item in names:
df1 = df[[item]]
df1[item] = df1[item].astype(str).str.replace(']', '').str.replace('[','').str.replace("'",'')
df2 = df1[item].str.split(',', expand=True)
for name_col in list(df2):
df2.rename(columns={name_col: item + '_' + str(name_col)}, inplace=True)
df = pd.concat([df, df2], axis=1)
df = df.drop(columns=[item])
return df
Однако, 214 столбцов при разделении образуют 3 555 новых столбцов.
2) Предварительный программный отбор столбцов.
Для начала, данные необходимо «почистить». Дописываю в скрипт следующий метод:
def cleaning_columns(self):
data = AnalyticsDatasets.split_columns(self)
data.dropna(how='all', axis=1, inplace=True)
data = data.reset_index()
columns_name = list(data)
for name in columns_name[1:]:
cl = data.groupby([name])[['index']].count()
if len(cl['index']) == 1:
data = data.drop(columns=[name])
data.to_csv(self.analytics_path + 'clean_outputs_file.csv', encoding='utf-8', index=False)
По окончанию работы скрипта формируется .csv файл, содержащий 10000 строк и 590 колонок, среди которых не осталось пустых столбцов и столбцов, в которых присутствует лишь одно значение (0, nan и т.д.), ведь это не оказывает никакого влияния на другие параметры.
Перейду к последнему этапу подготовки данных.
3) Ручной отбор столбцов и кодировка значений
Для последующего анализа подходят не все образовавшиеся 590 столбцов. Чтобы не упустить нужное, было принято решение оценить их вручную. Если категориальные текстовые данные возможно закодировать в числовые данные – кодирую, если нет – столбец отбрасывается, поскольку текстовые данные не участвуют в статистических расчётах.
В итоге, были закодированы значения из 13 столбцов, а общее количество столбцов сократилось до 383, остальные – отброшены.
Теперь с уверенностью можно сказать, что данные почищены от нежелательного «мусора» и полностью подготовлены для проведения регрессионного и корреляционного анализа.
Регрессионный анализ данных
Имеется 383 колонки в файле, что соответствует наличию 383 параметрам, возможно, влияющих на ранее выделенную переменную self.main_column = ‘Value’. Теперь из этого набора данных необходимо извлечь наиболее важные параметры.
Включаем в скрипт следующие методы:
def get_attr_and_obj(self):
data = pd.read_excel(self.file_name)
data.stack().apply(pd.to_numeric, errors='ignore').fillna(0).unstack()
data = data.replace('', 0)
data = data.fillna(0)
names_main = list(data)
X = data[names_main]
Y = data[self.main_column]
regressor = LinearRegression()
regressor.fit(X, Y)
return X, Y, regressor
def get_coef_regression(self):
X, Y, regressor = AnalyticsDatasets.get_attr_and_obj(self)
coef = pd.DataFrame(regressor.coef_, X.columns, columns=['coeff'])
coef = coef.reset_index()
coef = coef.sort_values('coeff')
res_coef = coef[(coef['coeff'] <= -0.005) | (coef['coeff'] >= 0.005)]
res_coef.to_csv(self.analytics_path + 'coef_regression.csv', index=False, encoding='utf-8')
def prediction_and_score(self):
X, Y, regressor = AnalyticsDatasets.get_attr_and_obj(self)
Y_pred = regressor.predict(X)
pred_df = pd.DataFrame({'Фактические значения': Y, 'Прогнозируемые значения': Y_pred})
pred_df.to_csv(self.analytics_path + 'prediction.csv', index=False, encoding='utf-8')
new_row = {
'R^2': regressor.score(X, Y),
'Средняя абсолютная ошибка (MAE)': metrics.mean_absolute_error(Y, Y_pred),
'Среднеквадратичная ошибка (MSE)': metrics.mean_squared_error(Y, Y_pred),
'Среднеквадратичная ошибка (RMSE)': np.sqrt(metrics.mean_squared_error(Y, Y_pred))}
with open(self.analytics_path + 'score.txt', 'w', encoding='utf-8') as f:
for key, item in new_row.items():
f.write(str(key) + ': ' + str(item) + '\n')
В результате работы скрипта формируются три файла:
- coef_regression.csv – таблица с коэффициентами регрессии.
- prediction.csv – первая таблица для оценки модели.
- score.txt – вторая таблица для оценки модели.
1) Расчёт коэффициентов регрессии — файл coef_regression.csv.
Данные имеют следующий вид:
Где в первом столбце расположены все параметры, а во втором — коэффициенты регрессии. Скрипт нам отобрал лишь те значения, которые либо меньше и равны -0.005, либо больше и равны 0.005.
Соответственно, выделен 41 параметр, которые в наибольшей степени имеют сильную взаимосвязь с исходным параметром.
2) Оценка адекватности алгоритма.
Для этого подготовлены два других файла.
А) prediction.csv – позволяет сравнить фактические выходные данные с прогнозируемыми значениями.
Получаю следующий результат:
Всего 10000 строк, соответственно, для примера выделены лишь несколько первых.
Хотя модель не очень точна, но прогнозируемые данные близки к фактическим, что говорит о адекватности данных и адекватности проведенного регрессионного анализа.
Б) score.txt — позволяет оценить производительность алгоритма.
R-квадрат, равный 0.99, говорит о том, что примерно 99% наблюдаемых вариаций могут быть объяснены входными данными модели, что показывает высокий уровень описательной способности регрессионной модели.
Корреляционный анализ данных
Как и при регрессионном анализе проверяю влияние 384 показателей из файла на выделенную ранее переменную self.main_column = ‘Value’.
Дописываю последний метод в скрипт:
def get_correlation_coef(self):
corr = pd.read_excel(self.file_name)
names_col = list(corr)
lst_colms = []
for item in names_col:
try:
corr[item] = corr[item].astype(float)
lst_colms.append(item)
except:
continue
res = corr[lst_colms]
crl = res.corr().reset_index().sort_values(self.main_column)
res = crl[['index', self.main_column]]
res.dropna(subset=[self.main_column])
result = res[(res[self.main_column] <= -0.5) | (res[self.main_column] >= 0.5)]
result.to_csv(self.analytics_path + 'coef_corr.csv', index=False, encoding='utf-8')
Результатом выполнения скрипта является файл — coef_corr.csv, содержащий в себе восемь параметров в наибольшей степени влияющих на имеющуюся переменную.
Скриптом были отобраны лишь те параметры, коэффициенты которых больше или равно 0.5, меньше или равно -0.5, что соответствует уровню средней корреляции и выше. Таковых показателей скрипт отобрал 8.
Подводя итог, можно сказать, что основная цель в посте достигнута и все поставленные задачи были выполнены в полной мере:
- Для удобства работы был сформирован сводный файл в табличном формате csv, собрав все данные из json файлов в компактном виде.
- Файл с выходными данными полностью обработан: почищен от пустых столбцов, дубликатов, выбросов, нетипичных данных, неинформативных данных.
- Проведен регрессионный и корреляционный анализ данных для выявления параметров в наибольшей степени влияющих на ранее выделенный параметр.
Количество выявленных показателей можно считать достаточным для выявления специфических особенностей.
- Регрессионный анализ выявил 41 параметр.
- Корреляционный анализ выявил 8 параметров.
Среди них четыре параметра встречаются в обоих результирующих таблицах.
Выполнение скрипта по обработке данных заняло 112 минут.
Удачи в кодинге!
https://t.me/machinelearning_interview