Skip to main content
4 of 7
added 1130 characters in body
J.D.
  • 921
  • 5
  • 20
  • 31

Building an efficient feature vector

I am building a classifier for malware analysis, which predicts if I have a malware by looking at the intructions of an assembly code, such as push, mov,... and predicting the optimization method. Note that I am considering a json file. My code is the following:

#pakages
import numpy as np
import pandas as pd
import json as j
import re
import nltk
from nltk.tokenize import word_tokenize


from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import *
from sklearn.metrics import confusion_matrix, classification_report
from sklearn import svm

#for visualizing data
import matplotlib.pyplot as plt
import seaborn as sns; sns.set(font_scale=1.2)

%matplotlib inline

json_data = None;
with open('training_dataset.jsonl') as data_file:
    lines = data_file.readlines()
    joined_lines = "[" + ",".join(lines)+"]"

    json_data = j.loads(joined_lines)    

data = pd.DataFrame(json_data)
data.head()

enter image description here

myList = [];
for value in data['instructions'].iteritems():
    myList.extend(list(value[1]))

opcodes = [instruction.split()[0] for instruction in myList]

enter image description here

vect = CountVectorizer()
x = vect.fit_transform(opcodes)
a =vect.vocabulary_

enter image description here

X = list(a.values())
X_all = np.array(X).reshape(-1,1)



Y = list(data['opt'])
MlistY = Y[ :395]
y_all = np.array(MlistY)

X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, 
      test_size=0.2, random_state=15)

from sklearn.svm import SVC
model = SVC()

model.fit(X_train,y_train)

y_pred = model.predict(X_test)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

model.score(X_test,y_test)  

so, what I did is doing a feature extraction where I counted the numner of times each instruction such as push,mov,... appearsin the training set, and use these numbers as feature vectors. After that I had to cut the column data['opt'] in such a way to have the same number of elements of X_all. Then I split the dataset and I used as model support vector machines.

My problem is that the accuracy is very low, infact it is : 0.4810126582278481

I think this method I just used is called bag of words, but it is not very efficient for my case.

I think this is due to the fact that the method I used to extract the features is very inefficient.

My idea is to try to do a vectorization such that I assign to each operator a number, for example:

push -->0 mov -->1 jmp -->2 edx -->3

and so on and build a feature vector like this. But I also would like to keep track of the order on which the operators occurs inside the feature vector.

Is there a way to do this?

I have not found a specific vectorizer that does this, so is there a way for doing this type of vectorization?

Thank's in advance.

[EDIT] To create such feature vector where I keep the order I tried the following:

opcodes_ordered = pd.factorize(opcodes)

opcodes_ordered_true = opcodes_ordered[0]

opcodes_ordered_true

which returns : rray([ 0, 0, 0, ..., 22, 3, 5], dtype=int64)

Now I create the feature vector and define a model:

X_all_2 = opcodes_ordered_true.reshape(-1,1)[:30000] #had to cut the vector 
                                                     #because y has 30000 
                                                     # elements

y_all_2 = list(data['opt'])

X_train_2, X_test_2, y_train_2, y_test_2 = train_test_split(X_all_2, 
y_all_2, test_size=0.2, random_state=15)

model_2 = SVC(kernel = 'sigmoid',gamma = 1.0)

model_2.fit(X_train_2,y_train_2)

y_pred_2 = model_2.predict(X_test_2)
print(confusion_matrix(y_test_2, y_pred_2))
print(classification_report(y_test_2, y_pred_2))

model_2.score(X_test_2,y_test_2) 

but accuracy is still very low, in fact I have an accuracy of :

0.4841666666666667

I don't know what to do now.

J.D.
  • 921
  • 5
  • 20
  • 31