机器学习建模方法和KNN算法

机器学习基础(三)

  • sklearn数据处理和模型评价
    • 数据切分
    • 模型评价
  • KNN算法
    • 算法流程
    • 距离度量
    • kd树
    • 代码实现
    • 模型调优
      • 交叉验证
    • 超参数搜索-网格搜索

sklearn数据处理和模型评价

数据切分

在机器学习中,算法模型是根据数据拟合出来的结果,如果将用于训练得数据用于评价模型,那么模型得效果很可能是偏高的。所以我们需要对数据集进行切分,将数据集分为测试集和训练集。
代码如下

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=123)
#test_size是指定测试集的大小,0.3指将30%的数据作为测试集
#random_state是指定随机种子,这样可以保证每次切分的数据集是一样

模型评价

对于一个机器学习的模型我们需要对它进行评价,衡量模型的优劣。最常见的评价方法就是使用模型的预测准确率(经常看的是测试集的准确率),其次就是F1 score,在许多竞赛中,评价标准通常是F1 score+acc。

首先介绍一下混淆矩阵、precision和recall。

混淆矩阵 是指预测结果和正确标记之间的四种不同的组合。

混淆矩阵 预测正例 预测反例
标记正例 TP FN
标记反例 FP TN

Precision(精准率) 是指预测结果为正例样本中真实为正例的比例,故精确率的计算公式如下

P r e c i s i o n = T P T P + F P Precision=\frac{TP}{TP+FP} Precision=TP+FPTP

Recall(查全率/召回率) 是指真实为正例的样本中被预测为正样本的比例

R e c a l l = T P T P + F N Recall = \frac{TP}{TP+FN} Recall=TP+FNTP

接下来介绍F1 score,F1 score是反应模型的稳健性。
F 1 = 2 ∗ P r e c i s i o n ∗ R e c a l l P r e c i s i o n + R e c a l l F1 = \frac{2*Precision*Recall}{Precision+Recall} F1=Precision+Recall2PrecisionRecall

sklearn模型评价的使用

#假设训练好的模型为model
y_pre = model.predict(x_test) #预测测试集的结果
model.score(x_test,y_test) #返回模型的准确率
print(classification_report(y_test,y_pre,target_names=target_names"))	
#target_names指标签名的列表

KNN算法

定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

算法流程

首先输入训练的数据集 ( X , Y ) (X,Y) (X,Y)
( X , Y ) = ( ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 2 ) , ⋯   , ( x N , y N ) ) (X,Y)=((x_{1},y_{1}),(x_{2},y_{2}),(x_{3},y_{2}),\cdots,(x_{N},y_{N})) (X,Y)=((x1,y1),(x2,y2),(x3,y2),,(xN,yN))
X X X为输入的特征变量, Y Y Y是输入的标签

然后输入实例 x x x,然后输出其所属类别的 y y y

计算方法:(1)根据所给定的距离变量,在训练集 ( X , Y ) (X,Y) (X,Y)中找出与 x x x最近邻的 k k k个点,然后将涵盖这 k k k个点的 x x x的领域记为 N k ( x ) N_{k}(x) Nk(x)
(2)在 N k ( x ) N_{k}(x) Nk(x)中根据分类决策规则(即 k k k个类别中哪个列别多)决定 x x x所属的类别 y y y

公式
y = a r g m a x c j ∑ x i ∈ N k ( x ) I ( y i = c i ) i = 1 , 2 , 3 , ⋯   , K y=argmax_{c_{j}}\sum_{x_{i}\in N_{k}(x)}I(y_{i}=c_{i}) i=1,2,3,\cdots,K y=argmaxcjxiNk(x)I(yi=ci)i=1,2,3,,K
其中 I I I为指示函数,当 y i = c i y_{i}=c_{i} yi=ci是返回1,否则返回0

该算法则称之为 k k k近邻算法, k k k是超参数通常取奇数,当 k = 1 k=1 k=1时,称之为最近邻算法,即离 x x x最近点的分类为 x x x所属的类。

距离度量

距离的标准是该模型计算的重点,常用的距离度量为欧式距离, L p L_{p} Lp距离也是经常使用
L p ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ p ) 1 p L_{p}(x_{i},x_{j})=\left(\sum^{n}_{l=1}|x^{(l)}_{i}-x_{j}^{(l)}|^{p}\right)^{\frac{1}{p}} Lp(xi,xj)=(l=1nxi(l)xj(l)p)p1

这里 p ⩾ 1 p\geqslant1 p1。当 p = 2 p=2 p=2时,称为欧式距离,即
L 2 ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ 2 ) 1 2 L_{2}(x_{i},x_{j})=\left(\sum^{n}_{l=1}|x_{i}^{(l)} -x_{j}^{(l)}|^{2}\right)^{\frac{1}{2}} L2(xi,xj)=(l=1nxi(l)xj(l)2)21

p = 1 p=1 p=1时,称为曼哈顿距离,即
L 1 ( x i , x j ) = ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ L_{1}(x_{i},x_{j})=\sum^{n}_{l=1}|x_{i}^{(l)} -x_{j}^{(l)}| L1(xi,xj)=l=1nxi(l)xj(l)

p = ∞ p=\infty p=时,它是各个坐标距离的最大值(因为细小的差距会被拉至无限大),故
L ∞ ( x i , x j ) = m a x l ∣ x i ( l ) − x j ( l ) ∣ \displaystyle L_{\infty}(x_{i},x_{j})=max_{l}|x_{i}^{(l)}-x_{j}^{(l)}| L(xi,xj)=maxlxi(l)xj(l)

kd树

k d kd kd树是一种对 k k k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。 k d kd kd树是二叉树,表示对 k k k维空间的一个划分。构造 k d kd kd树相当于不断地用垂直于坐标轴的超平面将 k k k维空间切分,构成一系列的 k k k维超矩形区域。 k d kd kd树的每个结点对应于一个 k k k维超矩形区域。

k n n knn knn算法中,使用 k d kd kd树可以加快模型的搜索速度,从而使模型的效率更高。关于 k d kd kd树 的详细介绍以后再分享。

代码实现

本次代码以sklearn中的新闻数据集为例

from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import classification_report
#导入数据
news = fetch_20newsgroups(subset= "all")
x = news.data
y = news.target
#切分数据集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3,random_state=123)

#数据是文本类型,使用tf-idf转化为数值型数据
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
x_test = tf.transform(x_test)

#使用KNN算法进行拟合数据
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train,y_train)
print("模型的准确率为",knn.score(x_test,y_test)) #78.47%
y_pre = knn.predict(x_test)
print("模型的F1值为",classification_report(y_test,y_pre,target_names=news["target_names"]))

模型调优

交叉验证

交叉验证就是将数据分为训练集和验证集。例如将数据分成5等份,然后将其中的一份作为验证集,然后经过5次的测试,每次测试都需要更换不同的验证集,最后得到5组模型的结果,取5组结果的平均值做为最终结果。这也称作5折交叉验证。(常用的交叉验证还有十折交叉验证,几折验证就分成几等分)

超参数搜索-网格搜索

在机器学习的模型中,很多模型是存在超参数的, 这个超参数是需要人工指定的,但频繁的更改十分消耗人力和时间。故需要使模型可以对多组参数进行验证并返回结果。 每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

接下来以 k k k近邻算法为例子, k k k是超参数,使用代码如下

from sklearn.model_selection import GridSearchCV

#首先建立估计器
knn = KNeighborsClassifier()
#指定模型的调参范围
param_grid = {"n_neighbors":[k for k in range(1,22,2)]}
#使用模块进行迭代,指定每次使用的交叉验证次数为5
gd = GridSearchCV(knn,param_grid,cv=5)
gd.fit(x_train,y_train)
print("模型的最优准确率为",gd.score(x_test,y_test))
print("模型的最优参数为",gd.best_params_)
print("模型的全部训练结果",gd.cv_results_)

你可能感兴趣的:(机器学习,机器学习,算法,python,人工智能)