机器学习常用算法-k近邻算法

概述

今天介绍一下机器学习常用算法,以及常用的数据处理技巧等。我们都知道机器学习针对特定任务从经验中学习,并且使得我们的任务效果越来越好。我们看一机器学习的workflow,如下所示: 数据采集和标记->数据清洗->特征选择->模型选择->模型训练和测试->模型性能评估和优化->模型使用即上线。 我们一般通过Python来实现机器学习常用算法的程序,所以基于Python语言常用的机器学习类库及其第三方扩展库有:IPython,Jupyter,numpy,matplotlib,scipy,scikit-learn,seaborn。 我们先安装这些类库即。

pip install ipython,jupyter,numpy,matplotlib,scipy,scikit-learn,seaborn

下面我们来简单的介绍一下这几个类库。

类库了解

ipython

1.ipython是一种探索性编程的类库,它可以非常方便的执行你的python代码。快捷键和魔法用法可以自己百度和google,介绍一个常用的技巧就是通过魔法函数可以直接启用魔法命令,不用每次执行魔法命令时键入%。

%automagic on
pwd
cd

2.可视化的嵌套可以通过。

%matplotlib inline

numpy

Numpy 是Python计算机科学基础库,里面有很多的数学算法。

import numpy as np

a = np.array([[1,2,4],[1,2,3]])
a.shape,a.ndim,a.dtype
#分别是多维数据的维度,轴和数据类型
(2, 3), 2, dtype('int64')

numpy是共享内存的,如果需要独立保存则需要显式的备份。可以通过np.may_share_memory(),判断两个数组是否是共享内存。

a = np.arange(10)
b = a[2:5]
np.may_share_memory(a,b)
#输出
True
b = a[2:5].copy()
np.may_share_memory(a,b)
#输出
False

关于轴的问题,numpy的多维数组是面向轴处理的。例如:

a = np.random.randint(1,5,(4,6))
print(a)
#输出
array([[2, 4, 2, 3, 4, 3],
       [2, 2, 1, 3, 4, 2],
       [1, 3, 1, 1, 3, 1],
       [1, 3, 3, 2, 3, 3]])
#面向轴处理,axis=0代表按行处理,axis=1面向列处理。
print(a.sum(axis=0),a.sum(axis=1))
#输出
(array([ 6, 12,  7,  9, 14,  9]), array([18, 14, 10, 15]))

还有一个经常使用的用法就是按照array的维度操作。比如:

a = np.arange(12)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
b = a.reshape((3,4))
array([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
b.ravel()
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]))
b=a[:,np.newaxis]
array([[ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5],
       [ 6],
       [ 7],
       [ 8],
       [ 9],
       [10],
       [11]])

排序,排序不仅支持按照值排序而且还通过index返回。比如

a=np.array([10,3,4,7,12])
a.argsort()
#输出
array([1, 2, 3, 0, 4])

我在Numpy 数据处理一文中介绍了一些常用的用法,或者参考它的官方文档。

pandas

关于pandas的技巧,可以参考Pandass 数据处理

matplotlib 和 sklearn

官方文档已经非常全面了,建议参考官方文档。

算法

在之前我们已经介绍了机器学习算法理论,下面我们介绍两个几个重要的关键术语。过拟合:模型能很好的拟合训练数据,但是对于新数据或者测试数据的预测准确性较差。欠拟合:模型不能很好的拟合训练样本且对新数据或者测试数据的预测准确性较差。相对应的我们一般称欠拟合为高偏差,过拟合称为高方差。我们现在常用的机器学习算法是通过模型算法成本来反馈(反推)模型参数,使得在成本函数或者代价函数最低的情况下,寻找最优的模型参数。比如:

J_{test}(\theta)=\frac 1{2m}\sum_{i=0}^m(h_\theta(x^{(i)})-y^{i})^2

我们通过模型在数据集上的最少成本来求解最优模型参数。

算法评价

我们在采用机器学习应用业务时,我们通常通过交叉验证数据集来衡量模型,即:训练数据集:交叉验证数据集:测试数据集=6:2:2在模型选择时,使用训练数据集来训练算法参数,用交叉验证集来验证参数,选择交叉验证集的成本J最下的算法作为数据拟合模型,最后再用测试数据集来测试选择出来的模型准确性。但是在实践中,大多数直接将数据集分成训练数据集和测试数据集,而没有交叉验证数据集,主要是大多数时候并不需要横向对比不同的模型。在工程上,我们最主要的工作不是选择模型,而是获取更多的数据、分析数据以及数据挖掘。

学习曲线

学习曲线是观察模型准确率与训练数据集关系。步骤: 1.将数据集分为训练数据集和交叉验证数据集。 2.取训练数据集的20%作为训练样本,训练出模型参数。 3.使用交叉验证数据集来计算训练出来的模型的准确率。 4.以训练数据集的准确性,交叉验证的准确性作为纵坐标,训练数据集个数作为横坐标,在坐标轴画出。 5.训练数据集增加10%,跳到第三步骤继续执行,知道训练数据集大小为100%为止。 在详细的机器学习算法里面,我们会画出一个学习曲线。一般我们会通过学习曲线,来判断算法是高偏差还是高方差。 对于过拟合一般采取的方法: 1.获取更多的训练数据。 2.减少输入的特征数。 对于欠拟合一般采取的方法: 1.增加有价值的特征。 2.增加多项式特征。

查准率和召回率

除了学习曲线外,我们一般还会通过查准率和召回率来评价一个算法的好坏。比如关于一个肿瘤预测的实例中: 预测数据/实际数据 实际恶性肿瘤 实际良性肿瘤 预测恶性肿瘤 TruePositive FalsePositive 预测良性肿瘤 FalseNegative TrueNegative

Precision=\frac {TruePositive}{TruePositive+FalsePositive} Recall=\frac {TruePositive}{TruePositive+FalseNegative} F_1Score=2\frac{PR}{P+R}

K-近邻算法

k-近邻算法是针对未标记的样本类别,由距离其最近的k个邻居投票决定的。优点:准确性高,对异常值和噪声有较高的的容忍度。缺点:计算量较大,对内存的需求较大。一般而言,k值越大,模型的偏差越大,对噪声数据越不敏感,当k值很大时,可能造成欠拟合;k值越小,模型的方差越大,当k值太小时容易造成过拟合。我们通过k-近邻算法来进行糖尿病预测。数据集为diabetes.csv,我们依次来看一下。 1.加载数据

data_path="diabetes.csv"
import pandas as pd
data = pd.read_csv(data_path)
data.head()

数据的8个特征分别为

  • Pregnancies:怀孕的次数
  • Glucose:血浆葡糖糖浓度。
  • BloodPressure:舒张压(单位毫米)
  • SkinThickness:肱三头肌厚度(单位毫米)
  • Insulin:两个小时的血清胰岛素(单位毫升)
  • BMI:身体质量指数,体重除以身高的平方。
  • DiabetesPedigreeFunction:糖尿病血统指数。
  • Age 年龄
  • Outcome:结果标记值,0表示没有糖尿病,1表示有糖尿病。

我们可以看一下实例数据。

data.shape
(768,9)
ata.groupby("Outcome").size()
Outcome
0    500
1    268
dtype: int64

其中阳性有500个,阴性有268个。我们将数据集分类出来方便我们训练和衡量。

#只含有特征的数据集
x=data.iloc[:,0:8]
#标记数据
y=data.iloc[:,8]
print('shape of x {};shape of y {}'.format(x.shape,y.shape))
#输出 shape of x (768, 8);shape of y (768,)
from sklearn.model_selection import train_test_split
#将数据集划分为训练数据集和测试数据集,其中测试数据集为20%。
x_train,x_test,y_trian,y_test = train_test_split(x,y,test_size=0.2)

2.模型选择 我们使用三种算法对数据进行拟合即普通的k-均值算法,带权重的k-均值算法和指定半径的k-均值算法。

from sklearn.neighbors import KNeighborsClassifier,RadiusNeighborsClassifier
models=[]
models.append(("KNN",KNeighborsClassifier(n_neighbors=2)))
models.append(("KNN with weights",KNeighborsClassifier(n_neighbors=2,weights="distance")))
models.append(("Radius Neighbors",RadiusNeighborsClassifier(n_neighbors=2,radius=500)))
results=[]
for name,model in models:
    model.fit(x_train,y_trian)
    results.append((name,model.score(x_test,y_test)))
for i in range(len(results)):
    print("name:{};score:{}".format(results[i][0],results[i][1]))
#输出
name:KNN;score:0.7142857142857143
name:KNN with weights;score:0.6168831168831169
name:Radius Neighbors;score:0.6948051948051948

因为训练样本和测试样本是随机分配的,那么如何衡量模型呢?所以我们需要多次分配训练数据集和交叉验证数据集,然后对多次预测结果进行平均。

#kfold 将数据分成10份,其中一份作为交叉验证数据集来计算模型准确性。
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
results=[]
for name,model in models:
    kfold=KFold(n_splits=10)
    cv_result=cross_val_score(model,x,y,cv=kfold)
    results.append((name,cv_result))
for i in range(len(results)):
    print("name:{};score:{}".format(results[i][0],results[i][1].mean()))

我们采用普通的k-近邻算法。 3.模型分析 我们分别对训练集和测试集进行分析,如下:

knn = KNeighborsClassifier(n_neighbors=2)
knn.fit(X=x_train,y=y_trian)
train_score=knn.score(x_train,y_trian)
test_score=knn.score(x_test,y_test)
print("train score {};test score {}".format(train_score,test_score))
#输出
train score 0.8289902280130294;test score 0.7142857142857143

一是模型在训练样本上表现不佳,这说明算法太简单。二是在测试集的准确性欠佳。 我们下面通过学习曲线来看一下:

from sklearn.model_selection import learning_curve
import numpy as np
import matplotlib.pyplot as plt

def plot_learning_curve(plt, estimator, title, X, y, ylim=None, cv=None,n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel("Training examples")
    plt.ylabel("Score")
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid()

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.1,
                     color="r")
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.1, color="g")
    plt.plot(train_sizes, train_scores_mean, 'o--', color="r",
             label="Training score")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
             label="Cross-validation score")

    plt.legend(loc="best")
    return plt

cv=ShuffleSplit(n_splits=10,test_size=0.2,random_state=0)
plt.figure(figsize=(10,6),dpi=64)
plot_learning_curve(plt,knn,"cure",x,y,ylim=(0.0,1.01),cv=cv)
plt.show()

我们能看到学习曲线,和我们的之前的模型分析的结果是一致的。如下图所示:

后面我们会介绍如何提高该算法准确率。 4.特征可视化和分析 有时候我们想通过将最相关的一个或者多个特征选择出来进行可视化分析,那么如何选择最相关的特征呢?我们一般通过如下方法:

from sklearn.feature_selection import SelectKBest
selector = SelectKBest(k=2)
x_new=selector.fit_transform(x,y)
results=[]
for name,model in models:
    kfold=KFold(n_splits=10)
    cv_result=cross_val_score(model,x_new,y,cv=kfold)
    results.append((name,cv_result))
for i in range(len(results)):
    print("name:{};score:{}".format(results[i][0],results[i][1].mean()))
#输出
name:KNN;score:0.725205058099795
name:KNN with weights;score:0.6900375939849623
name:Radius Neighbors;score:0.6510252904989747

然后可以将这两个特征和输出标记投影在坐标轴上,看一下数据分布。可以看到数据分布和重叠性很大,所以选择k-近邻算法无法达到一个很好的预测准确性。 这里的最相关的特征选择主要采用了统计学上的相关性检验,比如:卡方检验、t检验。

总结

通过一个简单的例子对机器学习的常用算法-k近邻算法有了一个整体上的了解。下面我们介绍一下另外一个常用算法:线性回归参考 1.《scikit-learning 机器学习》 2.scikit learning 3.《机器学习导论》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专知

【干货】一种直观的方法认识梯度下降

【导读】本文是深度学习专家Thalles Silva分享的一篇技术博客,主要讲解机器学习算法中的梯度下降。首先从形象的角度介绍梯度下降:梯度、偏导数等。然后,根...

3776
来自专栏人工智能LeadAI

BAT机器学习面试1000题系列(第150~279题)

长文~可先收藏再看哟~ 150、在感知机中(Perceptron)的任务顺序是什么?深度学习 DL基础 易 1 随机初始化感知机的权重 2 去到数据集的下一批(...

1.8K9
来自专栏机器学习算法与Python学习

收藏 | 数据分析师最常用的10个机器学习算法!

在机器学习领域,有种说法叫做“世上没有免费的午餐”,简而言之,它是指没有任何一种算法能在每个问题上都能有最好的效果,这个理论在监督学习方面体现得尤为重要。

814
来自专栏人工智能LeadAI

机器学习算法集锦

摘要: 机器学习 机器学习(Machine Learning, ML)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研...

3295
来自专栏书山有路勤为径

Optimization Algorithms

机器学习应用是一个高度依赖经验并伴随着大量迭代的过程——这一句话不得不同意,经验更重要,深有体会。你需要训练诸多模型才能找到合适的那一个。深度学习没有在大数据领...

411
来自专栏人工智能

随机计算图:连续案例

去年我介绍了一些现代的变分推理理论。 这些方法通常与深度神经网络结合使用,形成深度生成模型(例如VAE),或者利用随机控制丰富确定性模型,从而导致更好的探索。 ...

2580
来自专栏一心无二用,本人只专注于基础图像算法的实现与优化。

图像增强系列之图像自动去暗角算法。

  暗角图像是一种在现实中较为常见的图像,其主要特征就是在图像四个角有较为显著的亮度下降,比如下面两幅图。根据其形成的成因,主要有3种:natural vign...

3929
来自专栏灯塔大数据

塔秘 | 极简Python带你探索分类与回归的奥秘

前言 本文从分类和回归两个方面介绍了基本的监督学习方法,并用Scikit-Learn做了实例演示。 ? 为何使用人工智能和机器学习? 地球的未来在于人工智能和机...

38212
来自专栏企鹅号快讯

新手必备!十大机器学习算法之旅已启程

【IT168 资讯】在机器学习中,有一种叫做“没有免费的午餐”的定理。简而言之,它指出没有任何一种算法能够适用每一个问题,而且它对于监督式学习(即预测性建模)尤...

1947
来自专栏PPV课数据科学社区

数据科学家最常用的十大机器学习算法

在机器学习领域,有种说法叫做“世上没有免费的午餐”,简而言之,它是指没有任何一种算法能在每个问题上都能有最好的效果,这个理论在监督学习方面体现得尤为重要。

1232

扫码关注云+社区