Python机器学习入门开发权威简介

本文概述

你将在著名的Iris数据集上实现KNN。

注意:你可能需要考虑学习使用Python进行机器学习的课程, 或者想了解ML的发展背景, 更多的读者可以考虑阅读本文。

介绍

机器学习源于计算机科学, 它主要研究可以从经验中学到的算法的设计。要学习, 他们需要具有某些属性的数据, 算法会根据这些属性尝试找到一些有意义的预测模式。机器学习任务主要可以归类为概念学习, 聚类, 预测建模等。机器学习算法的最终目标是能够在没有任何人工干预的情况下做出决策。预测库存或天气是机器学习算法的两个应用。

有各种机器学习算法, 例如决策树, 朴素贝叶斯, 随机森林, 支持向量机, K最近邻, K均值聚类等。

从机器学习算法的类别来看, 你今天要使用的是k近邻算法。

现在, 问题是什么是K最邻近算法, 所以让我们找出答案!

什么是k最近邻?

KNN或K最邻近算法是一种有监督的学习算法, 通过监督, 它意味着在学习阶段它利用了训练数据的类别标签。它是一种基于实例的机器学习算法, 其中, 新数据点基于已存储的标记实例(数据点)进行分类。 KNN可用于分类和回归;但是, 它更广泛地用于分类目的。

KNN中的k是关键变量, 也称为超参数, 可帮助准确分类数据点。更准确地说, k是分类新数据点时希望从其投票的最近邻的数量。

Python机器学习简介1
Python机器学习简介2

图1. KNN源的可视化

你可以看到, 随着k的值从1增加到7, 具有某些数据点的两个类之间的决策边界变得更加平滑。

现在的问题是, 所有这些魔术是如何发生的, 每当新数据点进入时, 都会根据存储的数据点对其进行分类?

因此, 让我们通过以下方式快速了解它:

  • 首先, 你加载所有数据并初始化k的值,
  • 然后, 使用各种相似度或距离度量标准(例如曼哈顿距离(L1), 欧几里得距离(L2), 余弦相似度, 巴氏距离, 切比雪夫距离等)来计算存储的数据点与要分类的新数据点之间的距离。 。
  • 接下来, 以降序或升序对距离值进行排序, 并确定前k个或下k个最近邻。
  • 收集k个最近邻的标签, 并使用多数票或加权票对新数据点进行分类。根据在所有已存储数据点中得分最高的某个数据点, 为新数据点分配一个类别标签。
  • 最后, 返回新实例的预测类。

预测可以有两种类型:一种是将类别标签分配给新数据点的分类, 另一种是将值分配给新数据点的回归。与分类不同, 在回归中, 所有k个最近邻的平均值都分配给新数据点。

KNN的缺点:首先, 为每个新数据点搜索最近邻的复杂性。其次, 确定k的值有时变得繁琐。最后, 也不清楚在计算最近邻时应使用哪种类型的距离度量。

理论足够了吗?因此, 让我们加载, 分析和了解你将在今天的小型教程中使用的数据。

加载虹膜数据

Iris数据集由150个样本组成, 具有三个类别, 即Iris-Setosa, Iris-Versicolor和Iris-Virginica。四个特征/属性有助于唯一地识别, 因为萼片长度, 萼片宽度, 花瓣长度和花瓣宽度是三类之一。

随意使用其他一些公共数据集或你的私有数据集。

Sklearn是一个机器学习python库, 广泛用于与数据科学相关的任务。它具有各种分类, 回归和聚类算法, 包括支持向量机, 随机森林, 梯度提升, k均值, KNN等。在sklearn下, 你有一个称为数据集的库, 其中有多个可用于不同任务的数据集包括Iris数据集, 所有这些数据集都可以直接安装。这是非常直观和直接的。因此, 让我们快速加载虹膜数据集。

from sklearn.datasets import load_iris

load_iris同时具有每个样本的数据和类标签。让我们快速提取所有内容。

data = load_iris().data

数据变量将是形状为(150, 4)的numpy数组, 其中包含150个样本, 每个样本具有四个不同的属性。每个类别每个都有50个样本。

data.shape
(150, 4)

让我们提取类标签。

labels = load_iris().target
labels.shape
(150, )

接下来, 你必须结合数据和类标签, 为此, 你将使用一个名为NumPy的出色python库。 NumPy增加了对大型多维数组和矩阵的支持, 以及用于在这些数组上进行操作的大量高级数学函数的集合。因此, 让我们快速导入它!

import numpy as np

由于数据是二维数组, 因此你还必须将标签的形状重新调整为二维数组。

labels = np.reshape(labels, (150, 1))

现在, 你将使用numpy库中可用的连接函数, 并将使用axis = -1, 它将基于第二维进行连接。

data = np.concatenate([data, labels], axis=-1)
data.shape
(150, 5)

接下来, 你将导入python的名为pandas的数据分析库, 当你希望以表格形式排列数据并对数据执行一些操作和操作时, 该库很有用。特别是, 它提供了用于操纵数值表和时间序列的数据结构和操作。

在今天的教程中, 你将广泛使用熊猫。

import pandas as pd
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'species']
dataset = pd.DataFrame(data, columns=names)

现在, 你将拥有同时具有所需数据和类标签的数据集数据框!

在进一步潜水之前, 请记住, labels变量将类标签作为数字值, 但是你将把这些数字值转换为花朵名称或种类。

为此, 你将仅选择类列, 并将三个数值中的每一个替换为相应的种类。你将使用inplace = True, 它将修改数据框数据集。

dataset['species'].replace(0, 'Iris-setosa', inplace=True)
dataset['species'].replace(1, 'Iris-versicolor', inplace=True)
dataset['species'].replace(2, 'Iris-virginica', inplace=True)

让我们打印数据集的前五行, 看看它是什么样子!

dataset.head(5)
萼片长度 萼片宽度 花瓣长度 花瓣宽度 种类
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 虹膜柔滑
3 4.6 3.1 1.5 0.2 虹膜柔滑
4 5.0 3.6 1.4 0.2 虹膜柔滑

分析你的数据

让我们快速了解一下这三朵花在可视化时的样子, 以及它们彼此之间的差异, 不仅在数量上而且在真实上!

Python机器学习简介3

(资源)

让我们使用散点图可视化上面加载的数据, 以找出一个变量受另一变量影响的程度, 或者说两个变量之间有多少相关性。

你将使用matplotlib库使用散点图可视化数据。

import matplotlib.pyplot as plt

提示:你是否热衷于学习以不同方式显示python中数据的方式?然后查看python课程的数据可视化简介。

plt.figure(4, figsize=(10, 8))

plt.scatter(data[:50, 0], data[:50, 1], c='r', label='Iris-setosa')

plt.scatter(data[50:100, 0], data[50:100, 1], c='g', label='Iris-versicolor')

plt.scatter(data[100:, 0], data[100:, 1], c='b', label='Iris-virginica')

plt.xlabel('Sepal length', fontsize=20)
plt.ylabel('Sepal width', fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.title('Sepal length vs. Sepal width', fontsize=20)
plt.legend(prop={'size': 18})
plt.show()
Python机器学习简介4

从上面的图中可以看出, 鸢尾花与萼片长度和萼片宽度之间存在高度相关性。另一方面, 鸢尾鸢尾和弗吉尼亚鸢尾之间的相关性较小。与密集的setosa相比, versicolor和virginica中的数据点分布更广。

让我们快速地绘制花瓣长度和花瓣宽度的图表。

plt.figure(4, figsize=(8, 8))

plt.scatter(data[:50, 2], data[:50, 3], c='r', label='Iris-setosa')

plt.scatter(data[50:100, 2], data[50:100, 3], c='g', label='Iris-versicolor')

plt.scatter(data[100:, 2], data[100:, 3], c='b', label='Iris-virginica')
plt.xlabel('Petal length', fontsize=15)
plt.ylabel('Petal width', fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.title('Petal length vs. Petal width', fontsize=15)
plt.legend(prop={'size': 20})
plt.show()
Python机器学习简介5

即使谈到花瓣的长度和花瓣的宽度, 上图也显示了密集簇生的刚毛花的强相关性。

接下来, 为进一步验证关于花瓣长度和花瓣宽度如何相关的主张, 让我们为所有三种物种绘制一个相关矩阵。

dataset.iloc[:, 2:].corr()
花瓣长度 花瓣宽度
花瓣长度 1.000000 0.962865
花瓣宽度 0.962865 1.000000

上表表明, 当将所有三种结合时, 花瓣长度和花瓣宽度的相关性很强, 为0.96。

我们还分别分析所有三个物种之间的相关性。

dataset.iloc[:50, :].corr() #setosa
萼片长度 萼片宽度 花瓣长度 花瓣宽度
萼片长度 1.000000 0.742547 0.267176 0.278098
萼片宽度 0.742547 1.000000 0.177700 0.232752
花瓣长度 0.267176 0.177700 1.000000 0.331630
花瓣宽度 0.278098 0.232752 0.331630 1.000000
dataset.iloc[50:100, :].corr() #versicolor
萼片长度 萼片宽度 花瓣长度 花瓣宽度
萼片长度 1.000000 0.525911 0.754049 0.546461
萼片宽度 0.525911 1.000000 0.560522 0.663999
花瓣长度 0.754049 0.560522 1.000000 0.786668
花瓣宽度 0.546461 0.663999 0.786668 1.000000
dataset.iloc[100:, :].corr() #virginica
萼片长度 萼片宽度 花瓣长度 花瓣宽度
萼片长度 1.000000 0.457228 0.864225 0.281108
萼片宽度 0.457228 1.000000 0.401045 0.537728
花瓣长度 0.864225 0.401045 1.000000 0.322108
花瓣宽度 0.281108 0.537728 0.322108 1.000000

从以上三个表中, 可以很清楚地看出, setosa和virginica的花瓣长度和花瓣宽度之间的相关性分别为0.33和0.32。而对于杂色而言, 它是0.78。

接下来, 让我们通过绘制直方图来可视化特征分布:

fig = plt.figure(figsize = (8, 8))
ax = fig.gca()
dataset.hist(ax=ax)
plt.show()
Python机器学习简介6

花瓣长度, 花瓣宽度和萼片长度显示为单峰分布, 而萼片宽度显示为高斯分布。所有这些都是有用的分析, 因为这样你就可以考虑使用一种适用于这种分布的算法。

接下来, 你将分析所有四个属性是否都在同一范围内。这是ML的重要方面。熊猫数据框具有一个称为describe的内置函数, 该函数以表格格式为你提供数据的计数, 平均值, 最大值, 最小值。

dataset.describe()
萼片长度 萼片宽度 花瓣长度 花瓣宽度
计数 150.000000 150.000000 150.000000 150.000000
意思 5.843333 3.057333 3.758000 1.199333
小时 0.828066 0.435866 1.765298 0.762238
4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
最大值 7.900000 4.400000 6.900000 2.500000

你可以看到, 如果你希望将其进一步缩小到0到1之间, 则这四个属性在0到8之间的比例都相似, 以厘米为单位。

即使大家都知道每个类别有50个样本, 即约占总分布的33.3%, 但还是让我们重新检查一下!

print(dataset.groupby('species').size())
species
Iris-setosa        50
Iris-versicolor    50
Iris-virginica     50
dtype: int64

预处理数据

在加载数据并进行了广泛分析之后, 是时候准备你的数据了, 你可以将其提供给ML模型。在本节中, 你将通过两种方式预处理数据:标准化数据以及将数据分为训练集和测试集。

规范化你的数据

你可以通过两种方式对数据进行规范化:

  • 标准化示例, 其中你分别标准化每个样本,
  • 特征归一化, 你可以在所有样本中以相同的方式归一化每个特征。

现在的问题是, 为什么或何时需要标准化数据?你是否需要标准化虹膜数据?

好吧, 答案几乎一直都是。归一化你的数据是个好习惯, 因为它将所有样本置于相同的比例和范围内。当你拥有的数据不一致时, 对数据进行规范化至关重要。你可以使用上面学习的describe()函数检查不一致之处, 该函数将为你提供最大值和最小值。如果一个要素的最大值和最小值明显大于另一要素, 则将两个要素规格化为相同比例非常重要。

假设X是一个具有较大范围的特征, Y是第二个具有较小范围的特征。然后, 特征Y的影响可以被特征X的影响所压倒。在这种情况下, 标准化特征X和Y变得很重要。

在虹膜数据中, 不需要标准化。

让我们再次打印describe()函数, 看看为什么不需要任何规范化。

dataset.describe()
萼片长度 萼片宽度 花瓣长度 花瓣宽度
计数 150.000000 150.000000 150.000000 150.000000
意思 5.843333 3.057333 3.758000 1.199333
小时 0.828066 0.435866 1.765298 0.762238
4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
最大值 7.900000 4.400000 6.900000 2.500000

sepal-length属性的值从4.3到7.9, 并且sepal-width的值从2到4.4, 而花瓣长度的值在1到6.9之间, 花瓣宽度在0.1到2.5之间。所有功能部件的值都在0.1到7.9的范围内, 你可以认为可接受。因此, 你无需对Iris数据集应用任何规范化。

分割数据

这是机器学习的另一个重要方面, 因为你的目标是建立一个足以在没有任何人工干预的情况下在测试环境中做出决策或对数据进行分类的模型。因此, 在行业中部署ML模型之前, 你需要确保模型可以很好地概括测试数据。

为此, 你需要一个培训和测试集。回到Iris数据, 你有150个样本, 你将在80%的数据上训练ML模型, 其余20%的数据将用于测试。

在数据科学中, 你经常会遇到一个名为”过度拟合”的术语, 这意味着你的模型已经很好地学习了训练数据, 但是无法对测试数据执行操作。因此, 将数据分为训练和测试或验证集通常可以帮助你了解模型是否过度拟合。

对于训练和测试集合拆分, 你将使用sklearn库, 该库具有一个内置的拆分功能, 称为train_test_split。因此, 让我们分割数据。

from sklearn.model_selection import train_test_split
train_data, test_data, train_label, test_label = train_test_split(dataset.iloc[:, :3], dataset.iloc[:, 4], test_size=0.2, random_state=42)

请注意, random_state是一个种子, 如果你更改数据分割的数字, 该种子也将使用random_state作为输入。但是, 如果你保持random_state不变并多次运行单元, 则数据拆分将保持不变。

让我们快速打印训练和测试数据的形状及其标签。

train_data.shape, train_label.shape, test_data.shape, test_label.shape
((120, 3), (120, ), (30, 3), (30, ))

最后, 是时候将数据提供给k近邻算法了!

KNN模型

在完成所有数据的加载, 分析和预处理之后, 现在该将数据输入到KNN模型中了。为此, 你将使用sklearn的内置函数neighbor, 其中包含一个名为KNeigborsClassifier的类。

让我们从导入分类器开始。

from sklearn.neighbors import KNeighborsClassifier

注意:k(n_neighbors)参数通常是一个奇数, 以避免在投票分数中产生联系。

为了确定超参数k的最佳值, 你将执行称为网格搜索的操作。你将在10个不同的k值上训练和测试模型, 最后使用可为你提供最佳结果的模型。

让我们初始化一个变量neighbors(k), 该变量的取值范围为1-9, 以及两个numpy零矩阵, 分别是train_accuracy和test_accuracy, 用于训练和测试精度。你稍后将需要它们来绘制图形以选择最佳邻居值。

neighbors = np.arange(1, 9)
train_accuracy =np.zeros(len(neighbors))
test_accuracy = np.zeros(len(neighbors))

下一段代码是所有魔术发生的地方。你将枚举所有九个邻居值, 然后针对每个邻居对训练和测试数据进行预测。最后, 将精度存储在train_accuracy和test_accuracy numpy数组中。

for i, k in enumerate(neighbors):
    knn = KNeighborsClassifier(n_neighbors=k)

    #Fit the model
    knn.fit(train_data, train_label)

    #Compute accuracy on the training set
    train_accuracy[i] = knn.score(train_data, train_label)

    #Compute accuracy on the test set
    test_accuracy[i] = knn.score(test_data, test_label)

接下来, 你将使用matplotlib绘制训练和测试的准确性, 并通过准确性与变化的邻居数图来选择模型表现最佳的最佳k值。

plt.figure(figsize=(10, 6))
plt.title('KNN accuracy with varying number of neighbors', fontsize=20)
plt.plot(neighbors, test_accuracy, label='Testing Accuracy')
plt.plot(neighbors, train_accuracy, label='Training accuracy')
plt.legend(prop={'size': 20})
plt.xlabel('Number of neighbors', fontsize=20)
plt.ylabel('Accuracy', fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.show()
Python机器学习简介7

好了, 通过查看上面的图, 看起来当n_neighbors = 3时, 两个模型都表现最佳。因此, 让我们坚持使用n_neighbors = 3并再次重新运行训练。

knn = KNeighborsClassifier(n_neighbors=3)

#Fit the model
knn.fit(train_data, train_label)

#Compute accuracy on the training set
train_accuracy = knn.score(train_data, train_label)

#Compute accuracy on the test set
test_accuracy = knn.score(test_data, test_label)

评估模型

在本教程的最后一部分中, 你将使用诸如confusion_matrix和category_report之类的两种技术在测试数据上评估模型。

让我们首先在测试数据上检查模型的准确性。

test_accuracy
0.9666666666666667

中提琴!看起来该模型能够正确分类96.66%的测试数据。那不是很神奇吗?仅需几行代码, 你就可以训练一个ML模型, 该模型现在只需使用96.66%的准确性就可以告诉你花的名字。谁知道它的性能可能比人类更好。

混淆矩阵

混淆矩阵主要用于描述模型在已知真实值或标签的测试数据上的性能。

Scikit-learn提供了一个为你计算混淆矩阵的函数。

prediction = knn.predict(test_data)

下面的plot_confusion_matrix()函数已被修改并从此源获取。

import itertools
def plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues):


    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt), horizontalalignment="center", color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label', fontsize=30)
    plt.xlabel('Predicted label', fontsize=30)
    plt.tight_layout()
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
class_names = load_iris().target_names


# Compute confusion matrix
cnf_matrix = confusion_matrix(test_label, prediction)
np.set_printoptions(precision=2)

# Plot non-normalized confusion matrix
plt.figure(figsize=(10, 8))
plot_confusion_matrix(cnf_matrix, classes=class_names)
plt.title('Confusion Matrix', fontsize=30)
plt.show()
Python机器学习简介8

从上面的confusion_matrix图中, 你可以看到该模型正确地对所有花朵进行了分类, 除了一朵杂色花被分类为维吉尼亚花。

分类报告

分类报告可通过提供每个类别的准确性, 召回率和F1分数来帮助你更详细地识别错误分类的类别。你将使用sklearn库来可视化分类报告。

from sklearn.metrics import classification_report
print(classification_report(test_label, prediction))
                 precision    recall  f1-score   support

    Iris-setosa       1.00      1.00      1.00        10
Iris-versicolor       0.90      1.00      0.95         9
 Iris-virginica       1.00      0.91      0.95        11

      micro avg       0.97      0.97      0.97        30
      macro avg       0.97      0.97      0.97        30
   weighted avg       0.97      0.97      0.97        30

走得更远!

首先祝贺所有成功实现这一目标的人!但这仅仅是开始。还有很长的路要走!

本教程主要涉及机器学习的基础知识以及一种称为KNN和python的ML算法的实现。你使用的Iris数据集非常小而且有点简单。

如果本教程激发了你的兴趣以了解更多信息, 则可以尝试使用其他一些数据集或尝试学习更多的ML算法, 并可以将其应用于Iris数据集以观察对准确性的影响。通过这种方式, 你将学到更多, 而不仅仅是了解理论!

如果你对本教程中介绍的基础知识和其他机器学习算法进行了充分的实验, 则可能需要进一步进行python和数据分析。

来源:

https://www.srcmini02.com/45506.html

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?