Chapter 4 - Data Loading and Pre-processing(Sample)
Copyright and License
Copyright © by Ricardo A. Calix.
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, without written permission of the copyright owner.
MIT License.
FTC and Amazon Disclaimer
This post/page/article includes Amazon Affiliate links to products. This site receives income if you purchase through these links.
This income helps support content such as this one.
Data Loading and Pre-processing
In this chapter, I will address the very important issue of dealing with the data. To me and most practitioners, data processing is the most important issue
in machine learning.
There are many aspects that must be addressed when dealing with data. These include:
- getting the data
- cleaning the data
- pre-processing the data
- extracting the features
- building a corpus and annotating it
- performing inter-annotator agreement
- etc.
Here in this chapter I will address general issues about data as well as data issues related to cyber security and machine learning such
as one-hot encoding and feature extraction.
Loading the Data
Data can be obtained from the web such as text from twitter or web pages. Specific data sets can also be obtained from the machine learning libraries.
Sklearn has a “dataset” module, for instance. This dataset module can be used to obtain certain data sets such as the Iris dataset. An example of
this code can be seen below.
Here, the first index in the data matrix represents the rows and the second index represents the columns. Data can also be obtained from text files.
Many practitioners and academics will have their own data in text files. This data can be formatted in many different ways and loaded into the code.
In most of the examples in this book, the data is assumed to be formatted in csv (comma separated) format.
The code to load the data to both SKlearn based traditional machine learning algorithms and to PyTorch code files is shown below. In the code, we can see that
we can use the Numpy library (or namespace) to obtain the data. For the example below we assume that the data is stored in
the file \textbf{data/12559_Training_Dataset.csv} and is read by loadtxt() into the python variable \textbf{Matrix_data}.
Since we are using csv format, the Iris data file can look like the following.
Once the data is in \textbf{Matrix_data}, it can be processed as a Numpy array matrix. This means that it is no longer just an array but instead it
is more a vector or matrix as in linear algebra. Many operations are now simplified like extracting certain columns or rows. This is usually referred
to as slicing.
In the previous code listing we can see that we can calculate the dimensions of the matrix as follows:
And this gives you the number of columns or number of features plus the class.
Data and Feature Pre-Processing
Feature scaling is very important to achieving good results in ML modeling tasks. For example, in Principal Component Analysis (PCA) which is a feature reduction
technique, feature scaling is very important. The purpose of PCA is to project data to a space that captures the most variability in the data. If the features
are not scaled properly, one feature could dominate over the others and therefore be considered as the most variable feature.
With feature scaling, features with real valued numbers from any range can be mapped to other ranges such as from -1.0 to 1.0. This is performed for all features
so that no one feature will dominate in the model.
All machine learning models are susceptible to feature scaling. The code below shows how the data can be scaled from \textbf{X_train} to \textbf{X_train_normalized}.
CSV Files
In the following code listing I am showing you a general way in which you can take a standard dataset such as Iris or mnist obtained from a library module
and save it to a csv file.
This approach allows you to do the machine learning modeling by reading data from text files where the data is formatted in a very standard and well known
format such as csv (comma separated format).
One Hot Encoding
ML algorithm implementations in PyTorch use one-hot encoding. Quite simply, one hot encoding means that you take labels in the following format.
and convert them to labels in the equivalent one-hot encoded format as shown below. So, we create new vectors where all values are zero except for the
value of the position corresponding to the correct class in the vector.
One-hot encoding transforms the labels vector (\textbf{y}) of size \textbf{n} into a matrix of size \textbf{n} by \textbf{B} where \textbf{B} represents the number
of classes in the data set. For the case of the Iris dataset, we have 3 classes and, therefore, for a sample with label 2 we would get an equivalent one-hot
encoded vector equal to [0,0,1].
The code to convert the data to one-hot encoded format is provided below. There are several ways of implementing one-hot encoding. I have used the approach below
because I think it is the easiest to understand (while possibly not the most efficient or pythony).
Notice how \textbf{“a”} is a 2-dimensional array initialized with all zeros. You use the value in the input vector data to determine the
indeces \textbf{i} and \textbf{j} that are used to assign a "1" to the correct position in the matrix.
Features
A machine learning (ML) algorithm is only as good as the features that are provided to it. This statement used to be very true and many people made careers
of just developing features for problems in different domains. For instance, in NLP, many people would spend a lot of time developing parsers and other
techniques to find and create features from a text input. Similarly, in image processing, researchers developed many techniques to filter data out of images
to perform efficient image classification. Today, deep learning has somewhat changed this. DL has managed to introduce approaches to decrease the amount of
human involvement in the feature extraction process. Basically, deep learning (DL) methods, in some cases, have the ability to extract features from
raw data using only un-supervised or self-supervised techniques, transfer learning, etc. In some way, you can say that deep learning algorithms can extract
the features themselves without human involvement. This ability has had a very strong impact on the performance of the algorithms implemented in industry
and in the work performed by machine learning specialists. These abilities, for enhanced feature extraction, are available for the main ML mediums such as
for text processing and for image processing. I think they are less developed in the medium of Cyber Security.
In this section, I will cover ways of extracting features to address problems such as: malware detection, network intrusion detection, phishing detection, etc.
In general, we need techniques to extract data from cyber security related sources that we can convert to vector space model formats for use in machine
learning algorithms. The vector space model format is simply a comma separate file (CSV) where each column(F1, F2, F3, ...) maps to an axis in a vector
space (X, Y, Z, ...).
The columns are the axes on the vector space. An N number of columns corresponds to an N number of axes in the vector space ($R^N$).
Sniffing and Spoofing
When it comes to network data, sniffing and spoofing can be considered the two main approaches for network data processing and manipulation.
Sniffing can be more directly linked to defense and analysis, whereas spoofing can be more directly linked to attacks.
Sniffing
Sniffing is the process of capturing packets and extracting data from them. The following code listing shows an example of this using Scapy
(a Python library). You need to have root privileges on the computer to be able to sniff packets.
The code uses "sniff" with a filter to capture and print "icmp" packets.
Spoofing
Spoofing is the process of creating or modifying packets. Any packet that is arbitrarily modified by a user or agent can be used in an attack.
You need to have root privileges on the computer to be able to spoof packets.
The next code listing shows an example of how to spoof packets. Here we generate and send 10 ping packets to the address 8.8.8.8.
In the next code listing we can further modify the ping packets to carry a text message. Consider that here we have a delivery mechanism and think
of the text message as an actual payload that could be malicious.
The possibilities with Scapy are endless. For instance, here we can create a very simple script to simulate the "traceroute" functionality.
Features from Network Data
Sniffing is the process of collecting data from network packets. The Python Scapy library is great for this. In the next code listing
we see an example of how to collect network packet data from ping (icmp) packets using Scapy. The function "sniff" has a filter option to specify
what kinds of packets to collect (e.g. icmp, http, sport=80, etc.).
The results of running the sniffer can be seen in the following figure.
Example to extract features from PCAP files
A PCAP file is a type of file used to store collected network data. For this example, for instance, we collected data from an IOT
(Internet Of Things) network environment. The goal is to go from data in the network (in the form of packets) to a vector space
representation of the data samples for use in ML applications. The following figure summarizes the pipeline.
The IOT network consists of IP enabled devices such as cameras, assistants, etc. (next Figure).
Sniffers such as Wireshark produce PCAP files (figure below).
In this example, we extract features from PCAP files in order to represent the raw data as feature vectors.
The PCAP file includes many columns. Here is a description of a few of the columns:
- No: The number of the packet in the captured file
- Time: The timestamp of the packet
- Source: The address where this packet is coming from
- Destination: The address where this packet is going to
- Protocol: The protocol name in a short (perhaps abbreviated) version
- Length: The length of each packet
The following figure shows an example of some of the features we can use.
Every packet is made up of headers such as IP, TCP, etc. And each header can contain multiple fields (e.g. srcport, protocol, etc.).
The following code can be used to extract features from PCAP files. The PCAP files used in this example are available on the GitHub. First we filter
the PCAP file and then we extract features using "tshark". The results are written to a text file.
The "tshark" command includes several flags.
Some of the "tshark" flags from the previous code segment are described in the following figure.
After running the previous code, the extracted features, written to the final text file, should look like the following.
As such, the fields in the packets are represented as columns in the CSV file (Next figure). The columns in the CSV will be used to extract "X" and "y" for
use in training the ML algorithms.
In the previous example, we defined each sample as being a single packet. However, that is not necessarily the only option. For instance, for detecting
denial of service attacks, we may need to use samples that include multiple packet information. In this case, instead of individual packets as samples,
we may need to create samples that include averages of multiple packet data given a window of time.
Features from Malware
Extracting features from malware can seem like a daunting task. But, in fact, this can be simple depending on the approach. In static malware analysis,
we do not need to run the malware in a sandbox environment and instead just extract data from the actual static malware files. This can be as simple
as the following:
Notice that in the previous code segment, we copy the "exe" file data into a bytearray. The function
extract_features()
is simpler than it seems. The "malwareByteArr" variable is now a sequence of data much like a string in Byte format. Common sequences of characters
can be extracted in a similar way to how you would process syllables in text.
We could, for instance, use a tokenizer as in the next code listing.
From here, we could use the "bag of words" approach to generate the CSV for use with ML algorithms. See \textbf{Bag of Words} approach in the next section.
This example will be covered in more detail in the Malware chapter.
Another type of malware analysis approach is called "Dynamic Malware Analysis". In dynamic malware analysis, we would generate a \textbf{log file} containing
information about the behavior of the malware after running it in a sandbox environment with an emulator.
The following figure shows an example of a log file with malware behavior data (from dynamic analysis). The information in this file can include: file
read traces, DLL calls, registry edits, etc. DLL is the acronym for dynamic linked library. These are files that contain code, data, etc. that can
be used by several programs when running on the operating system.
Let us consider a scenario where we have "exe" files (goodware and malware).
After running these "exe" files in an emulator, we could end up with a \textbf{log file} (CSV) for every goodware or malware sample (Figure below).
Each of these log files could become a sample in our \textbf{X} matrix for use in ML modeling. The contents of the log files could be the source to extract
the features for each sample.
As can be seen in the next figure, each log file (s1, s2, etc.) is used to create the \textbf{X} matrix.
We can then combine the goodware and malware log files to create our data set with samples and labels.
For instance, we could have 50 samples of malware and 50 samples of goodware. This data is available on the GitHub and this example will be
covered further in the "Malware" chapter.
Each sample (S1, S2, ...) should be consistently represented by the same features such as DLL calls, registry edits, file read traces, etc.
When we are extracting the features from the log files we can also add the labels using the file names (i.e. goodeware or malware). The code for this can be seen
in the next figure.
Once the data is extracted, we can proceed to build the neural network model (such as the following). This will be addressed further in the "Malware" chapter.
Features from Forensics
Digital forensics is a huge field and there are many techniques that fall under the topic. In this section I will show a simple example of how to extract
meta-data from an image file. Digital meta data has been used by law enforcement to solve many crimes.
The following code listing shows the example code. You can use any JPG file with this code.
The extracted forensic data should look like the following.
As can be seen, we have information about the OS, the software version, etc.
Features from Text
Feature extraction from text usually involves the processing of text documents to extract tokens, words, chunks, or other phrases to be used to create
the features. There are many, many types of features that can be extracted from text. Some of the methods (\babelEN{\cite{Jurafsky2008Ref}}) that can
be used include:
- the bag of words approach
- frequency histograms of the words
- Part of speech tagging of the words
-
- Anaphora resolution
- word embeddings (the main method used today)
With the information provided by the previous methods, many features can be extracted. In general, text features can be binary or numeric.
Binary features include the presence or absence of words, part of speech tags, chunks, syntactic parses, semantic parses, etc. Numeric
based text features can be derived from performing counts or calculating distance metrics between words or higher level semantic concepts such as with embeddings.
One simple technique, for example, that has had success in extracting features for supervised machine learning is called the gramulator
(McCarthy et al. 2012). The gramulator is a feature extraction technique used particularly in natural language processing.
The main idea is that, for a 2 class problem, you want to extract features (e.g. words or tokens) that are very frequent in one class but
infrequent in the other. This helps to better discriminate between the classes. The downside of this approach, however, is that it needs
a lot of annotated or labeled data to extract the grams or words from each class that are infrequent in the opposite class. If the grams
are representative of the entire population; then, it can be expected that a classifier will have good performance in the classification task.
The downside of most of these techniques is that in the past they have required annotated data. Deep learning provides several new techniques
that address this issue and obtain good performance without needing large amounts of annotated data. These mainly involve some type of word
embedding approach with self-learning. Word embeddings are vector representations of words or syllables or subwords. The vectors are dense
and usually of fixed size such as 256. The values of each vector representing the token in question are learned through some algorithmic
scheme such as Word2Vec (Mikolov et al. 2014), or Transformers.
These techniques can be very useful for cyber security.
Bag of Words approach
A very simple example of performing the "bag of words" approach can be seen in the next code listing. The code uses the "CountVectorizer" function
from sklearn to perform this task. We will use "CountVectorizer" with a concrete example in a future chapter.
Features from Websites for Web Security
Web security can relate to defending against web attacks such as SQL injections and cross site scripting attacks (XSS).
Web Attacks
- cross site scripting attacks (XSS)
- SQL injections
- cross site request forgery
The following code listing shows how to extract features for use in addressing these types of attacks. In particular we can use the
python "beautifulsoup" library to extract data from HTML files.