2019-04-27 11:29:56 weixin_44766179 阅读数 3489
  • 机器学习入门30天实战

    购买课程后,可扫码进入学习群,获取唐宇迪老师答疑 系列课程包含Python机器学习库,机器学习经典算法原理推导,基于真实数据集案例实战3大模块。从入门开始进行机器学习原理推导,以通俗易懂为基础形象解读晦涩难懂的机器学习算法工作原理,案例实战中使用Python工具库从数据预处理开始一步步完成整个建模工作!具体内容涉及Python必备机器学习库、线性回归算法原理推导、Python实现逻辑回归与梯度下降、案例实战,信用卡欺诈检测、决策树与集成算法、支持向量机原理推导、SVM实例与贝叶斯算法、机器学习常规套路与Xgboost算法、神经网络。

    7609 人正在学习 去看看 唐宇迪

K近邻(K-Nearest Neighor,KNN)学习是一种常用的监督学习方法,它的思想非常简单:给定测试样本,基于某种距离度量找出训练集中与其最靠近的K个训练样本,然后基于这K个邻居的信息进行预测。KNN是一种基本的机器学习算法。KNN既可以用作分类,也可以用作回归。KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最近的K个样本,预测为里面有最多类别数的类别。而KNN做回归时,一般是选择平均法,即最近的K个样本的样本输出的平均值作为回归预测值。

一般通过交叉验证选择最优的K值。对于距离的度量方式,最常见的是欧氏距离:
在这里插入图片描述
KNN的主要优点有:
1) 理论成熟,思想简单,既可以用来做分类也可以用来做回归
2) 可用于非线性分类
3) 训练时间复杂度比支持向量机之类的算法低,仅为O(n)
4) 和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
5) 由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
6)该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分
    
KNN的主要缺点有:
1)计算量大,尤其是特征数非常多的时候
2)样本不平衡的时候,对稀有类别的预测准确率低
3)使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
4)相比决策树模型,KNN模型可解释性不强

# K近邻
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt

# 随机生成数据
x, y = make_classification(n_clusters_per_class=1, n_samples=500, n_redundant=0, n_features=2, random_state=14)
# 数据划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=2)

# 画出原始数据
plt.scatter(x[:, 0], x[:, 1], c=y)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Orical Data')
plt.show()

# 参数n_neighbor的选择
n_neighbors = [3, 5, 7, 9, 11]

# 平均值
accuracy_list = []
# 方差
accuracy_std = []

# 找到最优参数
for n in n_neighbors:
    knn = KNeighborsClassifier(n_neighbors=n)
    scores = cross_val_score(knn, x_train, y_train, cv=5)
    accuracy_list.append(scores.mean())
    accuracy_std.append(scores.std())
    
# 可视化
plt.grid()
plt.plot(n_neighbors, accuracy_list)
plt.scatter(n_neighbors, accuracy_list, c='r')
plt.errorbar(n_neighbors, accuracy_list, accuracy_std, c='g')
plt.xlabel('n')
plt.ylabel('accuracy')
plt.show()

# 由上图可以看出n_neighbor最优值为3
knn = KNeighborsClassifier(n_neighbors=3).fit(x_train, y_train)
y_pred = knn.predict(x_test)

print('tesing accuracy:', accuracy_score(y_pred, y_test))

# 画出训练集样本点
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)

# 画出测试集样本点
for i in range(len(x_test)):
    if y_pred[i] == 0:
        plt.scatter(x_test[i, 0], x_test[i, 1], c='r')  # 标签为0的样本点
    else:
        plt.scatter(x_test[i, 0], x_test[i, 1], c='g')  # 标签为1的样本点

plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2019-04-04 17:57:26 weixin_44530236 阅读数 107
  • 机器学习入门30天实战

    购买课程后,可扫码进入学习群,获取唐宇迪老师答疑 系列课程包含Python机器学习库,机器学习经典算法原理推导,基于真实数据集案例实战3大模块。从入门开始进行机器学习原理推导,以通俗易懂为基础形象解读晦涩难懂的机器学习算法工作原理,案例实战中使用Python工具库从数据预处理开始一步步完成整个建模工作!具体内容涉及Python必备机器学习库、线性回归算法原理推导、Python实现逻辑回归与梯度下降、案例实战,信用卡欺诈检测、决策树与集成算法、支持向量机原理推导、SVM实例与贝叶斯算法、机器学习常规套路与Xgboost算法、神经网络。

    7609 人正在学习 去看看 唐宇迪

算法原理

K均值聚类(K-Means)算法的核心步骤如下:

  1. 将数据集{D}中随机取K个元素,作为K个簇的各自的中心。
  2. 分别计算剩下的元素到K个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
  3. 根据聚类结果,重新计算K个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
  4. 将{D}中全部元素按照新的中心重新聚类。
  5. 重复第 4 步,直到每个簇的中心基本不再变化。
  6. 将结果输出。

K均值聚类(K-Means)算法的特点如下:

  • 计算伸缩性: 算法复杂度不高,算法收敛速度快,聚类效果好;
  • 参数依赖性: 可控制的参数较少(仅簇数k), 调参简单;
  • 普适性能力: 泛化能力一般,容易受到噪音干扰;
  • 抗噪音能力: 需要考虑局部最优问题,异常数据干扰问题等;
  • 结果解释性: 模型和结果均具有解释性。
     

sklearn.cluster.KMeans(n_clusters=8, init=’k-means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm=’auto’)

主要参数含义:

  1. n_clusters: 即k值,一般需要多试一些值以获得较好的聚类效果。
  2. max_iter: 最大的迭代次数,一般如果是凸数据集的话可以不管这个值,如果数据集不是凸的,可能很难收敛,此时可以指定最大的迭代次数让算法可以及时退出循环。 
  3. n_init:用不同的初始化质心运行算法的次数。由于K-Means是结果受初始值影响的局部最优的迭代算法,因此需要多跑几次以选择一个较好的聚类效果,默认是10,一般不需要改。如果你的k值较大,则可以适当增大这个值。 
  4. init: 即初始值选择的方式,可以为完全随机选择’random’,优化过的’k-means++’或者自己指定初始化的k个质心。一般建议使用默认的’k-means++’。 
  5. algorithm:有“auto”, “full” or “elkan”三种选择。”full”就是我们传统的K-Means算法, “elkan”是elkan K-Means算法。默认的”auto”则会根据数据值是否是稀疏的,来决定如何选择”full”和“elkan”。一般数据是稠密的,那么就是 “elkan”,否则就是”full”。一般来说建议直接用默认的”auto”。
  6. n_jobs:并发次数。

from sklearn import datasets
iris = datasets.load_iris()
iris_data = iris.data

print(iris_data)

array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [6.5, 3. , 5.2, 2. ],
       [6.2, 3.4, 5.4, 2.3],
       [5.9, 3. , 5.1, 1.8]])

#归一化
from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
data = min_max_scaler.fit_transform(iris_data)
print(data)

[[0.22222222 0.625      0.06779661 0.04166667]
 [0.16666667 0.41666667 0.06779661 0.04166667]
 [0.11111111 0.5        0.05084746 0.04166667]
 [0.61111111 0.41666667 0.71186441 0.79166667]
 [0.52777778 0.58333333 0.74576271 0.91666667]
 [0.44444444 0.41666667 0.69491525 0.70833333]]

#取两个维度,对比一下聚类结果和真实分类
X = iris_data[:,2:]
X_2 = min_max_scaler.fit_transform(X)
cluster = KMeans(n_clusters=3)
cluster.fit(X_2)
y_p = cluster.predict(X_2)
plt.scatter(X_2[:,0], X_2[:,1], c=y_p)
plt.show()

plt.scatter(X[:,0], X[:,1], c=data_label)
plt.show()

#训练模型
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3)
kmeans.fit(data)

KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
    n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto',
    random_state=None, tol=0.0001, verbose=0)

#聚类结果
kmeans.labels_

array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0,
       0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0,
       0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2])

#簇的中心点
kmeans.cluster_centers_

array([[0.70726496, 0.4508547 , 0.79704476, 0.82478632],
       [0.19611111, 0.595     , 0.07830508, 0.06083333],
       [0.44125683, 0.30737705, 0.57571548, 0.54918033]])

#样本到最近的聚类中心的距离总和
kmeans.inertia_

6.982216473785234

import pandas as pd
r1 = pd.Series(kmeans.labels_).value_counts()    #统计聚类后各个类别的个数
r2 = pd.DataFrame(kmeans.cluster_centers_)       #聚类中心
r = pd.concat([r2, r1], axis=1)      #聚类中心对应类别下的个数,axis=1表示横向连接,0是纵向连接
print(r)

          0         1         2         3   0
0  0.707265  0.450855  0.797045  0.824786  39
1  0.196111  0.595000  0.078305  0.060833  50
2  0.441257  0.307377  0.575715  0.549180  61

import numpy as np
res = np.column_stack((data, kmeans.labels_))   
#res = np.c_[data, kmeans.labels_]   #同上一条语句一样的功能
print(res)

[[0.22222222 0.625      0.06779661 0.04166667 1.        ]
 [0.16666667 0.41666667 0.06779661 0.04166667 1.        ]
 [0.11111111 0.5        0.05084746 0.04166667 1.        ]
 [0.61111111 0.41666667 0.71186441 0.79166667 0.        ]
 [0.52777778 0.58333333 0.74576271 0.91666667 0.        ]
 [0.44444444 0.41666667 0.69491525 0.70833333 2.        ]]

data_iris = pd.DataFrame(iris_data, columns=iris.feature_names)
print(data_iris)

   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)
0                  5.1               3.5                1.4               0.2
1                  4.9               3.0                1.4               0.2
2                  4.7               3.2                1.3               0.2
147                6.5               3.0                5.2               2.0
148                6.2               3.4                5.4               2.3
149                5.9               3.0                5.1               1.8

# pandas绘制密度概率图,聚类结果在不同维度上的密度分布
def density_plot(data,k): 
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    # subplots=True表示dataframe格式的数据中每一列绘制一幅子图 
    p = data.plot(kind='kde', linewidth=2,  title='class=%d'%k, subplots=True, sharex=False,figsize=(6,9))
    # p[i]代表第i个子图
    [p[i].set_ylabel(u'密度') for i in range(4)]
    plt.legend()
    return plt

for i in range(3):
    density_plot(data_iris[kmeans.labels_ == i],i)

# 对比一下每个聚类结果在相同维度上的密度分布
def density_plot(data,k,max): 
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号  
    p = data.plot(kind='kde', linewidth=2,  title='class=%d'%k, xlim=[0,max],figsize=(4,2))
    p.set_ylabel(u'密度')
    plt.legend()
    return plt    
for c in data_iris.columns:
    data_tem = data_iris.loc[:,[c]]
    max_x = max(data_iris.loc[:,c])+1
    for i in range(3):
        density_plot(data_tem[kmeans.labels_==i],i,max_x)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2018-05-13 21:22:17 XiaoYi_Eric 阅读数 2064
  • 机器学习入门30天实战

    购买课程后,可扫码进入学习群,获取唐宇迪老师答疑 系列课程包含Python机器学习库,机器学习经典算法原理推导,基于真实数据集案例实战3大模块。从入门开始进行机器学习原理推导,以通俗易懂为基础形象解读晦涩难懂的机器学习算法工作原理,案例实战中使用Python工具库从数据预处理开始一步步完成整个建模工作!具体内容涉及Python必备机器学习库、线性回归算法原理推导、Python实现逻辑回归与梯度下降、案例实战,信用卡欺诈检测、决策树与集成算法、支持向量机原理推导、SVM实例与贝叶斯算法、机器学习常规套路与Xgboost算法、神经网络。

    7609 人正在学习 去看看 唐宇迪

1.KNN简介

K近邻(K-Nearest Neighbors, KNN)算法既可处理分类问题,也可处理回归问题,其中分类和回归的主要区别在于最后做预测时的决策方式不同。KNN做分类预测时一般采用多数表决法,即训练集里和预测样本特征最近的K个样本,预测结果为里面有最多类别数的类别。KNN做回归预测时一般采用平均法,预测结果为最近的K个样本数据的平均值。其中KNN分类方法的思想对回归方法同样适用,因此本文主要讲解KNN分类问题,下面我们通过一个简单例子来了解下KNN算法流程。

如下图所示,我们想要知道绿色点要被决定赋予哪个类,是红色三角形还是蓝色正方形?我们利用KNN思想,如果假设K=3,选取三个距离最近的类别点,由于红色三角形所占比例为2/3,因此绿色点被赋予红色三角形类别。如果假设K=5,由于蓝色正方形所占比例为3/5,因此绿色点被赋予蓝色正方形类别。
01
从上面实例,我们可以总结下KNN算法过程

  1. 计算测试数据与各个训练数据之间的距离。
  2. 按照距离的递增关系进行排序,选取距离最小的K个点。
  3. 确定前K个点所在类别的出现频率,返回前K个点中出现频率最高的类别作为测试数据的预测分类。

从KNN算法流程中,我们也能够看出KNN算法三个重要特征,即距离度量方式、K值的选取和分类决策规则。

  • 距离度量方式: KNN算法常用欧式距离度量方式,当然我们也可以采用其他距离度量方式,比如曼哈顿距离,相应公式如下所示。

D(x,y)=(x1y1)2+(x2y2)2+...+(xnyn)2=i=1n(xiyi)2 D(x,y)=\sqrt{(x_1-y_1)^2+(x_2-y_2)^2+...+(x_n-y_n)^2}=\sqrt{\sum_{i=1}^{n}(x_i-y_i)^2}

D(x,y)=x1y1+x2y2+x3y3...+xnyn=i=1nxiyi D(x,y)={|x_1-y_1|+|x_2-y_2|+|x_3-y_3|...+|x_n-y_n|}={\sum_{i=1}^{n}|x_i-y_i|}

  • K值的选取: KNN算法决策结果很大程度上取决于K值的选择。选择较小的K值相当于用较小领域中的训练实例进行预测,训练误差会减小,但同时整体模型变得复杂,容易过拟合。选择较大的K值相当于用较大领域中训练实例进行预测,可以减小泛化误差,但同时整体模型变得简单,预测误差会增大。
  • 分类决策规则: KNN分类决策规则经常使用我们前面提到的多数表决法,在此不再赘述。

KNN要选取前K个最近的距离点,因此我们就要计算预测点与所有点之间的距离。但如果样本点达到几十万,样本特征有上千,那么KNN暴力计算距离的话,时间成本将会很高。因此暴力计算只适合少量样本的简单模型,那么有没有什么方法适用于大样本数据,有效降低距离计算成本呢?那是当然的,我们下面主要介绍KD树和球树方法。

2.KD树原理

KD树算法没有一开始就尝试对测试样本进行分类,而是先对训练集建模,建立的模型就是KD树,建立好模型之后再对测试集做预测。KD树就是K个特征维度的树,注意KD树中K和KNN中的K意思不同。KD树中的K代表样本特征的维数,为了防止混淆,后面我们称KD树中特征维数为n。KD树可以有效减少最近邻搜索次数,主要分为建树、搜索最近邻、预测步骤,下面我们对KD树进行详细讲解。

2.1KD树建立

下述为KD树构建步骤,包括寻找划分特征、确定划分点、确定左子空间和右子空间、递归构建KD树。

  1. 寻找划分特征: KD树是从m个样本的n维特征中,分别计算n个特征取值的方差,用方差最大的第k维特征nk来作为根节点。
  2. **确定划分点:**选择特征nk的中位数nkv所对应的样本作为划分点。
  3. **确定左子空间和右子空间:**对于所有第k维特征取值小于nkv的样本划入左子树,所有第k维特征取值大于nkv的样本划入右子树。
  4. **递归构建KD树:**对于左子树和右子树,采用和上述同样的方法来找方差最大的特征生成新节点,递归的构建KD树。

我们举例来说明KD树构建过程,假如有二维样本6个,分别为{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},KD树过程构建过程如下

  1. 寻找划分特征: 6个数据点在x,y维度上方差分别为6.97,5.37,x轴上方差更大,用第1维度特征建树。
  2. **确定划分点:**根据x维度上的值将数据排序,6个数据中x的中值为7,所以划分点数据为(7,2),该节点的分割超平面便是x=7直线。
  3. **确定左子空间和右子空间:**分割超平面x=7将空间分为两部分。x<=7的部分为左子空间,包含节点为{(2,3),(5,4),(4,7)}。x>7的部分为右子空间,包含节点为{(9,6),(8,1)}。
  4. **递归构建KD树:**用同样的方法划分左子树{(2,3),(5,4),(4,7)}和右子树{(9,6),(8,1)},最终得到KD树。
    02
    03

2.2KD树搜索最近邻

当我们生成KD树后,就可以预测测试样本集里面的样本目标点。

  1. 二叉搜索:对于目标点,通过二叉搜索,能够很快在KD树里面找到包含目标点的叶子节点
  2. 回溯:为找到最近邻,还需要进行回溯操作,算法沿搜索路径反向查找是否有距离查询点更近的数据点。以目标点为圆心,目标点到叶子节点的距离为半径,得到一个超球体,最邻近点一定在这个超球体内部。
  3. **更新最近邻:**返回叶子节点的父节点,检查另一叶子节点包含的超矩形体是否和超球体相交,如果相交就到这个子节点中寻找是否有更近的最近邻,有的话就更新最近邻。如果不相交就直接返回父节点的父节点,在另一子树继续搜索最近邻。当回溯到根节点时,算法结束,此时保存的最近邻节点就是最终的最近邻。

为方便理解上述过程,我们利用2.1建立的KD树来寻找(2,4.5)的最近邻。

  1. **二叉搜索:**首先从(7,2)节点查找到(5,4)节点。由于目标点y=4.5,同时分割超平面为y=4,因此进入右子空间(4,7)进行查找,形成搜索路径{(7,2)->(5,4)->(4,7)}。
  2. **回溯:**节点(4,7)与目标查找点距离为3.202,回溯到父节点(5,4)与目标查找点之间距离为3.041,所以(5,4)为查询点的最近邻。以目标点(2,4.5)为圆心,以3.041为半径作圆,最近邻一定在超球体内部。
  3. **更新最近邻:**该圆和y = 4超平面交割,所以需要进入(5,4)左子空间进行查找,将(2,3)节点加入搜索路径{(7,2)->(2,3)}。回溯至(2,3)叶子节点,(2,4.5)到(2,3)的距离比到(5,4)要近,所以最近邻点更新为(2,3),最近距离更新为1.5。回溯至(7,2),以(2,4.5)为圆心,1.5为半径作圆,发现并不和x = 7分割超平面交割,至此搜索路径回溯完成,完成更新最近邻操作,返回最近邻点(2,3)。

04

2.3KD树预测

根据KD树搜索最近邻的方法,我们能够得到第一个最近邻数据点,然后把它置为已选。然后忽略置为已选的样本,重新选择最近邻,这样运行K次,就能得到K个最近邻。如果是KNN分类,根据多数表决法,预测结果为K个最近邻类别中有最多类别数的类别。如果是KNN回归,根据平均法,预测结果为K个最近邻样本输出的平均值。

3.球树原理

KD树算法能够提高KNN搜索效率,但在某些时候效率并不高,比如处理不均匀分布的数据集时。如下图所示,如果黑色的实例点离目标点(星点)再远一点,那么虚线会像红线那样扩大,导致与左上方矩形的右下角相交。既然相交那就要检查左上方矩形,而实际上最近的点离目标点(星点)很近,检查左上方矩形区域已是多余。因此KD树把二维平面划分成矩形会带来无效搜索的问题。
05
为优化超矩形体带来的搜索效率问题,我们在此介绍球树算法来进一步提高最近邻搜索效率。

3.1球树建立

球树的每个分割块都是超球体,而不像KD树中的超矩形体,这样在做最近邻搜索是可以避免无效搜索,下面我们介绍球树构建过程

  1. **构建超球体:**超球体是可以包含所有样本的最小球体。
  2. **划分子超球体:**从超球体中选择一个离超球体中心最远的点,然后选择第二个点离第一个点最远,将球中所有的点分配到离这两个聚类中心最近的一个。然后计算每个聚类的中心,以及聚类能够包含它所有数据点所需的最小半径,这样我们便得到两个子超球体,和KD树中的左右子树对应。
  3. **递归:**对上述两个子超球体,递归执行步骤2,最终得到球树。
    06

3.2球树搜索最近邻

KD树在搜索路径优化时使用的是两点之间的距离来判断,而球树使用的是两边之和大于第三边来判断。相对来说球树的判断更加复杂,但却避免一些无效的搜索,下述为球树搜索最近邻过程。

  1. 自上而下贯穿整棵树找出包含目标点所在的叶子,并在这个球里找出与目标点最邻近的点,这将确定目标点距离最邻近点的上限值。
  2. 然后和KD树查找相同,检查兄弟结点,如果目标点到兄弟结点中心的距离超过兄弟结点的半径与当前的上限值之和,那么兄弟结点里不可能存在一个更近的点。否则进一步检查位于兄弟结点以下的子树。
  3. 检查完兄弟节点后,向父节点回溯,继续搜索最小邻近值。当回溯到根节点时,此时的最小邻近值就是最终的搜索结果。

3.3球树预测

根据球树搜索最近邻的方法,我们能够得到第一个最近邻数据点,然后把它置为已选。然后忽略置为已选的样本,重新选择最近邻,这样运行K次,就能得到K个最近邻。如果是KNN分类,根据多数表决法,预测结果为K个最近邻类别中有最多类别数的类别。如果是KNN回归,根据平均法,预测结果为K个最近邻样本输出的平均值。

4.KNN算法扩展

有时我们会遇到样本中某个类别数的样本非常少,甚至少于我们实现定义的K,这将导致稀有样本在找K个最近邻的时候会把距离较远的无关样本考虑进来,进而导致预测不准确。为解决此类问题,我们先设定最近邻的一个最大距离,也就是说,我们在一定范围内搜索最近邻,这个距离称为限定半径。

5.Sklearn实现KNN算法

下述代码是利用iris数据进行分类,我们经常需要通过改变参数来让模型达到分类结果,具体参数设置可参考sklearn官方教程

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

#load iris data
iris=load_iris()
X=iris.data
y=iris.target
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=1)

knn=KNeighborsClassifier(algorithm='kd_tree')
knn.fit(X_train,y_train)
print(knn.predict(X_test))
# [0 1 1 0 2 1 2 0 0 2 1 0 2 1 1 0 1 1 0 0 1 1 1 0 2 1 0 0 1 2 1 2 1 2 2 0 1
#  0 1 2 2 0 1 2 1]
print(y_test)
# [0 1 1 0 2 1 2 0 0 2 1 0 2 1 1 0 1 1 0 0 1 1 1 0 2 1 0 0 1 2 1 2 1 2 2 0 1
#  0 1 2 2 0 2 2 1]
print(knn.score(X_test,y_test))
# 0.977777777778

6.KNN优缺点

6.1优点

  • 即可处理分类也可处理回归问题。
  • 对数据没有假设,准确度高,对异常点不敏感。
  • 比较适合样本容量大的类域进行自动分类,对样本容量较小的类域容易产生误分。
  • 主要靠周围有限的邻近样本进行分类或回归,比较适合类域交叉或重叠较多的待分样本集。

6.2缺点

  • 计算量大,尤其是特征维数较多时候。
  • 样本不平衡时,对稀有类别的预测准确率低。
  • KD树、球树之类的模型建立时需要大量的内存。
  • 使用懒惰学习方法,基本上不学习,导致预测时速度较慢。

7.推广

更多内容请关注公众号谓之小一,若有疑问可在公众号后台提问,随时回答,欢迎关注,内容转载请注明出处。
推广
参考

刘建平Pinard_K近邻法(KNN)原理小结

Yabea_K-近邻(KNN)算法

2019-04-16 18:48:45 Autopilot 阅读数 101
  • 机器学习入门30天实战

    购买课程后,可扫码进入学习群,获取唐宇迪老师答疑 系列课程包含Python机器学习库,机器学习经典算法原理推导,基于真实数据集案例实战3大模块。从入门开始进行机器学习原理推导,以通俗易懂为基础形象解读晦涩难懂的机器学习算法工作原理,案例实战中使用Python工具库从数据预处理开始一步步完成整个建模工作!具体内容涉及Python必备机器学习库、线性回归算法原理推导、Python实现逻辑回归与梯度下降、案例实战,信用卡欺诈检测、决策树与集成算法、支持向量机原理推导、SVM实例与贝叶斯算法、机器学习常规套路与Xgboost算法、神经网络。

    7609 人正在学习 去看看 唐宇迪

1.模型评估
在样本数为m时,既要进行训练,又要进行测试的解决方案。
1.1留出法:
将原先数据集按照一定的比例划分成训练集和测试集,常见的为2/3,4/5。
优化:可进行若干次随机划分,独立同分布进行分层采样,进行评估后取其平均值。
1.2交叉验证法:
将数据集划分成K个大小相似且互斥的子集,用K-1的子集进行训练,剩下的当做测试集。进行K次训练
当K为样本数时,称为‘留一法’,优点:结果较为准备。缺点:训练时长过长。
1.3自助采样法
进行m次随机从样本中选择一个样本加入到训练集D’中,然后将该样本放回原先数据集,最后将未出现在训练集中的样本当做测试集使用。
经过调参之后获得的较优模型,记录此时的算法及参数,用原先的数据集再次进行训练。
2.模型性能度量
2.1错误率
2.2正确率
2.3查准率:选出来的有多少是正确的(P)
2.4查全率:选出来的占所有正确的比例(R)
可通过P-R曲线对比模型好坏
若A曲线包括B曲线,则认为A的性能更好
根据平衡点进行判断
根据面积进行判读
根据需求进行判断
2.5ROC曲线
对预测的样本置信度进行排序
TP真正例 FN假反例
FP假正例 TN真反例
纵轴:真正例率 TPR: TP/(TP+FN) P
横轴:假正例率 FPR: FP/(FP+TN) 1-P
3.代价敏感矩阵

2017-09-14 19:36:15 zhangt85 阅读数 278
  • 机器学习入门30天实战

    购买课程后,可扫码进入学习群,获取唐宇迪老师答疑 系列课程包含Python机器学习库,机器学习经典算法原理推导,基于真实数据集案例实战3大模块。从入门开始进行机器学习原理推导,以通俗易懂为基础形象解读晦涩难懂的机器学习算法工作原理,案例实战中使用Python工具库从数据预处理开始一步步完成整个建模工作!具体内容涉及Python必备机器学习库、线性回归算法原理推导、Python实现逻辑回归与梯度下降、案例实战,信用卡欺诈检测、决策树与集成算法、支持向量机原理推导、SVM实例与贝叶斯算法、机器学习常规套路与Xgboost算法、神经网络。

    7609 人正在学习 去看看 唐宇迪

  k均值算法的计算过程非常直观:

      1、从D中随机取k个元素,作为k个簇的各自的中心。

      2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。

      3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。

      4、将D中全部元素按照新的中心重新聚类。

      5、重复第3,4步,直到聚类结果不再变化。

      6、将结果输出。


相似度计算:

方法1:欧式距离


方法2:曼哈顿距离



方法3:闵可夫斯基距离



这里有一个问题,就是不同维度的属性取值范围不同,对于最终结果的计算结果影响有偏差,所以需要进行规格化。所谓规格化就是将各个属性值按比例映射到相同的取值区间,这样是为了平衡各个属性对距离的影响。通常将各个属性均映射到[0,1]区间

映射公式:


其中max(ai)和min(ai)表示所有元素项中第i个属性的最大值和最小值


没有更多推荐了,返回首页