Рубрики
Без рубрики

Create ConnectionS park & Python: MLlib Basic Statistics & Exploratory Data Analysis

В этом учебнике Spark и Python вы узнаете больше о базовой статистике MLlib и исследовательском анализе данных.

Автор оригинала: Jose A Dianes.

Инструкции

Моя серия учебников Spark & Python может быть рассмотрена индивидуально, хотя существует более или менее линейная “история”, если следовать ей последовательно. Используя один и тот же набор данных, они пытаются решить с ним связанный набор задач.

Это не единственный способ, но хороший способ следовать этим учебникам Spark-сначала клонировать репо GitHub , а затем запускать свой собственный IPython notebook в режиме PySpark . Например, если у нас есть автономная Spark установка, работающая в нашем localhost с максимальным объемом 6 Гб на узел, назначенный IPython:

MASTER="spark://127.0.0.1:7077" SPARK_EXECUTOR_MEMORY="6G" IPYTHON_OPTS="notebook --pylab inline" ~/spark-1.3.1-bin-hadoop2.6/bin/pyspark

Обратите внимание, что путь к команде pyspark будет зависеть от вашей конкретной установки. Таким образом, в качестве требования вам необходимо установить Spark на той же машине, на которой вы собираетесь запустить сервер IPython notebook .

Дополнительные параметры Spark см. в разделе здесь . В общем случае работает правило передачи опций, описанное в виде spark.executor.memory as SPARK_EXECUTOR_MEMORY при вызове IPython/PySpark.

Наборы данных

Мы будем использовать наборы данных из KDD Cup 1999 .

Рекомендации

Справочником по этим и другим темам, связанным с Spark, является Learning Spark Holden Karau, Andy Konwinski, Patrick Wendell и Matei Zaharia.

Набор данных соревнований KDD Cup 1999 подробно описан здесь .

Вступление

До сих пор мы использовали различные картографические и агрегационные функции на простых и парных Rdd ключ/значение, чтобы получить простую статистику, которая поможет нам понять наши наборы данных. В этом уроке мы познакомимся с библиотекой машинного обучения Spark MLlib через ее базовую статистическую функциональность, чтобы лучше понять наш набор данных. Мы будем использовать сокращенные 10-процентные наборы данных KDD Cup 1999 .

Получение данных и создание RDD

Как и в нашем первом блокноте, мы будем использовать сокращенный набор данных (10 процентов), предоставленный для KDD Cup 1999 , содержащий почти полмиллиона сетевых взаимодействий. Файл предоставляется в виде файла Gzip, который мы будем загружать локально.

import urllib
f = urllib.urlretrieve ("http://kdd.ics.uci.edu/databases/kddcup99/kddcup.data_10_percent.gz", "kddcup.data_10_percent.gz")


data_file = "./kddcup.data_10_percent.gz"
raw_data = sc.textFile(data_file)

Локальные Векторы

A local vector часто используется в качестве базового типа для RDDS в Spark MLlib. Локальный вектор имеет целочисленные и 0-типизированные индексы и значения двойного типа, хранящиеся на одной машине. MLlib поддерживает два типа локальных векторов: плотные и разреженные. Плотный вектор поддерживается двойным массивом, представляющим его входные значения, в то время как разреженный вектор поддерживается двумя параллельными массивами: индексами и значениями.

Для плотных векторов MLlib использует либо Python lists , либо тип NumPy /array . Рекомендуется использовать более поздний вариант, так что вы можете просто передавать массивы NumPy.

Для разреженных векторов пользователи могут построить объект Sparse Vector из MLlib или передать SciPy | scipy.sparse column vectors, если SciPy доступен в их среде. Самый простой способ создания разреженных векторов-использовать заводские методы, реализованные в Vectors .

RDD плотных векторов

Давайте представим каждое сетевое взаимодействие в нашем наборе данных в виде плотного вектора. Для этого мы будем использовать тип NumPy | array .

import numpy as np

def parse_interaction(line):
    line_split = line.split(",")
    # keep just numeric and logical values
    symbolic_indexes = [1,2,3,41]
    clean_line_split = [item for i,item in enumerate(line_split) if i not in symbolic_indexes]
    return np.array([float(x) for x in clean_line_split])

vector_data = raw_data.map(parse_interaction)

Сводная статистика

MLlib Spark предоставляет сводную статистику столбцов для RDD[Vector] через функцию colStats , доступную в Statistics . Метод возвращает экземпляр Многомерной статистической сводки , которая содержит по столбцам max , min , mean , variance и number of nonzeros , а также total count .

from pyspark.mllib.stat import Statistics 
from math import sqrt 

# Compute column summary statistics.
summary = Statistics.colStats(vector_data)

print "Duration Statistics:"
print " Mean: {}".format(round(summary.mean()[0],3))
print " St. deviation: {}".format(round(sqrt(summary.variance()[0]),3))
print " Max value: {}".format(round(summary.max()[0],3))
print " Min value: {}".format(round(summary.min()[0],3))
print " Total value count: {}".format(summary.count())
print " Number of non-zero values: {}".format(summary.numNonzeros()[0])
Duration Statistics:  
Mean: 47.979  
St. deviation: 707.746  
Max value: 58329.0  
Min value: 0.0  
Total value count: 494021  
Number of non-zero values: 12350.0  

Сводная статистика по меткам

Интересная часть сводной статистики, в нашем случае, исходит из возможности получить ее по типу сетевой атаки или “метки” в нашем наборе данных. Таким образом, мы сможем лучше охарактеризовать нашу зависимую переменную набора данных в терминах диапазона значений независимых переменных.

Если мы хотим сделать такую вещь, мы могли бы отфильтровать наш RDD, содержащий метки как ключи и векторы как значения. Для этого нам просто нужно адаптировать нашу функцию parse_interaction , чтобы вернуть кортеж с обоими элементами.

def parse_interaction_with_key(line):
    line_split = line.split(",")
    # keep just numeric and logical values
    symbolic_indexes = [1,2,3,41]
    clean_line_split = [item for i,item in enumerate(line_split) if i not in symbolic_indexes]
    return (line_split[41], np.array([float(x) for x in clean_line_split]))

label_vector_data = raw_data.map(parse_interaction_with_key)

Следующий шаг не очень сложный. Мы используем filter на RDD, чтобы исключить другие метки, кроме той, из которой мы хотим собрать статистику.

normal_label_data = label_vector_data.filter(lambda x: x[0]=="normal.")

Теперь мы можем использовать новый RDD для вызова colStats по значениям.

normal_summary = Statistics.colStats(normal_label_data.values())

И собирать результаты, как мы делали это раньше.

print "Duration Statistics for label: {}".format("normal")
print " Mean: {}".format(normal_summary.mean()[0],3)
print " St. deviation: {}".format(round(sqrt(normal_summary.variance()[0]),3))
print " Max value: {}".format(round(normal_summary.max()[0],3))
print " Min value: {}".format(round(normal_summary.min()[0],3))
print " Total value count: {}".format(normal_summary.count())
print " Number of non-zero values: {}".format(normal_summary.numNonzeros()[0])
Duration Statistics for label: normal  
Mean: 216.657322313  
St. deviation: 1359.213  
Max value: 58329.0  
Min value: 0.0  
Total value count: 97278  
Number of non-zero values: 11690.0  

Вместо того чтобы работать с парой ключ/значение, мы могли бы просто отфильтровать необработанные данные, разделенные с помощью метки в столбце 41. Затем мы можем проанализировать результаты, как мы делали это раньше. Это тоже сработает. Однако организация наших данных в виде пар ключ/значение откроет дверь для лучших манипуляций. Поскольку values() является преобразованием в RDD, а не действием, мы не выполняем никаких вычислений, пока не вызовем colStats в любом случае.

Но давайте обернем это в функцию, чтобы мы могли повторно использовать ее с любой меткой.

def summary_by_label(raw_data, label):
    label_vector_data = raw_data.map(parse_interaction_with_key).filter(lambda x: x[0]==label)
    return Statistics.colStats(label_vector_data.values())

Давайте снова попробуем использовать ярлык “нормальный”.

normal_sum = summary_by_label(raw_data, "normal.")

print "Duration Statistics for label: {}".format("normal")
print " Mean: {}".format(normal_sum.mean()[0],3)
print " St. deviation: {}".format(round(sqrt(normal_sum.variance()[0]),3))
print " Max value: {}".format(round(normal_sum.max()[0],3))
print " Min value: {}".format(round(normal_sum.min()[0],3))
print " Total value count: {}".format(normal_sum.count())
print " Number of non-zero values: {}".format(normal_sum.numNonzeros()[0])
Duration Statistics for label: normal  
Mean: 216.657322313  
St. deviation: 1359.213  
Max value: 58329.0  
Min value: 0.0  
Total value count: 97278  
Number of non-zero values: 11690.0  

Давайте попробуем теперь с какой-нибудь сетевой атакой. У нас все они перечислены здесь .

guess_passwd_summary = summary_by_label(raw_data, "guess_passwd.")

print "Duration Statistics for label: {}".format("guess_password")
print " Mean: {}".format(guess_passwd_summary.mean()[0],3)
print " St. deviation: {}".format(round(sqrt(guess_passwd_summary.variance()[0]),3))
print " Max value: {}".format(round(guess_passwd_summary.max()[0],3))
print " Min value: {}".format(round(guess_passwd_summary.min()[0],3))
print " Total value count: {}".format(guess_passwd_summary.count())
print " Number of non-zero values: {}".format(guess_passwd_summary.numNonzeros()[0])
Duration Statistics for label: guess_password  
Mean: 2.71698113208  
St. deviation: 11.88  
Max value: 60.0  
Min value: 0.0  
Total value count: 53  
Number of non-zero values: 4.0  

Мы видим, что этот тип атаки короче по продолжительности, чем обычное взаимодействие. Мы могли бы построить таблицу со статистикой продолжительности для каждого типа взаимодействия в нашем наборе данных. Сначала нам нужно получить список меток, как описано в первой строке здесь .

label_list = ["back.","buffer_overflow.","ftp_write.",
              "guess_passwd.","imap.","ipsweep.",
              "land.","loadmodule.","multihop.",
              "neptune.","nmap.","normal.","perl.",
              "phf.","pod.","portsweep.",
              "rootkit.","satan.","smurf.","spy.",
              "teardrop.","warezclient.",
              "warezmaster."]

Затем мы получаем список статистики для каждой метки.

stats_by_label = [(label, summary_by_label(raw_data, label)) for label in label_list]

Теперь мы получаем столбец duration , первый в нашем наборе данных (т. Е. индекс 0).

duration_by_label = [ 
    (stat[0], 
     np.array([
         float(stat[1].mean()[0]), 
         float(sqrt(stat[1].variance()[0])), 
         float(stat[1].min()[0]), 
         float(stat[1].max()[0]), 
         int(stat[1].count())])) 
    for stat in stats_by_label]

Это мы можем поместить в фрейм данных Панды .

import pandas as pd
pd.set_option('display.max_columns', 50)

stats_by_label_df = pd.DataFrame.from_items(duration_by_label, columns=["Mean", "Std Dev", "Min", "Max", "Count"], orient='index')

И напечатать.

print "Duration statistics, by label"
stats_by_label_df

Статистика продолжительности, по меткам

14 0 0.128915 2203 назад. 1.110062
321 0 91.700000 30 buffer_overflow. 97.514685
134 0 32.375000 8 ftp_write. 47.449033
60 0 2.716981 53 guess_passwd. 11.879811
41 0 6.000000 12 imap. 14.174240
7 0 0.034483 1247 апсвип. 0.438439
0 0 0.000000 21 земля. 0.000000
103 0 36.222222 9 loadmodule. 41.408869
718 0 184.000000 7 мультихоп. 253.851006
0 0 0.000000 107201 нептун. 0.000000
0 0 0.000000 231 нмап. 0.000000
58329 0 216.657322 97278 обычный. 1359.213469
54 25 41.333333 3 перл. 14.843629
12 0 4.500000 4 фф. 5.744563
0 0 0.000000 264 стручок. 0.000000
42448 0 1915.299038 1040 портсвип. 7285.125159
708 0 100.800000 10 руткит. 216.185003
11 0 0.040277 1589 сатана. 0.522433
0 0 0.000000 280790 смурф. 0.000000
337 299 318.000000 2 шпион. 26.870058
0 0 0.000000 979 слеза. 0.000000
15168 0 615.257843 1020 варезклиент. 2207.694966
156 0 15.050000 20 варезмастер. 33.385271

Чтобы повторно использовать этот код и получить фрейм данных из любой переменной в нашем наборе данных, мы определим функцию.

def get_variable_stats_df(stats_by_label, column_i):
    column_stats_by_label = [
        (stat[0], 
         np.array([
             float(stat[1].mean()[column_i]), 
             float(sqrt(stat[1].variance()[column_i])), 
             float(stat[1].min()[column_i]), 
             float(stat[1].max()[column_i]), 
             int(stat[1].count())])) 
        for stat in stats_by_label
    ]
    return pd.DataFrame.from_items(
        column_stats_by_label, 
        columns=["Mean", "Std Dev", "Min", "Max", "Count"], 
        orient='index')

Давайте попробуем еще раз duration .

get_variable_stats_df(stats_by_label,0)
14 0 0.128915 2203 назад. 1.110062
321 0 91.700000 30 buffer_overflow. 97.514685
134 0 32.375000 8 ftp_write. 47.449033
60 0 2.716981 53 guess_passwd. 11.879811
41 0 6.000000 12 imap. 14.174240
7 0 0.034483 1247 апсвип. 0.438439
0 0 0.000000 21 земля. 0.000000
103 0 36.222222 9 loadmodule. 41.408869
718 0 184.000000 7 мультихоп. 253.851006
0 0 0.000000 107201 нептун. 0.000000
0 0 0.000000 231 нмап. 0.000000
58329 0 216.657322 97278 обычный. 1359.213469
54 25 41.333333 3 перл. 14.843629
12 0 4.500000 4 фф. 5.744563
0 0 0.000000 264 стручок. 0.000000
42448 0 1915.299038 1040 портсвип. 7285.125159
708 0 100.800000 10 руткит. 216.185003
11 0 0.040277 1589 сатана. 0.522433
0 0 0.000000 280790 смурф. 0.000000
337 299 318.000000 2 шпион. 26.870058
0 0 0.000000 979 слеза. 0.000000
15168 0 615.257843 1020 варезклиент. 2207.694966
156 0 15.050000 20 варезмастер. 33.385271

Теперь перейдем к следующему числовому столбцу в наборе данных: src_bytes .

print "src_bytes statistics, by label"
get_variable_stats_df(stats_by_label,1)
src_bytes statistics, by label
54540 13140 54156.355878 2203 назад. 3.159360e+03
6274 0 1400.433333 30 buffer_overflow. 1.337133e+03
676 0 220.750000 8 ftp_write. 2.677476e+02
126 104 125.339623 53 guess_passwd. 3.037860e+00
1492 0 347.583333 12 imap. 6.299260e+02
18 0 10.083400 1247 апсви. 5.231658e+00
0 0 0.000000 21 земля. 0.000000e+00
302 0 151.888889 9 loadmodule. 1.277453e+02
1412 0 435.142857 7 мультихоп. 5.409604e+02
0 0 0.000000 107201 нептун. 0.000000e+00
207 0 24.116883 231 нмап. 5.941987e+01
2194619 0 1157.047524 97278 обычный. 3.422612e+04
269 260 265.666667 3 перл. 4.932883e+00
51 51 51.000000 4 фф. 0.000000e+00
1480 564 1462.651515 264 стручок. 1.250980e+02
693375640 0 666707.436538 1040 портсвип. 2.150067e+07
1727 0 294.700000 10 руткит. 5.385782e+02
1710 0 1.337319 1589 сатана. 4.294620e+01
1032 520 935.772300 280790 смурф. 2.000224e+02
237 112 174.500000 2 шпион. 8.838835e+01
28 28 28.000000 979 слеза. 0.000000e+00
5135678 30 300219.562745 1020 варезклиент. 1.200905e+06
950 0 49.300000 20 варезмастер. 2.121551e+02

И так далее. Повторно используя функции summary_by_label и get_variable_stats_df , мы можем выполнить некоторый исследовательский анализ данных в больших наборах данных с помощью Spark.

Корреляции

MLlib Spark поддерживает Pearson и Spearman для вычисления методов попарной корреляции между многими рядами. Оба они предоставляются методом corr в пакете Statistics .

У нас есть два варианта в качестве входных данных. Либо два RDD[Double] s, либо RDD[Vector] . В первом случае результатом будет значение Double , а во втором – целая корреляционная матрица. Из-за характера наших данных мы получим второе.

from pyspark.mllib.stat import Statistics 
correlation_matrix = Statistics.corr(vector_data, method="spearman")

Как только у нас будут готовы корреляции, мы сможем начать проверять их значения.

import pandas as pd
pd.set_option('display.max_columns', 50)

col_names = ["duration","src_bytes","dst_bytes",
             "land","wrong_fragment",
             "urgent","hot","num_failed_logins",
             "logged_in","num_compromised",
             "root_shell","su_attempted",
             "num_root","num_file_creations",
             "num_shells","num_access_files",
             "num_outbound_cmds",
             "is_hot_login","is_guest_login","count",
             "srv_count","serror_rate",
             "srv_serror_rate","rerror_rate",
             "srv_rerror_rate","same_srv_rate",
             "diff_srv_rate","srv_diff_host_rate",
             "dst_host_count","dst_host_srv_count",
             "dst_host_same_srv_rate","dst_host_diff_srv_rate",
             "dst_host_same_src_port_rate",
             "dst_host_srv_diff_host_rate","dst_host_serror_rate",
             "dst_host_srv_serror_rate",
             "dst_host_rerror_rate","dst_host_srv_rerror_rate"]

corr_df = pd.DataFrame(
                    correlation_matrix, 
                    index=col_names, 
                    columns=col_names)

corr_df
продолжительность 0.108639 -0.001068 -0.259032 0.017883 1.000000 0.013401 0.299189 0.159564 0.014196 -0.250139 0.008632 0.040425 -0.025936 -0.074211 -0.000010 0.026015 -0.050875 0.062291 -0.161107 0.205606 -0.008025 0.010687 -0.026420 -0.073663 0.019407 0.014363 -0.000019 -0.217167 0.061099 0.123621 -0.007759 -0.056753 0.231644 -0.211979 -0.013891 -0.057298 -0.065202 0.100692
src_bytes 0.113920 -0.009404 0.666230 0.000094 0.014196 -0.002050 -0.167931 -0.089702 1.000000 0.722609 0.014403 0.003067 -0.342180 -0.657460 0.000019 0.002282 -0.739988 0.744046 0.130377 0.027511 -0.019358 0.118562 -0.332977 -0.652391 -0.001497 -0.008396 0.000010 0.741979 0.027710 -0.104042 -0.297338 -0.645920 -0.712965 0.729151 -0.300581 -0.641792 0.815039 -0.140231
dst_bytes 0.193156 -0.003040 -0.639157 0.007234 0.299189 -0.003884 1.000000 0.882185 -0.167931 -0.497683 -0.000054 0.026054 -0.100958 -0.205848 0.000041 0.012192 -0.222572 0.229677 -0.611972 0.085947 -0.022659 0.169772 -0.081307 -0.198715 0.065776 0.021952 -0.000031 0.024124 0.034154 0.521003 -0.003042 -0.167047 -0.035073 0.055033 0.001621 -0.158378 -0.396195 0.578557
земля -0.000539 1.000000 -0.010939 -0.000065 -0.001068 -0.000230 -0.003040 -0.002785 -0.009404 -0.010128 -0.000076 -0.000093 -0.000451 0.014160 0.002089 -0.000049 -0.001846 0.002153 -0.019923 -0.000250 -0.000333 -0.000447 -0.001690 0.014342 -0.000211 -0.000076 -0.002881 -0.012341 -0.000150 0.020678 0.000389 0.013566 -0.001803 0.002576 -0.001816 0.012265 0.004265 0.016171
неправильный фрагмент -0.004042 -0.000333 -0.057711 -0.000150 -0.008025 -0.001727 -0.022659 -0.020911 -0.019358 -0.029117 -0.000507 -0.000528 0.000430 -0.008849 0.000441 -0.000248 -0.009386 0.010218 -0.029149 -0.001869 1.000000 -0.003370 -0.012676 -0.023382 -0.001519 -0.000568 -0.000147 -0.058225 -0.001160 0.012117 0.046656 0.010387 0.055542 -0.049560 -0.013666 -0.024117 -0.015449 0.007306
срочный 0.008594 -0.000065 -0.004778 1.000000 0.017883 0.061994 0.007234 0.006821 0.000094 -0.004799 -0.000066 0.067437 -0.000705 -0.001338 0.005162 0.000020 -0.001522 0.001521 -0.005894 -0.000100 -0.000150 0.031765 -0.000726 -0.001327 0.023380 0.063009 0.012879 -0.005698 0.061383 -0.000788 -0.000786 -0.001381 0.005208 -0.004078 -0.000782 -0.001370 -0.001939 -0.000976
горячий 1.000000 -0.000539 -0.120847 0.008594 0.108639 0.003096 0.193156 0.189126 0.113920 -0.114735 0.009146 0.101983 0.013468 -0.035487 -0.000248 -0.000400 -0.040555 0.041342 -0.074178 0.463706 -0.004042 0.811529 0.052003 -0.034934 0.004224 0.112560 -0.000393 -0.017960 0.028694 0.032141 0.199019 -0.004706 -0.017198 0.018783 0.189142 -0.010721 -0.086998 -0.014141
num_failed_logins 0.112560 -0.000076 -0.018024 0.063009 0.014363 0.010060 0.021952 -0.002190 -0.008396 -0.018027 -0.000093 0.016895 0.035324 -0.003674 -0.001560 0.072748 -0.005538 0.005716 -0.028369 -0.000428 -0.000568 0.004619 0.034876 -0.004027 0.005581 1.000000 0.003431 -0.015092 0.015211 -0.003096 0.032395 0.014713 -0.002960 0.003004 0.032151 0.014914 -0.006617 -0.002588
logged_in 0.189126 -0.002785 -0.578287 0.006821 0.159564 0.082533 0.882185 1.000000 -0.089702 -0.438947 0.024354 0.025293 -0.091962 -0.187114 0.000127 0.011813 -0.214019 0.216969 -0.682721 0.089318 -0.020911 0.161190 -0.072287 -0.180122 0.072698 -0.002190 0.000079 0.080352 0.055530 0.503807 0.007236 -0.143283 -0.093565 0.114526 0.012979 -0.132474 -0.359506 0.659078
num_compromised 0.811529 -0.000447 -0.097212 0.031765 0.010687 0.028557 0.169772 0.161190 0.118562 -0.091154 0.011256 0.085558 0.008573 -0.030516 -0.000438 0.048985 -0.034953 0.035253 -0.041615 -0.002504 -0.003370 1.000000 0.054006 -0.030264 0.006977 0.004619 0.001048 0.003465 0.031223 0.036497 0.214115 -0.005019 -0.039091 0.038980 0.217858 -0.004504 -0.078843 -0.020979
root_shell 0.101983 -0.000093 -0.016409 0.067437 0.040425 0.094512 0.026054 0.025293 0.003067 -0.015174 0.132056 1.000000 -0.001104 -0.004952 -0.006602 0.233486 -0.004553 0.004946 -0.021367 -0.000405 -0.000528 0.085558 -0.001143 -0.004923 0.069353 0.016895 0.011462 -0.011906 0.140650 0.002286 0.002763 -0.003498 -0.000916 0.000515 0.002151 -0.003032 -0.004617 0.008631
su_attempted -0.000400 -0.000049 -0.008279 0.000020 0.026015 0.119326 0.012192 0.011813 0.002282 -0.008225 0.040487 0.233486 -0.001227 -0.002318 0.012927 1.000000 -0.002649 0.002634 -0.006697 -0.000219 -0.000248 0.048985 -0.001253 -0.002295 0.081272 0.072748 -0.018896 -0.006288 0.053110 0.000348 0.003173 0.001974 0.006687 -0.005738 0.001731 0.002893 -0.005020 0.001052
num_root 0.003096 -0.000230 -0.054721 0.061994 0.013401 1.000000 -0.003884 0.082533 -0.002050 -0.053530 0.034405 0.094512 -0.008610 -0.016031 -0.002585 0.119326 -0.011337 0.013881 -0.078717 -0.001281 -0.001727 0.028557 -0.008708 -0.015936 0.014513 0.010060 0.001524 -0.038689 0.047521 0.006316 -0.000421 -0.008457 0.047414 -0.038935 -0.005012 -0.007096 -0.015968 0.061030
num_file_creations 0.028694 -0.000150 -0.036467 0.061383 0.061099 0.047521 0.034154 0.055530 0.027710 -0.034598 0.068660 0.140650 -0.005069 -0.009703 -0.001664 0.053110 -0.008711 0.009784 -0.049529 0.013242 -0.001160 0.031223 -0.004775 -0.010390 0.031042 0.015211 -0.004081 -0.026890 1.000000 0.014412 0.000626 -0.002257 0.027092 -0.021731 -0.001096 -0.004295 -0.015018 0.030590
num_shells 0.009146 -0.000076 -0.013938 -0.000066 0.008632 0.034405 -0.000054 0.024354 0.014403 -0.011784 1.000000 0.132056 -0.002541 -0.004343 -0.006631 0.040487 -0.003743 0.004282 -0.021200 -0.000405 -0.000507 0.011256 -0.002572 -0.004740 0.019438 -0.000093 -0.002592 -0.012017 0.068660 0.001096 -0.000617 -0.001588 0.010761 -0.009962 -0.002020 -0.002357 -0.003521 0.015882
num_access_files 0.004224 -0.000211 -0.045282 0.023380 0.019407 0.014513 0.065776 0.072698 -0.001497 -0.040497 0.019438 0.069353 -0.007581 -0.013945 -0.002850 0.081272 -0.015112 0.015499 -0.023865 0.002466 -0.001519 0.006977 0.001874 -0.013572 1.000000 0.005581 -0.001597 -0.023657 0.031042 0.024266 -0.004743 -0.011197 0.026703 -0.021358 -0.004552 -0.011487 -0.033288 0.011765
num_outbound_cmds -0.000393 -0.002881 -0.000076 0.012879 -0.000019 0.001524 -0.000031 0.000079 0.000010 0.000100 -0.002592 0.011462 0.000536 0.000167 0.822890 -0.018896 0.000328 0.000208 -0.000424 0.000924 -0.000147 0.001048 0.000346 0.000209 -0.001597 0.003431 1.000000 -0.000280 -0.004081 -0.000141 -0.000823 -0.000011 -0.000181 -0.000503 -0.001038 -0.000372 -0.000455 0.000288
is_hot_login -0.000248 0.002089 0.000036 0.005162 -0.000010 -0.002585 0.000041 0.000127 0.000019 0.000064 -0.006631 -0.006602 -0.000550 0.000102 1.000000 0.012927 -0.000235 -0.000159 -0.000106 0.001512 0.000441 -0.000438 0.000457 -0.000302 -0.002850 -0.001560 0.822890 0.000206 -0.001664 -0.000360 -0.000435 -0.000076 -0.000004 0.000229 -0.000529 -0.000007 0.000283 0.000538
is_guest_login 0.463706 -0.000250 -0.062340 -0.000100 0.205606 -0.001281 0.085947 0.089318 0.027511 -0.062713 -0.000405 -0.000405 -0.008867 -0.017343 0.001512 -0.000219 -0.017000 0.018042 -0.055453 1.000000 -0.001869 -0.002504 -0.009193 -0.017240 0.002466 -0.000428 0.000924 -0.044366 0.013242 -0.008878 0.025282 -0.001066 0.044640 -0.041749 -0.004292 -0.016885 -0.038092 -0.012578
считать -0.120847 -0.010939 1.000000 -0.004778 -0.259032 -0.054721 -0.639157 -0.578287 0.666230 0.950587 -0.013938 -0.016409 -0.213824 -0.303538 0.000036 -0.008279 -0.361737 0.346718 0.547443 -0.062340 -0.057711 -0.097212 -0.221352 -0.308923 -0.045282 -0.018024 -0.000076 0.586979 -0.036467 -0.384010 -0.261194 -0.331571 -0.546869 0.539698 -0.256176 -0.335290 0.776906 -0.496554
srv_count -0.114735 -0.010128 0.950587 -0.004799 -0.250139 -0.053530 -0.497683 -0.438947 0.722609 1.000000 -0.011784 -0.015174 -0.281468 -0.428185 0.000064 -0.008225 -0.511998 0.517227 0.442611 -0.062713 -0.029117 -0.091154 -0.284034 -0.421424 -0.040497 -0.018027 0.000100 0.720746 -0.034598 -0.239057 -0.313442 -0.449096 -0.673916 0.681955 -0.308132 -0.442823 0.812280 -0.391712
error_rate -0.035487 0.014160 -0.303538 -0.001338 -0.074211 -0.016031 -0.205848 -0.187114 -0.657460 -0.428185 -0.004343 -0.004952 -0.091157 1.000000 0.000102 -0.002318 0.828012 -0.851915 0.165350 -0.017343 -0.008849 -0.030516 -0.095285 0.990888 -0.013945 -0.003674 0.000167 -0.724317 -0.009703 -0.121489 -0.103198 0.973947 0.719708 -0.745745 -0.105434 0.965663 -0.650336 -0.153568
srv_serror_rate -0.034934 0.014342 -0.308923 -0.001327 -0.073663 -0.015936 -0.198715 -0.180122 -0.652391 -0.421424 -0.004740 -0.004923 -0.110664 0.990888 -0.000302 -0.002295 0.815305 -0.839315 0.160322 -0.017240 -0.023382 -0.030264 -0.115286 1.000000 -0.013572 -0.004027 0.000209 -0.713313 -0.010390 -0.112222 -0.122630 0.967214 0.707753 -0.734334 -0.124656 0.970617 -0.646256 -0.148072
error_rate 0.013468 -0.000451 -0.213824 -0.000705 -0.025936 -0.008610 -0.100958 -0.091962 -0.342180 -0.281468 -0.002541 -0.001104 1.000000 -0.091157 -0.000550 -0.001227 0.345571 -0.327986 -0.067857 -0.008867 0.000430 0.008573 0.978813 -0.110664 -0.007581 0.035324 0.000536 -0.330391 -0.005069 -0.017902 0.910225 -0.094076 0.308722 -0.303126 0.911622 -0.110646 -0.278465 0.073061
srv_rerror_rate 0.052003 -0.001690 -0.221352 -0.000726 -0.026420 -0.008708 -0.081307 -0.072287 -0.332977 -0.284034 -0.002572 -0.001143 0.978813 -0.095285 0.000457 -0.001253 0.333439 -0.316568 -0.072595 -0.009193 -0.012676 0.054006 1.000000 -0.115286 0.001874 0.034876 0.000346 -0.323032 -0.004775 0.011285 0.904591 -0.096146 0.300186 -0.294328 0.914904 -0.114341 -0.282239 0.075178
same_srv_rate 0.041342 0.002153 0.346718 0.001521 0.062291 0.013881 0.229677 0.216969 0.744046 0.517227 0.004282 0.004946 -0.327986 -0.851915 -0.000159 0.002634 -0.982109 1.000000 -0.190121 0.018042 0.010218 0.035253 -0.316568 -0.839315 0.015499 0.005716 0.000208 0.848754 0.009784 0.140660 -0.282487 -0.830067 -0.844537 0.873551 -0.282913 -0.819335 0.732841 0.179040
diff_srv_rate -0.040555 -0.001846 -0.361737 -0.001522 -0.050875 -0.011337 -0.222572 -0.214019 -0.739988 -0.511998 -0.003743 -0.004553 0.345571 0.828012 -0.000235 -0.002649 1.000000 -0.982109 0.185942 -0.017000 -0.009386 -0.034953 0.333439 0.815305 -0.015112 -0.005538 0.000328 -0.844028 -0.008711 -0.138293 0.299041 0.807205 0.850911 -0.868580 0.298904 0.795844 -0.727031 -0.176930
srv_diff_host_rate 0.032141 0.020678 -0.384010 -0.000788 0.123621 0.006316 0.521003 0.503807 -0.104042 -0.239057 0.001096 0.002286 -0.017902 -0.121489 -0.000360 0.000348 -0.138293 0.140660 -0.445051 -0.008878 0.012117 0.036497 0.011285 -0.112222 0.024266 -0.003096 -0.000141 0.035010 0.014412 1.000000 0.022585 -0.097973 -0.050472 0.068648 0.024722 -0.092661 -0.222707 0.433173
dst_host_count -0.074178 -0.019923 0.547443 -0.005894 -0.161107 -0.078717 -0.611972 -0.682721 0.130377 0.442611 -0.021200 -0.021367 -0.067857 0.165350 -0.000106 -0.006697 0.185942 -0.190121 1.000000 -0.055453 -0.029149 -0.041615 -0.072595 0.160322 -0.023865 -0.028369 -0.000424 0.022731 -0.049529 -0.445051 -0.125142 0.123881 0.044338 -0.070448 -0.125273 0.113845 0.189876 -0.918894
dst_host_srv_count -0.017960 -0.012341 0.586979 -0.005698 -0.217167 -0.038689 0.024124 0.080352 0.741979 0.720746 -0.012017 -0.011906 -0.330391 -0.724317 0.000206 -0.006288 -0.844028 0.848754 0.022731 -0.044366 -0.058225 0.003465 -0.323032 -0.713313 -0.023657 -0.015092 -0.000280 1.000000 -0.026890 0.035010 -0.312040 -0.722607 -0.955178 0.970072 -0.300787 -0.708392 0.769481 0.043668
dst_host_same_srv_rate 0.018783 0.002576 0.539698 -0.004078 -0.211979 -0.038935 0.055033 0.114526 0.729151 0.681955 -0.009962 0.000515 -0.303126 -0.745745 0.000229 -0.005738 -0.868580 0.873551 -0.070448 -0.041749 -0.049560 0.038980 -0.294328 -0.734334 -0.021358 0.003004 -0.000503 0.970072 -0.021731 0.068648 -0.278068 -0.742045 -0.980245 1.000000 -0.264383 -0.725272 0.771158 0.107926
dst_host_diff_srv_rate -0.017198 -0.001803 -0.546869 0.005208 0.231644 0.047414 -0.035073 -0.093565 -0.712965 -0.673916 0.010761 -0.000916 0.308722 0.719708 -0.000004 0.006687 0.850911 -0.844537 0.044338 0.044640 0.055542 -0.039091 0.300186 0.707753 0.026703 -0.002960 -0.000181 -0.955178 0.027092 -0.050472 0.287476 0.719275 1.000000 -0.980245 0.271067 0.701149 -0.766402 -0.088665
dst_host_same_src_port_rate -0.086998 0.004265 0.776906 -0.001939 -0.065202 -0.015968 -0.396195 -0.359506 0.815039 0.812280 -0.003521 -0.004617 -0.278465 -0.650336 0.000283 -0.005020 -0.727031 0.732841 0.189876 -0.038092 -0.015449 -0.078843 -0.282239 -0.646256 -0.033288 -0.006617 -0.000455 0.769481 -0.015018 -0.222707 -0.299273 -0.658737 -0.766402 0.771158 -0.297100 -0.652636 1.000000 -0.175310
dst_host_srv_diff_host_rate -0.014141 0.016171 -0.496554 -0.000976 0.100692 0.061030 0.578557 0.659078 -0.140231 -0.391712 0.015882 0.008631 0.073061 -0.153568 0.000538 0.001052 -0.176930 0.179040 -0.918894 -0.012578 0.007306 -0.020979 0.075178 -0.148072 0.011765 -0.002588 0.000288 0.043668 0.030590 0.433173 0.114971 -0.118697 -0.088665 0.107926 0.120767 -0.103715 -0.175310 1.000000
dst_host_serror_rate -0.004706 0.013566 -0.331571 -0.001381 -0.056753 -0.008457 -0.167047 -0.143283 -0.645920 -0.449096 -0.001588 -0.003498 -0.094076 0.973947 -0.000076 0.001974 0.807205 -0.830067 0.123881 -0.001066 0.010387 -0.005019 -0.096146 0.967214 -0.011197 0.014713 -0.000011 -0.722607 -0.002257 -0.097973 -0.087531 1.000000 0.719275 -0.742045 -0.096899 0.968015 -0.658737 -0.118697
dst_host_srv_serror_rate -0.010721 0.012265 -0.335290 -0.001370 -0.057298 -0.007096 -0.158378 -0.132474 -0.641792 -0.442823 -0.002357 -0.003032 -0.110646 0.965663 -0.000007 0.002893 0.795844 -0.819335 0.113845 -0.016885 -0.024117 -0.004504 -0.114341 0.970617 -0.011487 0.014914 -0.000372 -0.708392 -0.004295 -0.092661 -0.111578 0.968015 0.701149 -0.725272 -0.110532 1.000000 -0.652636 -0.103715
dst_host_rerror_rate 0.199019 0.000389 -0.261194 -0.000786 -0.007759 -0.000421 -0.003042 0.007236 -0.297338 -0.313442 -0.000617 0.002763 0.910225 -0.103198 -0.000435 0.003173 0.299041 -0.282487 -0.125142 0.025282 0.046656 0.214115 0.904591 -0.122630 -0.004743 0.032395 -0.000823 -0.312040 0.000626 0.022585 1.000000 -0.087531 0.287476 -0.278068 0.950964 -0.111578 -0.299273 0.114971
dst_host_srv_rerror_rate 0.189142 -0.001816 -0.256176 -0.000782 -0.013891 -0.005012 0.001621 0.012979 -0.300581 -0.308132 -0.002020 0.002151 0.911622 -0.105434 -0.000529 0.001731 0.298904 -0.282913 -0.125273 -0.004292 -0.013666 0.217858 0.914904 -0.124656 -0.004552 0.032151 -0.001038 -0.300787 -0.001096 0.024722 0.950964 -0.096899 0.271067 -0.264383 1.000000 -0.110532 -0.297100 0.120767

Мы использовали здесь Pandas | DataFrame для более полного отображения корреляционной матрицы. Теперь нам нужны те переменные, которые сильно коррелируют. Для этого мы немного манипулируем фреймами данных.

# get a boolean dataframe where true means that 
# a pair of variables is highly correlated
highly_correlated_df = (abs(corr_df) > .8) & (corr_df < 1.0)

# get the names of the variables so we can use 
# them to slice the dataframe
correlated_vars_index = (highly_correlated_df==True).any()
correlated_var_names = correlated_vars_index[correlated_vars_index==True].index

# slice it
highly_correlated_df.loc[correlated_var_names,correlated_var_names]
src_bytes False False False False False False False False False False False False False False False False False False False False False False False True False
dst_bytes False False False True False False False False False False False False False False False False False False False False False False False False False
горячий False False False False False False False False False False False False True False False False False False False False False False False False False
logged_in False False True False False False False False False False False False False False False False False False False False False False False False False
num_compromised True False False False False False False False False False False False False False False False False False False False False False False False False
num_outbound_cmds False False False False False False False False True False False False False False False False False False False False False False False False False
is_hot_login False False False False False False False False False False False False False False False True False False False False False False False False False
считать False False False False False True False False False False False False False False False False False False False False False False False False False
srv_count False True False False False False False False False False False False False False False False False False False False False False False True False
error_rate False False False False False False False False False True True False False False True False False False True False False False True False False
srv_serror_rate False False False False False False False True False True True False False False False False False False True False False False True False False
error_rate False False False False False False False False False False False False False True False False False True False False False True False False False
srv_rerror_rate False False False False False False True False False False False False False False False False False True False False False True False False False
same_srv_rate False False False False False False False True False True False False False False True False True False True True True False True False False
diff_srv_rate False False False False False False False True False False True False False False True False True False True True True False False False False
dst_host_count False False False False False False False False False False False False False False False False False False False False False False False False True
dst_host_srv_count False False False False False False False False False True True False False False False False False False False True True False False False False
dst_host_same_srv_rate False False False False False False False False False True True False False False False False True False False True False False False False False
dst_host_diff_srv_rate False False False False False False False False False True True False False False False False True False False False True False False False False
dst_host_same_src_port_rate False False False False True True False False False False False False False False False False False False False False False False False False False
dst_host_srv_diff_host_rate False False False False False False False False False False False True False False False False False False False False False False False False False
dst_host_serror_rate False False False False False False False True False True True False False False True False False False False False False False True False False
dst_host_srv_serror_rate False False False False False False False True False False True False False False True False False False True False False False False False False
dst_host_rerror_rate False False False False False False True False False False False False False True False False False False False False False True False False False
dst_host_srv_rerror_rate False False False False False False True False False False False False False True False False False True False False False False False False False

Выводы

Возможные Подсказки По Выбору Модели

Предыдущий фрейм данных показал нам, какие переменные сильно коррелируют. Мы сохранили только те переменные, которые имеют по крайней мере одну сильную корреляцию. Мы можем использовать, как нам заблагорассудится, но хорошим способом может быть сделать некоторый выбор модели. То есть, если у нас есть группа переменных, которые сильно коррелированы, мы можем сохранить только одну из них, чтобы представить группу в предположении, что они передают аналогичную информацию в качестве предикторов. Уменьшение числа переменных не улучшит точность нашей модели, но облегчит ее понимание и повысит эффективность вычислений.

Например, из описания задачи KDD Cup 99 мы знаем, что переменная dst_host_same_src_port_rate ссылается на процент последних 100 подключений к одному и тому же порту для одного и того же хоста назначения. В нашей корреляционной матрице (и вспомогательных фреймах данных) мы находим, что эта матрица сильно и положительно коррелирует с src_bytes и srv_count . Первый-это количество байтов, отправленных от источника к месту назначения. Позднее-это количество подключений к той же службе, что и текущее соединение за последние 2 секунды. Мы могли бы решить не включать dst_host_same_src_port_rate в нашу модель, если мы включим два других, как способ уменьшить количество переменных и позже лучше интерпретировать наши модели.

Позже, в тех тетрадях, которые посвящены построению прогнозных моделей, мы будем использовать эту информацию для построения более интерпретируемых моделей.