本文将在上一篇文章的基础上(上一篇文章完成了项意图数据处理及统计学剖析),持续完善数据预处理部分、模型建立、模型练习等过程。

本项目运用Jupyter Notebook进行操作,运用PaddlePaddle结构进行实战操作

1 项目回忆 ✅

为了有用保护企业敏感数据,饯别企业安全操作行为准则,杜绝由反常操作行为导致的企业敏感数据走漏安全事件产生,用户反常行为剖析与识别成为重难点技术之一。

本项目将运用Paddle建立人工神经网络,经过机器学习的手段猜测用户上网反常评分,本项目包括数据处理与剖析、数据预处理、模型建立、模型练习、模型猜测、模型评价等完整流程,测验建立三种不同的网络处理该问题。

2. 数据预处理

2.1 数据编码

  • 在数据处理进程中,咱们有时需求对不连续的数字或者文本进行数字化处理。
  • 其间,咱们选取了'account', 'group', 'IP', 'url', 'switchIP'这五个object类型的特征字段进行了编码。
from sklearn.preprocessing import LabelEncoder
for feat in ['account', 'group', 'IP', 'url', 'switchIP']:
    labelencoder = LabelEncoder()
    train_data[feat] = labelencoder.fit_transform(train_data[feat])

检查编码后的数据集

# 检查编码后的数据集
train_data.head()

编码后的成果如下图所示:

  • 能够发现曾经的object字段都变成了数字编码

【机器学习】人工神经网络实现用户上网异常行为分析(2)

2.2 区分练习集与测验集

  • 选取了'account', 'group', 'IP', 'url', 'port', 'vlan', 'switchIP', 'hour', 'weekday', 'year', 'month', 'day'字段作为练习的特征(features)。
  • 'ret'字段为想要猜测的目标值/标签值(label)。
  • 咱们将数据集区分为:练习集:测验集 = 0.75:0.25

先结构全体数据的特征值与标签值。

data_X = train_data.loc[train_data.index[:], ['account', 'group', 'IP', 'url', 'port', 'vlan', 'switchIP', 'hour', 'weekday', 'year', 'month', 'day']]
data_Y = train_data['ret']

然后,运用sklearn库中的数据集切分API进行对练习集和测验集进行切分。

from sklearn.model_selection import train_test_split
# 数据集区分
x_train, x_test, y_train, y_test = train_test_split(data_X, data_Y, test_size=0.25, random_state=6)
print("练习集的特征值:\n", x_train, x_train.shape)
print("测验集的标签值:\n", y_test, y_test.shape)
print("The length of original data X is:", data_X.shape[0])
print("The length of train Data is:", x_train.shape[0])
print("The length of test Data is:", x_test.shape[0])

部分运转成果如下图所示:

【机器学习】人工神经网络实现用户上网异常行为分析(2)

2.3 标签值数组维度转化

练习集的特征数组(features)为二维数组,而练习集的标签数据(label)是一维数组,需求将其转变为二维数组再传入神经网络练习,坚持维度共同,不然会报错

首要转化字段类型,然后对数组维度进行转化

  • (-1,1):后一个1表明指定数组维度为1列,前一个-1表明依据指定好的数组维度1列主动调整行数
x_train = np.array(x_train, dtype='float32')
y_train = np.array(y_train, dtype='float32')
y_train = y_train.reshape(-1,1)
y_train

x_test = np.array(x_test, dtype='float32')
y_test = np.array(y_test, dtype='float32')
y_test = y_test.reshape(-1,1)
y_test

2.4 归一化(标准化)

咱们对练习集和测验集的特征值进行了标准化

  • 意图是将一切特征放缩在一个数量级下,这样就不会导致某个特征对模型的影响过大
# 标准化
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
# 1. 实例化一个转化器类
transfer = StandardScaler()
# 2. 标准化
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

2.5 设置随机数种子

import random
import paddle
seed = 666
# 设置随机种子 固定成果
def set_seed(seed):
    np.random.seed(seed)
    random.seed(seed)
    paddle.seed(seed)
set_seed(seed)

3. 模型组网

运用飞桨PaddlePaddle进行组网,激活函数能够挑选:

  • tanh(x)=2(2x)−1tanh(x) = 2(2x) − 1
  • ReLU(x)=Max(0,x)ReLU(x) = Max(0, x)

躲藏层层数能够测验运用1层,2层,3层。

3.1 建立神经网络

测验运用 12643216811264321681

  • 'account', 'group', 'IP', 'url', 'port', 'vlan', 'switchIP', 'hour', 'weekday', 'year', 'month', 'day':共12个特征(features)进行输入
  • 'ret':作为回归输出的标签(label)
  • 激活函数运用的是Tanh
  • 共4层躲藏层

paddle.nn.Dropout(p=0.5, axis=None, mode="upscale_in_train”, name=None)

  • Dropout 是一种正则化手段,该算子依据给定的丢掉概率 p,在练习进程中随机将一些神经元输出设置为 0,经过阻止神经元节点间的相关性来削减过拟合。
import paddle
import paddle.nn as nn
# 界说动态图
class Classification(paddle.nn.Layer):
    def __init__(self):
        super(Classification, self).__init__()
        nn.Tanh
        nn.PReLU
        self.drop = paddle.nn.Dropout(p=0.5)
        self.fc1 = paddle.nn.Linear(12, 64)
        self.fc2 = paddle.nn.Linear(64, 32)
        self.fc3 = paddle.nn.Linear(32, 16)
        self.fc4 = paddle.nn.Linear(16, 8)
        self.fc5 = paddle.nn.Linear(8, 1)
        self.Tanh = nn.Tanh()
        self.PReLU = nn.PReLU()
    # 网络的前向核算函数
    def forward(self, inputs):
        x = self.Tanh(self.fc1(inputs))
        x = self.drop(x)
        x = self.PReLU(self.fc2(x))
        x = self.drop(x)
        x = self.PReLU(self.fc3(x))
        x = self.drop(x)
        x = self.PReLU(self.fc4(x))
        x = self.drop(x)
        pred = self.fc5(x)
        return pred

4. 模型练习

4.1 界说可视化函数

  • 在练习后能够运转可视化函数,对练习丢失进行可视化
  • 可视化函数界说如下,重点是取得iter与cost之间的改变联系
# 界说制作练习进程的丢失值改变趋势的办法draw_train_process
train_nums = []
train_costs = []
def draw_train_process(iters,train_costs):
    title="training cost"
    plt.title(title, fontsize=24)
    plt.xlabel("iter", fontsize=14)
    plt.ylabel("cost", fontsize=14)
    plt.plot(iters, train_costs,color='red',label='training cost') 
    plt.grid()
    plt.show()

4.2 界说丢失函数

  • 丢失函数运用的是k1丢失,需求自己界说一下丢失函数。
  • 当然,也能够测验运用其他的丢失函数,例如均方差错丢失。
  • k1丢失函数界说如下:
import paddle
import paddle.nn.functional as F
class kl_loss(paddle.nn.Layer):
    def __init__(self):
       super(kl_loss, self).__init__()
    def forward(self, p, q, label):
        ce_loss = 0.5 * (F.mse_loss(p, label=label)) + F.mse_loss(q, label=label)
        kl_loss = self.compute_kl_loss(p, q)
        # carefully choose hyper-parameters
        loss = ce_loss + 0.3 * kl_loss 
        return loss
    def compute_kl_loss(self, p, q):
        p_loss = F.kl_div(F.log_softmax(p, axis=-1), F.softmax(q, axis=-1), reduction='none')
        q_loss = F.kl_div(F.log_softmax(q, axis=-1), F.softmax(p, axis=-1), reduction='none')
        # You can choose whether to use function "sum" and "mean" depending on your task
        p_loss = p_loss.sum()
        q_loss = q_loss.sum()
        loss = (p_loss + q_loss) / 2
        return loss

4.3 模型练习

模型参数设置如下:

  • 练习轮数:5
  • batch_size:64
  • 丢失函数:kl_loss

如果内存空间不是很大,batch_size也不适合挑选太大,能够设置稍微少一些

import paddle.nn.functional as F
y_preds = []
labels_list = []
BATCH_SIZE = 64
train_data = x_train
train_data_y = y_train
test_data = x_test
test_data_y = y_test
compute_kl_loss = kl_loss()
CET_loss = paddle.nn.CrossEntropyLoss()
def train(model):
    print('start training ... ')
    # 敞开模型练习模式
    model.train()
    EPOCH_NUM = 5
    train_num = 0
    scheduler = paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=0.001, T_max=int(train_data.shape[0]/BATCH_SIZE*EPOCH_NUM), verbose=False)
    optimizer = paddle.optimizer.Adam(learning_rate=scheduler, parameters=model.parameters())
    for epoch_id in range(EPOCH_NUM):
        # 在每轮迭代开端之前,将练习数据的次序随机的打乱
        np.random.shuffle(train_data)
        # 将练习数据进行拆分,每个batch包括64条数据
        mini_batches = [np.append(train_data[k: k+BATCH_SIZE], train_data_y[k: k+BATCH_SIZE], axis = 1) for k in range(0, len(train_data), BATCH_SIZE)]
        for batch_id, data in enumerate(mini_batches):
            features_np = np.array(data[:, :12], np.float32)
            labels_np = np.array(data[:, -1:], np.float32)
            features = paddle.to_tensor(features_np)
            labels = paddle.to_tensor(labels_np)
            #前向核算
            # y_pred = model(features)
            y_pred1 = model(features)
            y_pred2 = model(features)
            cost = compute_kl_loss(y_pred1, y_pred2, label=labels)
            # cost = CET_loss(y_pred, labels)
            # cost = F.mse_loss(y_pred, label=labels)
            train_cost = cost.numpy()[0]
            #反向传达
            cost.backward()
            #最小化loss,更新参数
            optimizer.step()
            # 清除梯度
            optimizer.clear_grad()
            if batch_id % 500 == 0 and epoch_id % 1 == 0:
                print("Pass:%d,Cost:%0.5f"%(epoch_id, train_cost))
            train_num = train_num + BATCH_SIZE
            train_nums.append(train_num)
            train_costs.append(train_cost)
model = Classification()
train(model)

运转练习函数,神经网络模型就能够练习起来了。部分练习成果如下图所示:

【机器学习】人工神经网络实现用户上网异常行为分析(2)

5. 模型猜测

测验集样本量较大,能够挑选猜测一个样本,也能够猜测部分样本值。

  • 界说猜测函数,然后运用猜测函数对测验集杨嫩
train_data = x_train
train_data_y = y_train
test_data = x_test
test_data_y = y_test
def predict(model):
    print('start evaluating ... ')
    model.eval()
    outputs = []
    mini_batches = [np.append(test_data[k: k+BATCH_SIZE], test_data_y[k: k+BATCH_SIZE], axis = 1) for k in range(0, len(test_data), BATCH_SIZE)]
    for data in mini_batches:
        features_np = np.array(data[:, :12], np.float32)
        features = paddle.to_tensor(features_np)
        pred = model(features)
        out = paddle.argmax(pred, axis=1)
        outputs.extend(out.numpy())
    return outputs
outputs = predict(model)

6. 核算目标

6.1 Mean Squared Error(MSE) 均方差错

  • 关于猜测的成果,咱们能够进行模型评价
  • 咱们挑选MSE目标进行评价
from sklearn.metrics import mean_squared_error
print(mean_squared_error(test_data_y,outputs))

7. 总结

本文持续上一篇文章,完成了用户上网反常剖析项意图数据预处理,模型建立,模型猜测,模型评价过程。对上网反常数据进行了猜测。

  • 本项目建立神经网络实现了对UEBA用户上网反常回归猜测。

  • 往后能够测验的改善方向总结如下:

    • 持续挖掘特征与目标值的联系
    • 由于数据集特征有限,能够考虑进一步丰厚数据特征。
    • 能够考虑运用其他网络模型,例如卷积网络,对该数据集进行回归猜测,剖析其作用。
    • 另外,能够测验运用不同的丢失函数对模型进一步优化。

本文正在参与「金石计划 . 分割6万现金大奖」