学习笔记

web安全之机器学习入门学习笔记

机器学习概述(第三章)

基本概念

有监督学习

对具有概念标记(分类)的训练样本进行学习,因为这里的概念标记样本是已知的,所以训练样本的歧义性低。对这些训练集样本继续学习,通过对训练集样本以外的数据进行标记预测,就叫有监督学习(即有一个标准进行对比)

无监督学习

跟有监督学习相反,对没有概念标记(分类)的训练样本进行学习,以便发现训练样本集中的结构性知识。这里的训练样本的歧义性高,因为标记的都是未知的。

聚类是典型的无监督学习。

准确率与召回率

召回率和准确率是两个最基本的指标(在信息检索、分类、识别、翻译等领域里),召回率也叫查全率,准确率也叫查准率。

用二分问题来解释,一个实例实际是真的,且预测时也是真的,就叫真正类(TP),若预测时为假的,则为假负类(FN)。若实际是假的,而预测为真的,则叫假正类(FP),若预测为假,则为真负类(TN)

所以召回率可以表示为【TP/(TP+FN)】,而准确率可以表示为【TP/(TP+FP)】

各种数据集

KDD99数据

这是1999年举办的KDD竞赛时采用的数据集。原本是1998年美国国防部高级研究计划局在MIT林肯实验室进行的入侵检测项目的数据,后来哥伦比亚大学的Sal Stolfo教授和来自北卡罗莱纳州立大学的Wenke Lee教授采用数据挖掘技术对以上数据集进行特征分析和数据预处理,行程了一个新的数据集,于是就成了著名的KDD99数据集。

HTTP DATASET CSIC 2010

这是一个包含大量标注过的针对Web服务的36000歌正常请求以及25000个攻击请求,攻击类型包括sql注入、缓冲区溢出、信息泄露、文件包含、xss等被广泛用于WAF类产品的功能评测。

SEA数据集

简单地说就是一个被广泛用于内部伪装者威胁检测研究的数据集,是Schonlau等人公开的。

ADFA-LD数据集

澳大利亚国防学院对外发布的一套主机级入侵检测系统的数据集合,被广泛应用于入侵检测类产品的测试。数据集包括Linux和Windows。

Alexa域名数据

Alexa是一家专门发布网站世界排名的网站,这个数据是根据用户下载并安装了Alexa Tools Bar嵌入到IE、FireFox等浏览器,从而监控其访问的网站数据进行统计的,因此数据不具有绝对的权威性。但数据提供了包括综合排名、到访问量排名、页面访问量排名等多个评价指标信息,且尚没有而且也很难有更科学、合理的评价参考。

PS:他的数据只是提供全球排名TOP一百万的网站域名的下载,文件格式是CSV

Scikit-Learn数据集

这个数据集里面最常用的是iris数据集,这是一个存储了鸢尾属植物的萼片和花瓣的长宽数据。

MNIST数据集

一个入门的计算机视觉数据集,包含各种手写数字图片

Movie Review Data

包含1000条正面评论和1000负面评论的数据,被广泛应用于文本分类。

SpamBase数据集

入门级的垃圾邮件分类训练集

Ps:已经经过特征化的数据,对应的特征是统计的关键字以及特殊符号的词频,一共58个属性

Enron数据集

该公司已经破产(太惨了吧)

一般用于不同文件夹盆正常邮件和垃圾邮件

特征提取

数字型特征提取

数据型特征可以直接作为特征,但是对于一个多为的特征,某一个特征的取值范围特别大,很可能导致其他特征对结果的影响被忽略,这时候我们需要对数字型特征进行预处理

标准化
1
2
3
4
5
6
7
from sklearn import preprocessing
import numpy as np
X = np.array([[1., -1., 2.],
[2., 0., 0.,],
[0., 1., -1.]])
X_scaled = preprocessing.scale(X) #规范化,使用格式放在下面
print(X_scaled)
1
sklearn.preprocessing.scale(X, axis=0, with_mean=True, with_std=True, copy=True)

沿着某个轴标准化数据集,以均值为中心,以分量为单位方差。

参数 数据类型 意义
X {array-like, sparse matrix} 以此数据为中心缩放
axis int (0 by default) 沿着计算均值和标准差的轴。如果是0,独立的标准化每个特征,如果是1则标准化每个样本(即行)
with_mean boolean, True by default 如果是True,缩放之前先中心化数据
with_std boolean, True by default 如果是True,以单位方差法缩放数据(或者等价地,单位标准差)
copy boolean, optional, default True False:原地执行行标准化并避免复制(如果输入已经是一个numpy数组或者scipy.sparse CSC矩阵以及axis是1)

输出结果

1
2
3
[[0.  ..., -1.22..., 1.33...],
[1.22..., 0. ..., -0.26...],
[1.22..., 1.22..., -1.06...]]
正则化
1
2
3
4
5
X = [[1., -1., 2.],
[2., 0., 0.,],
[0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='12')
print(X_normalized)
1
x_norm=np.linalg.norm(x, ord=None, axis=None, keepdims=False)

(1)x: 表示矩阵

(2)ord:范数的类型。可赋值1,2,none。默认情况下,求2范数,即平方之和再开方。

(3)axis:行向量处理或列向量处理。

axis=1表示按行向量处理,求多个行向量的范数

axis=0表示按列向量处理,求多个列向量的范数

axis=None表示矩阵范数。

(4)keepding:是否保持矩阵的二维特性

True表示保持矩阵的二维特性,False相反

输出结果

1
2
3
[[0.40..., -0.40..., 0.81...],
[1. ..., 0. ..., 0. ...],
[0. ..., 0.70..., -0.70...]]
归一化
1
2
3
4
5
6
X_train = np.array([[1., -1., 2.],
[2., 0., 0.,],
[0., 1., -1.]])
min_max_scaler = perprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
print(X_train_minmax)

输出结果

1
2
3
[[0.5     , 0.     , 1.      ],
[1. , 0.5 , 0.33333333],
[0. , 1. , 0. ]]

文本型特征提取

本质上就是对单词做切分,不同的单词当作一个新的特征。

一本进行文本型特征提取有两个非常重要的模型

一个是词集模型,即单词构成的集合,集合中每个元素都只有一个,换言之词集中的每个单词都只有一个

另一个是词袋模型,即一个单词在该文档中出现的次数不止一次,那么就统计其出现的次数(频数)。

这两个模型本质上并没有什么区别,只是词袋在词集的基础上增加了频率的维度:词集只关注有和没有,词袋还要关注有几个。

K近邻算法(第五章)

k近邻算法的核心思想是:距离接近的事物具有相同属性的可能性要大于距离相对较远的。

KNN

knn的核心思想:如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上的样本的特性。

常用算法:

Brute Force

K-D Tree

Ball Tree

决策树和随机森林算法(第六章)

决策树表现了对象属性与对象值之间的一种映射关系

随机森林算法可以看成是一个加强版的决策树,他是用多个决策树组成一个森林,每个决策树之间没有任何的关联。在输入一个样本的时候,它会经过每一个决策树,看看哪个样本应该属于哪个分类或者哪个选项被选择的最多。

朴素贝叶斯算法(第七章)

朴素贝叶斯算法是基于贝叶斯定理与特征条件独立假设的分类方法。

通常包括以下算法:

高斯朴素贝叶斯

多项式朴素贝叶斯

伯努利朴素贝叶斯

逻辑回归算法(第八章)

逻辑回归也叫回归分析,他是通过描述自变量X和因变量Y之间的关系而从对因变量Y进行预测的(也可以说是自变量X对因变量Y的影响程度)。

自变量如果只有一个,我们就叫一元回归分析,如果有多个,就叫多元回归分析。

支持向量机算法(第九章)

简单地说就是在桌面上有一堆红蓝两色的小球,然后通过一条线把红蓝分开,让一边只有红色另一边只有蓝色。如果在二维上无法划分就上升到三维去划分,以此类推。

升维需要依靠核函数,SVM通过一个非线性映射,把样本空间映射到一个高纬乃至无穷维的特征空间中,是的在原来的样本空间中非线性可分问题转化为在特征空间中的线性可分问题。(就是升维和线性化)

所谓的升维,就是把样本向高纬空间做映射,一般情况下这种处理方法会增加计算的复杂性,甚至会引起“维数灾难”(维数灾难就是高维的数据过于复杂,导致分析和组织高维空间(通常有成百上千维)中的数据,因体积指数增加而遇到各种问题场景,它有一个特点:当维度增加时,空间的体积增加得很快,使得可用的数据变得稀疏)

于是,一个矛盾就出来了,升维会导致计算复杂,数据变得稀疏,而不升维,会因为处于低维而导致样本空间无法线性处理(有些样本可以在高维空间通过一个线性超平面实现线性划分或者回归)。然而SVM却巧妙地化解了这个矛盾:应用和函数的展开定理,就不需要知道非线性映射的显式表达式。由于是在高维特征空间中建立线性学习机,所以与线性模型相比,可以避免维数灾难的发生以及高维的计算复杂性的增加。

常用的核函数有以下几种:

线性核函数:K(x,y) = x*y

多项式核函数: K(x,y) = [(x*y)+1]^d

径向基函数: K(x,y) = exp(-|x-y|^2/d^2)

二层神经网络核函数:K(x,y) = tanh(a(x*y)+b)

PS:tanh为双曲正切

使用方法

导入库

1
2
3
import numpy as np
import matplotlib.pyplot as ply
from sklearn import svm

创建40个随机点

1
2
3
4
5
6
np.random.seed(0)
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
Y = [0] * 20 + [1] * 20
#符合模型
clf = svm.SVC(kernel='linear')
clf.fit(X,Y)

构建超平面

1
2
3
4
5
6
7
8
9
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]
#绘制平行线到通过支撑的分离超平面
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])

调用matplotlib画图

1
2
3
4
5
6
7
plt.plot(xx, yy, 'k-')
plt.plot(xx, yy_down, 'k--')
plt.plot(xx, yy_up, 'k--')
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=80, facecolors='none')
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=cpl.cm.Paired)
plt.axis('tight')
plt.show()

K-Means与DBSCAN算法(第十章)

K-Means算法

中心思想:以空间中k个点为中心进行聚类,通过迭代的方法,组词更新各聚类中心的值,直至得到最好的聚类结果

基础使用方法

导库
1
2
3
4
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import K-Means
from sklearn.datasets import make_blobs
生成测试样本
1
2
3
n_samples = 1500
random_state = 170
X, Y = make_blobs(n_samples=n_samples, random_state=random_state)
进行聚类,指定聚类个数为3
1
Y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X)
可视化结果
1
2
3
4
plt.subplot(221)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title("hello word!")
plt.show()

DBSCAN算法

跟K-means不同,如果说前者是指定划分多少个聚类的话,那么这个就是只规定一个聚类里面有多少个东西,没有规定要划分多少个聚类。

它主要是将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并课在噪声的空间数据库中发现任意形状的聚类。

基本用法

核心函数
1
2
3
4
5
6
7
DBSACN(eps=0.5,
min_samples=5,
metric='euclidean',
algorithm='auto',
leaf_size=30,
p=None,
n_jobs=1)

主要参数如下:

esp【同一聚类集合中两个样本的最大距离】

min_samples【同一聚类集合中最小样本数】

algorithm【算法,分为‘auto’,‘ball_tree’, ‘kd_tree’, ‘brute’】

leaf_size【使用Ball Tree或者cKDTree算法时叶子节点个数】

n_jobs【并发任务数】

导库
1
2
3
4
5
6
import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
创建测试样本
1
2
3
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4, random_state=0)
X = StandardScaler().fit_transform(X)
运行算法,esp设计为0.3,最小样本数为10
1
2
3
4
db = DBSCAN(eso=0.3, min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
设置可视化需要的数据
1
2
3
4
5
6
7
8
9
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
for k , col in zip(unique_labels, colors):
if k == -1:
col = 'k'
class_member_mask = (labels == k)
xy = X[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col, markeredgecolor='k',
markersize=14)
xy = X[class_member_mask & ~core_samples_mask]
可视化展开
1
2
3
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col,
markeredecolor='k', markersize=6)
plt.show()

Apriori与FP-growth算法(第十一章)

Apriori算法

这是一个关联算法

它有三个基本概念:支持度、置信度、频繁K项集

Apriori算法是同时满足最小支持度阈值和最小置信度阈值的关联规则。使用频繁项集的先验知识,使用‘逐层搜索’的迭代方法。

支持度

既有A又有B的概率,它表现的是A和B两个时间相对整个数据集合同时发生的频繁程度。

置信度

在A发生的事件中同时发生B的概率P(AB)/p(A)

频繁K项集

满足最小支持度阈值的时间就称为频繁K项集

FP-growth算法

这是基于Apriori构建的算法,但采用了高级的数据结构减少了扫描次数,大大加快了算法速度。

它只需要对数据库进行两次扫描,而Apriori算法则是对于每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁。

基本过程:

构建FP树

从FP树中挖掘频繁项集

隐式马尔可夫算法(第十二章)

一个连续的时间序列时间,他的状态由且仅由它前面的N歌时间决定,对应的事件序列可以成为N阶马尔可夫链。

神经网络(深度学习)

神经网络由输入层、隐藏层、输出层组成。

如果隐藏层只有一个,那么这个就是最简单的单层神经网络。如果隐藏层有多个,那就是多层感知机。

而深度学习就是多层感知机。

狭义的多层感知机要求必须是全连接的(所谓的全连接,就是每个隐藏层的任何一个节点,都与下一层隐藏层的全部节点连接)

常见的深度学习包括:

深度神经网络(DNN)

卷积神经网络(CNN)

循环神经网络(RNN)

Tensorflow编程模型

Tensor叫张量,即所谓的N维数组

Flow叫流,所谓基于数据流图的计算

所以Tensorflow为张量从流图的一段流动到另一端的计算过程。它将复杂的数据结构传输到人工智能神经网中进行分析和处理。

它有着四个基本组件:操作、张量、变量和会话

操作

把算法表示成一个个操作的叠加,可以清晰地看到数据之间地关系。

当数据流过操作节点的时候就可以对数据进行操作,一个操作可以有零个或多个输入,产生零个或多个输出。

张量

在计算图中,每个边就代表数据从一个操作流到另一个操作。这些数据就被表示为张量,一个张量可以看成多维的数组或者高维的矩阵

需要注意的是张量本身并没有保存任何值,仅仅提供了范文数值的一个借口,可以看成数值的一种引用。

变量

变量是计算图中可以改变的节点。

会话

在Tensorflow中所有的操作都必须在会话中执行,会话负责分配和管理各种资源。