鸢尾花数据集,鸢尾花数据集下载

牵着乌龟去散步 广角镜 32 0
入门|10个例子带你了解机器学习中的线性代数

本文介绍了 10 个常见机器学习案例,这些案例需要用线性代数才能得到更好的理解。

线性代数是数学的分支学科,涉及矢量、矩阵和线性变换。

它是机器学习的重要基础,从描述算法操作的符号到代码中算法的实现,都属于该学科的研究范围。

虽然线性代数是机器学习领域不可或缺的一部分,但二者的紧密关系往往无法解释,或只能用抽象概念(如向量空间或特定矩阵运算)解释。

阅读这篇文章后,你将会了解到:

  • 如何在处理数据时使用线性代数结构,如表格数据集和图像。

  • 数据准备过程中用到的线性代数概念,例如 one-hot 编码和降维。

  • 深度学习、自然语言处理和推荐系统等子领域中线性代数符号和 *** 的深入使用。

让我们开始吧。

这 10 个机器学习案例分别是:

1. Dataset and Data Files 数据集和数据文件

2. Images and Photographs 图像和照片

3. One-Hot Encoding one-hot 编码

4. Linear Regression 线性回归

5. Regularization 正则化

6. Principal Component Analysis 主成分分析

7. Singular-Value Decomposition 奇异值分解

8. Latent Semantic Analysis 潜在语义分析

9. Recommender Systems 推荐系统

10. Deep Learning 深度学习

1. 数据集和数据文件

在机器学习中,你可以在数据集上拟合一个模型。

这是表格式的一组数字,其中每行代表一组观察值,每列代表观测的一个特征。

例如,下面这组数据是鸢尾花数据集的一部分

数据集地址:http://archive.ics.uci.edu/ml/datasets/Iris

5.1,3.5,1.4,0.2,Iris-setosa4.9,3.0,1.4,0.2,Iris-setosa4.7,3.2,1.3,0.2,Iris-setosa4.6,3.1,1.5,0.2,Iris-setosa5.0,3.6,1.4,0.2,Iris-setosa

这些数据实际上是一个矩阵:线性代数中的一个关键数据结构。

接下来,将数据分解为输入数据和输出数据,来拟合一个监督机器学习模型(如测量值和花卉品种),得到矩阵(X)和矢量(y)。矢量是线性代数中的另一个关键数据结构。

每行长度相同,即每行的数据个数相同,因此我们可以说数据是矢量化的。这些行数据可以一次性或成批地提供给模型,并且可以预先配置模型,以得到固定宽度的行数据。

2. 图像和照片

也许你更习惯于在计算机视觉应用中处理图像或照片。

你使用的每个图像本身都是一个固定宽度和高度的表格结构,每个单元格有用于表示黑白图像的 1 个像素值或表示彩色图像的 3 个像素值。

照片也是线性代数矩阵的一种。

与图像相关的操作,如裁剪、缩放、剪切等,都是使用线性代数的符号和运算来描述的。

3. one-hot 编码

有时机器学习中要用到分类数据。

可能是用于解决分类问题的类别标签,也可能是分类输入变量。

对分类变量进行编码以使它们更易于使用并通过某些技术进行学习是很常见的。one-hot 编码是一种常见的分类变量编码。

one-hot 编码可以理解为:创建一个表格,用列表示每个类别,用行表示数据集中每个例子。在列中为给定行的分类值添加一个检查或「1」值,并将「0」值添加到所有其他列。

例如,共计 3 行的颜色变量:

redgreenblue...

这些变量可能被编码为:

red, green, blue1, 0, 00, 1, 00, 0, 1...

每一行都被编码为一个二进制矢量,一个被赋予「0」或「1」值的矢量。这是一个稀疏表征的例子,线性代数的一个完整子域。

4. 线性回归

线性回归是一种用于描述变量之间关系的统计学传统 *** 。

该 *** 通常在机器学习中用于预测较简单的回归问题的数值。

描述和解决线性回归问题有很多种 *** ,即找到一组系数,用这些系数与每个输入变量相乘并将结果相加,得出更佳的输出变量预测。

如果您使用过机器学习工具或机器学习库,解决线性回归问题的最常用 *** 是通过最小二乘优化,这一 *** 是使用线性回归的矩阵分解 *** 解决的(例如 LU 分解或奇异值分解)。

即使是线性回归方程的常用总结 *** 也使用线性代数符号:

y = A . b

其中,y 是输出变量,A 是数据集,b 是模型系数。

5. 正则化

在应用机器学习时,我们往往寻求最简单可行的模型来发挥解决问题的更佳技能。

较简单的模型通常更擅长从具体示例泛化到未见过的数据。

在涉及系数的许多 *** 中,例如回归 *** 和人工神经 *** ,较简单的模型通常具有较小的系数值。

一种常用于模型在数据拟合时尽量减小系数值的技术称为正则化,常见的实现包括正则化的 L2 和 L1 形式。

这两种正则化形式实际上是系数矢量的大小或长度的度量,是直接脱胎于名为矢量范数的线性代数 *** 。

6. 主成分分析

通常,数据集有许多列,列数可能达到数十、数百、数千或更多。

对具有许多特征的数据进行建模具有一定的挑战性。而且,从包含不相关特征的数据构建的模型通常不如用最相关的数据训练的模型。

我们很难知道数据的哪些特征是相关的,而哪些特征又不相关。

自动减少数据集列数的 *** 称为降维,其中也许更流行的 *** 是主成分分析法(简称 PCA)。

该 *** 在机器学习中,为可视化和模型创建高维数据的投影。

PCA *** 的核心是线性代数的矩阵分解 *** ,可能会用到特征分解,更广义的实现可以使用奇异值分解(SVD)。

7. 奇异值分解

另一种流行的降维 *** 是奇异值分解 *** ,简称 SVD。

如上所述,正如该 *** 名称所示,它是源自线性代数领域的矩阵分解 *** 。

该 *** 在线性代数中有广泛的用途,可直接应用于特征选择、可视化、降噪等方面。

在机器学习中我们会看到以下两个使用 SVD 的情况。

8. 潜在语义分析

在用于处理文本数据的机器学习子领域(称为自然语言处理),通常将文档表示为词出现的大矩阵。

例如,矩阵的列可以是词汇表中的已知词,行可以是文本的句子、段落、页面或文档,矩阵中的单元格标记为单词出现的次数或频率。

这是文本的稀疏矩阵表示。矩阵分解 *** (如奇异值分解)可以应用于此稀疏矩阵,该分解 *** 可以提炼出矩阵表示中相关性最强的部分。以这种方式处理的文档比较容易用来比较、查询,并作为监督机器学习模型的基础。

这种形式的数据准备称为潜在语义分析(简称 LSA),也称为潜在语义索引(LSI)。

9. 推荐系统

涉及产品推荐的预测建模问题被称为推荐系统,这是机器学习的一个子领域。

例如,基于你在亚马逊上的购买记录和与你类似的客户的购买记录向你推荐书籍,或根据你或与你相似的用户在 Netflix 上的观看历史向你推荐电影或电视节目。

推荐系统的开发主要涉及线性代数 *** 。一个简单的例子就是使用欧式距离或点积之类的距离度量来计算稀疏顾客行为向量之间的相似度。

像奇异值分解这样的矩阵分解 *** 在推荐系统中被广泛使用,以提取项目和用户数据的有用部分,以备查询、检索及比较。

10. 深度学习

人工神经 *** 是一种非线性机器学习算法,它受大脑中信息处理元素的启发,其有效性已经在一系列问题中得到验证,其中最重要的是预测建模。

深度学习是近期出现的、使用最新 *** 和更快硬件的人工神经 *** 的复兴,这一 *** 使得在非常大的数据集上开发和训练更大更深的(更多层) *** 成为可能。深度学习 *** 通常会在机器翻译、照片字幕、语音识别等一系列具有挑战性的领域取得最新成果。

神经 *** 的执行涉及线性代数数据结构的相乘和相加。如果扩展到多个维度,深度学习 *** 可以处理向量、矩阵,甚至输入和系数的张量,此处的张量是一个两维以上的矩阵。

线性代数是描述深度学习 *** 的核心,它通过矩阵表示法来实现深度学习 *** ,例如 Google 的 TensorFlow Python 库,其名称中包含「tensor」一词。

10个实用的数据可视化的图表总结

用于深入了解数据的一些独特的数据可视化技术

可视化是一种方便的观察数据的方式,可以一目了然地了解数据块。我们经常使用柱状图、直方图、饼图、箱图、热图、散点图、线状图等。这些典型的图对于数据可视化是必不可少的。除了这些被广泛使用的图表外,还有许多很好的却很少被使用的可视化 *** ,这些图有助于完成我们的工作,下面我们看看有那些图可以进行。

1、平行坐标图(Parallel Coordinate)

我们最多可以可视化 3 维数据。 但是我们有时需要可视化超过 3 维的数据才能获得更多的信息。 我们经常使用 PCA 或 t-SNE 来降维并绘制它。 在降维的情况下,可能会丢失大量信息。 在某些情况下,我们需要考虑所有特征, 平行坐标图有助于做到这一点。

上面的图片。横线(平行轴)表示鸢尾花的特征(花瓣长、萼片长、萼片宽、花瓣宽)。分类是Setosa, Versicolor和Virginica。上图将该物种编码为Setosa→1,Versicolor→2,Virginica→3。每个平行轴包含最小值到更大值(例如,花瓣长度从1到6.9,萼片长度从4.3到7.9,等等)。例如,考虑花瓣长度轴。这表明与其他两种植物相比,濑蝶属植物的花瓣长度较小,其中维珍属植物的花瓣长度更高。

有了这个图,我们可以很容易地获得数据集的总体信息。数据集是什么样子的?让我们来看看。

让我们用Plotly Express库<1>可视化数据。Plotly库提供了一个交互式绘图工具。

import plotly.express as pxdf = px.data.iris() fig = px.parallel_coordinates(df, color="species_id", labels={"species_id": "Species","sepal_width": "Sepal Width", "sepal_length": "Sepal Length","petal_width": "Petal Width", "petal_length": "Petal Length", },color_continuous_scale=px.colors.diverging.Tealrose,color_continuous_midpoint=2)fig.show()

除了上图以外我们还可以使用其他库,如pandas、scikit-learn和matplotlib来绘制并行坐标。

2、六边形分箱图 (Hexagonal Binning)

六边形分箱图是一种用六边形直观表示二维数值数据点密度的 *** 。

ax = df.plot.hexbin(x='sepal_width', y='sepal_length', gridsize=20,color='#BDE320')

我考虑了上一节的数据集来绘制上面的六边形分箱图。 Pandas 允许我们绘制六边形 binning <2>。 我已经展示了用于查找 sepal_width 和 sepal_length 列的密度的图。

如果仔细观察图表,我们会发现总面积被分成了无数个六边形。 每个六边形覆盖特定区域。 我们注意到六边形有颜色变化。 六边形有的没有颜色,有的是淡绿色,有的颜色很深。 根据图右侧显示的色标,颜色密度随密度变化。 比例表示具有颜色变化的数据点的数量。 六边形没有填充颜色,这意味着该区域没有数据点。

其他库,如 matplotlib、seaborn、bokeh(交互式绘图)也可用于绘制它。

3、等高线图(Contour )

二维等高线密度图是可视化特定区域内数据点密度的另一种 *** 。这是为了找到两个数值变量的密度。例如,下面的图显示了在每个阴影区域有多少数据点。

import plotly.express as pxfig = px.density_contour(df, x="sepal_width", y="sepal_length")fig.update_traces(contours_coloring="fill", contours_showlabels = True)fig.show()

为了生成上面的图表,我这里使用了plotly库,因为它可以方便地绘制交互式的图表。我们这里绘制了两个变量 sepal_width 和 sepal_length 的密度。

当然,也可以使用其他库,如seaborn、matplotlib等。

4、 *** -plot

*** plot是另一个有趣的图。 *** 是Quantile - Quantile plot的缩写(Quantile/percentile是一个范围,在这个范围内数据下降了指定百分比。例如,第10个quantile/percentile表示在该范围下,找到了10%的数据,90% 超出范围)。 这是一种直观地检查数值变量是否服从正态分布的 *** 。 让我解释一下它是如何工作的。

图(a)是样本分布; (b) 是标准正态分布。 对于样本分布,数据范围从 10 到 100(100% 数据在 10 到 100 之间)。 但对于标准正态分布,100% 的数据在 -3 到 3(z 分数)的范围内。 在 *** 图中,两个 x 轴值均分为 100 个相等的部分(称为分位数)。 如果我们针对 x 和 y 轴绘制这两个值,我们将得到一个散点图。

散点图位于对角线上。这意味着样本分布是正态分布。如果散点图位于左边或右边而不是对角线,这意味着样本不是正态分布的。

导入必要的库

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns

生成正态分布数据。

np.random.seed(10)# Generate Univariate Observationsgauss_data = 5 * np.random.randn(100) + 50

绘制数据点的分布。

sns.histplot(data=gauss_data, kde=True)

该图显示数据是正态分布的。我们用数据点做qq-plot来检验它是否正态分布。

import stat *** odels.api as  *** # q-q plot *** .qqplot(gauss_data, line='s')plt.show()

该图显示散点位于对角线上。所以它是正态分布的。

5、小提琴图(Violin Plot)

小提琴图与箱线图相关。 我们能从小提琴图中获得的另一个信息是密度分布。 简单来说就是一个结合了密度分布的箱线图。我们将其与箱线图进行比较。

在小提琴图中,小提琴中间的白点表示中点。 实心框表示四分位数间距 (IQR)。 上下相邻值是异常值的围栏。 超出范围,一切都是异常值。 下图显示了比较。

让我们看看小提琴图的可视化

import seaborn as snssns.violinplot(data=df, y="sepal_width")

我们还可以通过传递名称来绘制不同物种的小提琴图。

import seaborn as snssns.violinplot(data=df,x='species', y="sepal_width")

还可以使用其他库,如plotly、matplotlib等来绘制小提琴图。

6、箱线图的改进版(Boxen plot)

Boxenplot 是 seaborn 库引入的一种新型箱线图。 对于箱线图,框是在四分位数上创建的。 但在 Boxenplot 中,数据被分成更多的分位数。 它提供了对数据的更多内存。

鸢尾花数据集的 Boxenplot 显示了 sepal_width 的数据分布。

sns.boxenplot(x=df<"sepal_width">)

上图显示了比箱线图更多的盒。这是因为每个框代表一个特定的分位数。

sns.boxenplot(data=df, x="species",y='sepal_width')

不同物种sepal_width的Boxenplot图。

7、点图

下图中有一些名为误差线的垂直线和其他一些连接这些垂直线的线。 让我们看看它的确切含义。

点图是一种通过上图中显示的点的位置来表示数值变量集中趋势的 *** ,误差条表示变量的不确定性(置信区间)<4>。 绘制线图是为了比较不同分类值的数值变量的变异性 <4>。

让我们举一个实际的例子——

我们继续使用 seaborn 库和 iris 数据集(在平行坐标部分中提到)。

import seaborn as snssns.pointplot(data=df,x="species", y="sepal_width")

该图表显示了不同花的萼片宽度的变异性。我们还可以绘制多个点图。

8、分簇散点图(Swarm plot)

Swarm plot 是另一个受“beeswarm”启发的有趣图表。 通过此图我们可以轻松了解不同的分类值如何沿数值轴分布 <5>。它在不重叠数据点的情况下绘制数据。 但它不适用于大型数据集。

import seaborn as snssns.swarmplot(data=df,x="species", y="sepal_width")

9、旭日图(Sunburst Chart)

它是圆环图或饼图的定制版本,将一些额外的层次信息集成到图中 <7>。

整个图表被分成几个环(从内到外)。它保存层次结构信息,其中内环位于层次结构的顶部,外环位于较低的<7>阶。

import plotly.express as pxdf = px.data.tips()

绘制旭日图

fig = px.sunburst(df, path=<'sex', 'day', 'time'>, values='total_bill', color='time')fig.show()

sunburst类的path属性提供了层次结构,其中性别位于层次结构的顶部,然后是日期和时间。

10、词云(Word Cloud)

词云图的想法非常简单。假设我们有一组文本文档。单词有很多,有些是经常出现的,有些是很少出现的。在词云图中,所有单词都被绘制在特定的区域中,频繁出现的单词被高亮显示(用较大的字体显示)。有了这个词云,我们可以很容易地找到重要的客户反馈,热门的政治议程话题等。

import pandas as pddata=pd.read_csv('/work/android-games.csv')data.head()

我们统计每个类别的数据数量

data.category.value_counts()

我们进行可视化。

#importing the module from wordcloud libraryfrom wordcloud import WordCloudimport matplotlib.pyplot as plt#creating a text from the category column by taking only the 2nd part of the category. text = " ".join(cat.split()<1> for cat in data.category)#generating the cloudword_cloud = WordCloud(collocations = False, background_color = 'black').generate(text)plt.imshow(word_cloud, interpolation='bilinear')plt.axis("off")plt.show()

该图表显示了频率更高的所有类别。
我们也可以用这个图从文本中找到经常出现的单词。

总结

数据可视化是数据科学中不可缺少的一部分。在数据科学中,我们与数据打交道。手工分析少量数据是可以的,但当我们处理数千个数据时它就变得非常麻烦。如果我们不能发现数据集的趋势和洞察力,我们可能无法使用这些数据。希望上面介绍的的图可以帮助你深入了解数据。


作者:Md. Zubair

K-Means 聚类算法实现鸢尾花数据的聚类

完整代码:https://github.com/angelfate/python_ *** ysis/tree/master/K-Means%E8%81%9A%E7%B1%BB%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0%E9%B8%A2%E5%B0%BE%E8%8A%B1%E6%95%B0%E6%8D%AE%E7%9A%84%E8%81%9A%E7%B1%BB

#!/usr/bin/env Python3# -*- coding: utf-8 -*-# @Software: PyCharm# @virtualenv:workon# @contact: Kmeans聚类算法,数据集是Iris(鸢尾花的数据集),分类数k是3,数据维数是4。# @Desc:Code descripton__author__ = '未昔/AngelFate'__date__ = '2019/8/17 21:00'import pandas as pdimport numpy as npimport matplotlib.pylab as plt"""K-means聚类算法是典型的基于距离的非层次聚类算法,在最小化误差函数的基础上将数据划分为预定的K个类,使得K个类达到类内数据距离之和最小而类间距离之和更大。它是无监督学习算法,采用距离作为相似性的度量指标,即认为两个对象距离越近,其相似性就越大。1、数据类型与相似性度量(1)连续属性和离散属性数据对于连续属性,要依次对每个属性的属性值进行零-均值化处理;对于离散属性,要依次对每个属性的属性值进行数值化处理。然后通过计算距离来度量相似性,K-means聚类算法中一般需要计算样本间的距离,样本和簇的距离,簇和簇的距离。其中,样本间的距离通常用欧式距离(欧几里得距离)、曼哈顿距离和闵可夫斯基距离,样本和簇的距离可以用样本到簇中心的距离代替,簇和簇距离可以用簇中心到簇中心的距离代替。"""data = pd.read_table('Iris_data.txt', sep=' ', encoding='utf8',index_col=False,names=<'a','b','c','d'>)x = data<<'a', 'b', 'c', 'd'>>.valuesprint('x:\n',x)from sklearn.cluster import KMeansk = 4iteration = 500model = KMeans(n_clusters=k, n_jobs=1, max_iter=iteration)y = model.fit_predict(x)label_pred = model.labels_centroids = model.cluster_centers_inertia = model.inertia_print('y:\n',y)print('聚类标签:\n',label_pred)print('聚类中心:\n',centroids)print('聚类准则的总和:\n',inertia)print('----分类结果----:')result = list(zip(y, x))for i in result:    print(i)r1 = pd.Series(model.labels_).value_counts()print('r1:\n',r1)r2 = pd.DataFrame(model.cluster_centers_)print('r2: \n', r2)r = pd.concat(, axis=1)r.columns = data.columns.tolist() + <'类别数目'>print('r: \n', r)file = open('result.txt','w',encoding='utf8')file.write(str(r1)+'\n\n'+str(r2)+'\n\n'+str(r))file.close()

result:

| a b c d 类别数目 ||  | 0 6.997947 2.994129 5.794507 1.493422 14559 ||  | 1 5.006063 3.000701 3.196228 1.494557 14837 ||  | 2 7.003359 3.007491 3.286257 1.491236 15253 ||  | 3 5.019887 2.991471 5.724741 1.521535 15351 |

| a b c d 类别数目 ||  | 0 6.997947 2.994129 5.794507 1.493422 14559 ||  | 1 5.006063 3.000701 3.196228 1.494557 14837 ||  | 2 7.003359 3.007491 3.286257 1.491236 15253 ||  | 3 5.019887 2.991471 5.724741 1.521535 15351 |

一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)

在"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)"中我们详细介绍了BP算法的原理和推导过程,并且用实际的数据进行了计算演练。在下篇中,我们将自己实现BP算法(不使用第三方的算法框架),并用来解决鸢尾花分类问题。

图1 鸢尾花

鸢尾花数据集如图2所示,总共有三个品种的鸢尾花(setosa、versicolor和virginica),每个类别50条样本数据,每个样本有四个特征(花萼长度、花萼宽度、花瓣长度以及花瓣宽度)。

图2 鸢尾花数据集

首先我们导入需要的包:

from csv import readerimport numpy as npfrom sklearn.preprocessing import MinMaxScalerimport randomimport matplotlib.pyplot as pltimport math

接下来我们实现一个数据集的加载和预处理的函数"load_dataset":

def load_dataset(dataset_path, n_train_data): """加载数据集,对数据进行预处理,并划分训练集和验证集 :param dataset_path: 数据集文件路径 :param n_train_data: 训练集的数据量 :return: 划分好的训练集和验证集 """ dataset = <> label_dict = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2} with open(dataset_path, 'r') as file: # 读取CSV文件,以逗号为分隔符 csv_reader = reader(file, delimiter=',') for row in csv_reader: # 将字符串类型的特征值转换为浮点型 row<0:4> = list(map(float, row<0:4>)) # 将标签替换为整型 row<4> = label_dict> # 将处理好的数据加入数据集中 dataset.append(row) # 对数据进行归一化处理 dataset = np.array(dataset) mms = MinMaxScaler() for i in range(dataset.shape<1> - 1): dataset<:, i> = mms.fit_transform(dataset<:, i>.reshape(-1, 1)).flatten() # 将类标转为整型 dataset = dataset.tolist() for row in dataset: row<4> = int(row<4>) # 打乱数据集 random.shuffle(dataset) # 划分训练集和验证集 train_data = dataset<0:n_train_data> val_data = dataset return train_data, val_data

在"load_dataset"函数中,我们实现了数据集的读取、数据的归一化处理以及对数据集进行了"shuffle"操作等,最后函数返回了划分好的训练集和验证集。

实现数据预处理之后,接下来我们开始实现BP算法的关键部分(如果读者对算法原理有不清楚的地方,可以查看"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)")。首先我们实现神经元的计算部分、激活函数以及激活函数的求导部分。

def fun_z(weights, inputs): """计算神经元的输入:z = weight * inputs + b :param weights:  *** 参数(权重矩阵和偏置项) :param inputs: 上一层神经元的输出 :return: 当前层神经元的输入 """ bias_term = weights<-1> z = 0 for i in range(len(weights)-1): z += weights * inputs z += bias_term return zdef sigmoid(z): """激活函数(Sigmoid):f(z) = Sigmoid(z) :param z: 神经元的输入 :return: 神经元的输出 """ return 1.0 / (1.0 + math.exp(-z))def sigmoid_derivative(output): """Sigmoid激活函数求导 :param output: 激活函数的输出值 :return: 求导计算结果 """ return output * (1.0 - output)

函数"fun_z"实现了公式"z = weight * inputs + b",其中inputs是上一层 *** 的输出,weight是当前层的权重矩阵,b是当前层的偏置项,计算得到的z是当前层的输入。

函数"sigmoid"是Sigmoid激活函数的实现,将z作为激活函数的输入,计算得到当前层的输出,并传递到下一层。

函数"sigmoid_derivative"是Sigmoid函数求导的实现,在误差反向传播的时候需要用到。

接下来我们实现BP *** 的前向传播:

def forward_propagate(network, inputs): """前向传播计算 :param network: 神经 ***  :param inputs: 一个样本数据 :return: 前向传播计算的结果 """ for layer in network: # 循环计算每一层 new_inputs = <> for neuron in layer: # 循环计算每一层的每一个神经元 z = fun_z(neuron<'weights'>, inputs) neuron<'output'> = sigmoid(z) new_inputs.append(neuron<'output'>) inputs = new_inputs return inputs

前向计算的过程比较简单,和我们在上篇中介绍的计算过程一致。稍微麻烦一点的是误差反向传播的计算:

def backward_propagate_error(network, actual_label): """误差进行反向传播 :param network: 神经 ***  :param actual_label: 真实的标签值 :return: """ for i in reversed(range(len(network))): # 从最后一层开始计算误差 layer = network errors = list() if i != len(network)-1: # 不是输出层 for j in range(len(layer)): # 计算每一个神经元的误差 error = 0.0 for neuron in network: error += (neuron<'weights'> * neuron<'delta'>) errors.append(error) else: # 输出层 for j in range(len(layer)): # 计算每一个神经元的误差 neuron = layer errors.append(actual_label - neuron<'output'>) # 计算误差项 delta for j in range(len(layer)): neuron = layer neuron<'delta'> = errors * sigmoid_derivative(neuron<'output'>)

误差反向传播过程中,我们首先需要根据模型的输出来计算得到误差,然后计算输出层的误差项。得到输出层的误差项之后,我们就可以根据上篇中介绍的"第k层神经元的误差项是由第k+1层的误差项乘以第k+1层的权重,再乘以第k层激活函数的导数得到"来计算其它层的误差项。

在计算得到每一层的误差项之后,我们根据上篇中介绍的权重矩阵和偏置项的更新公式来更新参数:

def update_parameters(network, row, l_rate): """利用误差更新神经 *** 的参数(权重矩阵和偏置项) :param network: 神经 ***  :param row: 一个样本数据 :param l_rate: 学习率 :return: """ for i in range(len(network)): inputs = row<:-1> if i != 0: # 获取上一层 *** 的输出 inputs =  for neuron in network> for neuron in network: # 更新权重矩阵 for j in range(len(inputs)): neuron<'weights'> += l_rate * neuron<'delta'> * inputs # 更新偏置项 neuron<'weights'><-1> += l_rate * neuron<'delta'>

到这里所有的关键部分我们都已经实现了,接下来我们实现 *** 的初始化以及 *** 的训练部分,首先实现 *** 的初始化:

def initialize_network(n_inputs, n_hidden, n_outputs): """初始化BP *** (初始化隐藏层和输出层的参数:权重矩阵和偏置项) :param n_inputs: 特征列数 :param n_hidden: 隐藏层神经元个数 :param n_outputs: 输出层神经元个数,即分类的总类别数 :return: 初始化后的神经 ***  """ network = list() # 隐藏层 hidden_layer = <{'weights': } for i in range(n_hidden)> network.append(hidden_layer) # 输出层 output_layer = <{'weights': } for i in range(n_outputs)> network.append(output_layer) return network

这里我们初始化了一个两层神经 *** (一个隐藏层和一个输出层)。在初始化参数的时候,我们将权重矩阵和偏置项放在了一个数组中("weights"),数组的最后一个元素是偏置项,前面的元素是权重矩阵。

接下来我们实现模型的训练部分:

def train(train_data, l_rate, epochs, n_hidden, val_data): """训练神经 *** (迭代n_epoch个回合) :param train_data: 训练集 :param l_rate: 学习率 :param epochs: 迭代的回合数 :param n_hidden: 隐藏层神经元个数 :param val_data: 验证集 :return: 训练好的 ***  """ # 获取特征列数 n_inputs = len(train_data<0>) - 1 # 获取分类的总类别数 n_outputs = len(set( for row in train_data>)) # 初始化 ***  network = initialize_network(n_inputs, n_hidden, n_outputs) acc = <> for epoch in range(epochs): # 训练epochs个回合 for row in train_data: # 前馈计算 _ = forward_propagate(network, row) # 处理一下类标,用于计算误差 actual_label = <0 for i in range(n_outputs)> actual_label> = 1 # 误差反向传播计算 backward_propagate_error(network, actual_label) # 更新参数 update_parameters(network, row, l_rate) # 保存当前epoch模型在验证集上的准确率 acc.append(validation(network, val_data)) # 绘制出训练过程中模型在验证集上的准确率变化 plt.xlabel('epochs') plt.ylabel('accuracy') plt.plot(acc) plt.show() return network

我们总共训练了epochs个回合,这里我们使用随机梯度下降来优化模型,因此每次都用一个样本来更新参数。接下来我们实现一个函数用来验证模型的效果:

def validation(network, val_data): """测试模型在验证集上的效果 :param network: 神经 ***  :param val_data: 验证集 :return: 模型在验证集上的准确率 """ # 获取预测类标 predicted_label = <> for row in val_data: prediction = predict(network, row) predicted_label.append(prediction) # 获取真实类标 actual_label =  for row in val_data> # 计算准确率 accuracy = accuracy_calculation(actual_label, predicted_label) # print("测试集实际类标:", actual_label) # print("测试集上的预测类标:", predicted_label) return accuracy

训练过程中的每一个回合,我们都用模型对验证集进行一次预测,并将预测的结果保存,用来绘制训练过程中模型在验证集上的准确率的变化过程。准确率的计算以及使用模型进行预测的实现如下:

def accuracy_calculation(actual_label, predicted_label): """计算准确率 :param actual_label: 真实类标 :param predicted_label: 模型预测的类标 :return: 准确率(百分制) """ correct_count = 0 for i in range(len(actual_label)): if actual_label == predicted_label: correct_count += 1 return correct_count / float(len(actual_label)) * 100.0def predict(network, row): """使用模型对当前输入的数据进行预测 :param network: 神经 ***  :param row: 一个数据样本 :return: 预测结果 """ outputs = forward_propagate(network, row) return outputs.index(max(outputs))

最后我们运行代码:

if __name__ == "__main__": file_path = './iris.csv' # 参数设置 l_rate = 0.2 # 学习率 epochs = 300 # 迭代训练的次数 n_hidden = 5 # 隐藏层神经元个数 n_train_data = 130 # 训练集的大小(总共150条数据,训练集130条,验证集20条) # 加载数据并划分训练集和验证集 train_data, val_data = load_dataset(file_path, n_train_data) # 训练模型 network = train(train_data, l_rate, epochs, n_hidden, val_data)

训练过程如图3所示:

基于决策树算法完成鸢尾花的分类并使用scikit-learn进行交叉验证

专栏推荐

(此处已添加圈子卡片,请到今日头条客户端查看)

正文

这个demo我们要演示机器学习算法中的决策树实现,我们还是使用鸢尾花数据集,这个数据集有四个特征,而类别有4个,我们根据这四个特征进行决策,然后最后构造出一棵决策树,最终决策的结果就是对这个数据集中的鸢尾花类别进行分类。

首先我们先来读取一下这个鸢尾花的数据,因为鸢尾花的数据是没有列名的,所以之一步我们给这个数据集来添加一下类名,也就是标签名和类别名。

import pandas as pd

iris_data = pd.read_csv('iris.data')

iris_data.columns = <'sepal_length_cm', 'sepal_width_cm', 'petal_length_cm', 'petal_width_cm', 'class'>

print iris_data.head()

这个就是鸢尾花中的前五行数据,我们发现每一列都已经添加了特征名,最后一列class为标签名。

我有一张鸢尾花的图片,我们可以发现有一个叫做sepal叫做花萼,有一个叫做petal叫做花瓣,这个花萼和花瓣分别有长度和宽度,所以一共构成了四个特征:花萼的长度,花萼的宽度,花瓣的长度,花瓣的宽度。

我们先来使用python来读取一下这个图片,然后再来显示一下。


import matplotlib.pyplot as plt

from PIL import Image

img=Image.open('test.jpg')

plt.imshow(img)

plt.show()


这个代码很简单就是读取一个图片然后显示。

我们可以使用iris_data.describe() *** ,来看我们对鸢尾花这一数据集的数学描述

我们可以看出列为特征,一行为count总数,mean表示均值,std为标准查,min最小值,max更大值,25%为4分位,50%为二分位,75%为4分之3分位。

我们现在先来使用可视化的方式来看一下鸢尾花数据集中特征和特征之间的关系


import pandas as pd

import matplotlib.pyplot as plt

import seaborn as ***

*** .pairplot(iris_data.dropna(), hue='class')

plt.show()


使用seaborn画图会简单许多,pairplot画图会很给力,它会自动讲数据集中的特征进行两两组合进行画图。效果如下所示:

其中对角线位置因为是一个特征,所以它就化成了柱状图

这里来再画一个图,画小提琴图,这样可以更加直观的看出在相同特征之间不同类别之间的差距

我们画出来的小提琴图如图所示,越宽表示越集中,比如在特征sepal_length=5的时候iris-setosa那个地方很宽,这就表示sepal_length为5的地方这张鸢尾花的数据很多。我在小提琴图中画了两条黑色的直线,可以看出最上面的那条黑色直线并没有分开三个类别,而下面的那条直线很好的分开了三个类别(一条线上面为两个类别,下面为一个类别),所以我们可以说下面那个特征决策效果很好


画小提琴的代码为:

plt.figure(figsize=(10, 10)指定绘图区域

for column_index, column in enumerate(iris_data.columns):if column == 'class':continueplt.subplot(2, 2, column_index + 1)指定子图,column_index从0,1,2,3 *** .violinplot(x='class', y=column, data=iris_data)在子图上画图

plt.show()


我们输出鸢尾花的数据的时候,发现它都排好序了,也就是说如果我们取前面百分之70作为训练集,而取百分之30作为测试集是不行的,所以我们可以先把数据集打乱,然后随机挑选出百分之七十的数据作为训练集,那么剩下的当作测试集,幸运的是,sklearn已经封装好了类似的功能我们直接调用就好了。

这个地方因为要获取很多列的数据,所以我们使用<列名列表>

train_test_split之一个参数为数据集的样本,第二个为数据集中的标签,第三个为指定训练集的的占比,这里我们指定总样本的百分之75为训练样本,那么剩下的样本就是测试样本了。

现在我们有了训练数据和测试数据,那么我们下面的任务就是构造决策树,使用训练数据来拟合这颗决策树,然后再来验证我们测试集中的数据,看准确度是多少。

我们先创建一棵决策树decision_tree_classifier,然后使用训练数据来拟合这颗决策树,拟合之后我们可以测试我们的测试集数据,输出b,就是测试的准确度,准确度为:0.955555555556

其中DecisionTreeClassifier的参数有很多

1.criterion用什么指标: gini(基尼系数), entropy(信息增益)。一般说使用默认的基尼系数"gini"就可以了,即CART算法。除非你非得使用ID3, C4.5的更优特征选择 *** 。

2.splitter连续的特征从什么地方切分: best,random 前者是在所有特征中找更好的切分点而random是后者是在部分特征中(数据量大的时候)。

3.max_features更大使用多少个特征 :None(默认none为所有)log2(意味着划分时最多考虑log2N个特征),sqrt或者"auto"意味着划分时最多考虑根号N个特征,还可以max_features=整数,如果是整数,代表考虑的特征绝对数。如果是浮点数max_features=0.5,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。N 特征小于50的时候一般使用所有的。

4.max_depth预剪枝(更大深度): 数据少或者特征少的时候可以不管这个值,如果模型样本量多,特征也多的情况下,可以尝试限制下具体的取值取决于数据的分布。常用的可以取值10-100之间。

5.min_samples_split(节点样本个数):这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择更优特征来进行划分,如果样本量不大,不需要管这个值。如果样本量数量级非常大,则可以增大这个值。如果你有大概10万样本,建立决策树时,大概选择min_samples_split=10是差不多的。

6.min_samples_leaf(叶子节点最少的样本数):这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝,默认是1,如果样本量不大,不需要管这个值,如果要是样本数比较大的话可以使用这个参数,我们可以增大这个值,比如如果项目要是有10万样本的话,min_samples_leaf的值为5比较合适,当然实际情况可以自己来调整。

7.min_weight_fraction_leaf(叶子节点最小的样本权重和):默认是0,就是不考虑权重问题。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个阈值,则会和兄弟节点一起,被剪枝,一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

8.max_leaf_nodes :通过限制更大叶子节点数,可以防止过拟合,默认是"None”,即不限制更大的叶子节点数。如果加了限制,算法会建立在更大叶子节点数内更优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制具体的值可以通过交叉验证得到。

9.class_weight 指定样本各类别的的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。这里可以自己指定各个样本的权重,如果使用“balanced”,则算法会自己计算权重,样本量少的类别所对应的样本权重会高。如果你的样本类别分布没有明显的偏倚,则可以不管这个参数,使用默认的"None"就ok了。

10.min_impurity_split(节点划分最小不纯度):这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点不再生成子节点,就成为了叶子节点 。

11.presort(数据是否预排序):这个值是布尔值,默认是False不排序。排序就是在建树的过程中让划分点选择的更快,使得决策树建立的更快,但是使用这个排序功能的话,在样本数据很多的情况下,这个功能会耗费很多的时间,所以,一般数据很多的情况下是不用使用这个参数的,要是样本不是很多的情况下,其实也没有必要使用,因为样本本来就不多就直接建树就ok了,如果进行排序的话,这个操作简直就是多此一举,所以这个参数用处不大的。

12.min_impurity_decrease:如果这个分裂导致不纯度的降低大于或等于这个值,那么这个节点将被分割。(也不是很常用)。

13. random_state:值为int, RandomState实例或None(默认)。

以上就是我们使用sklearn库建造决策分类树时的一些参数,有些参数比较重要,有些参数不是很重要,

决策树很容易过拟合的种情况是特征数远远大于样本数,这种情况下,我们可以进行降维,比如主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA),这样拟合决策树模型效果会好。我们在训练的时候如果我们的样本集并不是很均衡,也就是样本的类别不均衡,我们可以使用class_weight来限制类别多的样本。如果输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用csr_matrix稀疏化。建造树的时候,可以主要使用树的高度这个参数进行限制,然后进行建造,等建造完成之后,使用graphviz工具来看当前建造的树是否符合我们的要求,如果不满足的话,可以调整这个参数。还要善用使用min_samples_split和min_samples_leaf参数来控制叶子节点的样本数量来有效防止过拟合。

以上的树是分类树(DecisionTreeClassifier)的一些常用的参数,回归树(DecisionTreeClassifier)的调参和这个分类树有一些不同,这个是需要我们注意一下的。

criterion: 可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。一般来说"mse"比"mae"更加精确。

其它的参数和上面的分类树是一样的,只不过参数class_weight在回归树种是没有的。

调参代码:

import pandas as pd

from sklearn.datasets import load_iris

from sklearn import tree

import pydotplus

from sklearn.model_selection import GridSearchCV

from sklearn.model_selection import train_test_split

from sklearn.model_selection import cross_val_score

from sklearn import metrics

iris_data = pd.read_csv('iris.data')

iris_data.columns = <'sepal_length_cm', 'sepal_width_cm', 'petal_length_cm', 'petal_width_cm', 'class'>

all_inputs = iris_data<<'sepal_length_cm', 'sepal_width_cm','petal_length_cm', 'petal_width_cm'>>.values

all_classes = iris_data<'class'>.values

decision_tree_classifier= tree.DecisionTreeClassifier()#构造分类树

parameters = {'max_depth': <1, 2, 3, 4, 5,6,7,8,9,10>,

'max_features': <1, 2, 3, 4>,

'min_samples_split':<2,3,4,5>,

'min_samples_leaf':<2,3,4,5>

}

training_inputs,testing_inputs,training_classes,testing_classes = train_test_split(all_inputs, all_classes, train_size=0.7, random_state=1)

if __name__ == "__main__":

decision_tree_classifier = tree.DecisionTreeClassifier()

clf = GridSearchCV(decision_tree_classifier, parameters, n_jobs=-1)

clf.fit(training_inputs,training_classes)

print (clf.best_params_)

print (clf.best_score_)

ypred = clf.predict(testing_inputs)

print(metrics.classification_report(testing_classes,ypred))

结果为:

可以看出当参数min_samples_leaf=5,max_depth=3,max_features=2,min_samples_split=5时训练准确率为更高的。

因为在实际的训练中,训练的结果对于训练集的拟合程度通常还是挺好的(初试条件敏感),但是对于训练集之外的数据的拟合程度通常就不那么令人满意了。因此我们通常并不会把所有的数据集都拿来训练,而是分出一部分来(这一部分不参加训练)对训练集生成的参数进行测试,相对客观的判断这些参数对训练集之外的数据的符合程度。这种思想就称为交叉验证(Cross Validation)

K折交叉验证(k-fold)

在机器学习中,将数据集A分为训练集(training set)B和测试集(test set)C,在样本量不充足的情况下,为了充分利用数据集对算法效果进行测试,将数据集A随机分为k个包,每次将其中一个包作为测试集,剩下k-1个包作为训练集进行训练。这样一共可以对分类器做k次训练,并且得到k个训练结果。

代码为:

from sklearn.model_selection import train_test_split

from sklearn.model_selection import cross_val_score

decision_tree_classifier = DecisionTreeClassifier()

cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)

cross_val_score的 参数为all_inputs:features all_classes:targets cv:k

这样我们输出cv_scores 的结果为:

我们这个程序分成了10份,所以我们现在会有10个测试结果,我们将其可视化,效果为:

*** .distplot(cv_scores)

plt.title('Average score: {}'.format(np.mean(cv_scores)))

plt.show()


我们前面学习了很多DecisionTreeClassifier()的参数可以用他们来限制决策树的建立,我们现在建立一棵其它的决策树,然后使用k这交叉验证 *** 来测试这颗决策树。

decision_tree_classifier = DecisionTreeClassifier(max_depth=1)cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)print (cv_scores) *** .distplot(cv_scores, kde=False)plt.title('Average score: {}'.format(np.mean(cv_scores)))plt.show()


StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同。

Iris数据集的历史生物学知识

如果我们了解数据背后的故事,那么数据会更有意义。

> Photo by Kalen Emsley on Unsplash

如果您曾经正式或非正式地接受过任何统计或机器学习培训,那么您就不会不熟悉Iris数据集,鉴于其受欢迎程度,它甚至拥有自己的Wikipedia页面。 大多数人对Iris数据集了解的是,它具有有关萼片和花瓣的长度和宽度度量的记录。 该数据集包含三种鸢尾属物种中的每种鸢尾属植物的50条记录:鸢尾鸢尾,鸢尾鸢尾和杂色鸢尾。

除此之外,您是否知道数据集来自何处? 你知道这些不同的物种是什么样吗? 如果您不知道答案,那就可以了。 这正是本文所要讨论的。 让我们简短地处理数据,并学习一些常见数据集背后的有趣故事。

数据集的历史

鸢尾花数据集也称为Fisher鸢尾花数据集。 您的猜测是正确的-费舍尔(Ronald Aylmer Fisher)爵士也是如此,他还发明了费舍尔的精确检验法。 费舍尔爵士是英国皇家学会的会员,1890年出生于英国伦敦,以统计学家和遗传学家而闻名。

> Sir Ronal Aylmer Fisher (Source: Wikipedia, License: Public Domain)

他对统计的贡献远远超出了费舍尔的精确检验。 例如,他开发了更大似然估计和方差分析(通常被称为ANOVA的首字母缩写)测试。 正如他的Wikipedia页面所指出的那样,由于这些重要的贡献,他在现代统计史上得到了高度评价。

对于统计工作,他被描述为"几乎单枪匹马为现代统计科学奠定基础的天才"和" 20世纪统计学中最重要的人物"。 — ***

1936年,费舍尔在《优生学年鉴》(Annals of Eugenics)上发表了题为"在分类学问题中使用多重测量"的报告。 如果您有兴趣,可以在此处阅读全文。 在本文中,Fisher开发并评估了根据花的形态区分虹膜种类的线性函数。 这是上述三种鸢尾属植物的萼片和花瓣尺寸的首次公开露面。 下面提供了原始数据表的快照。 请注意,这些度量单位是厘米。

> Morphological Measures of Iris Flowers (Part of the Iris Dataset, Source & License)

如下图所示,总体上,该判别功能在区分这些物种方面表现良好,除了杂色鸢尾和初生鸢尾之间有些重叠。 鸢尾鸢尾明显不同于其他两个物种。

> Figure From Fisher's Article on the Iris Dataset (Source & License)

但是,应该注意的是,费舍尔本人并没有收集这些数据。 在他的文章中,他明确地将数据源归功于Edgar Anderson博士,他在加拿大美丽的旅游胜地加斯佩半岛(GaspéPeninsula)收集了大部分数据。 我找不到Anderson博士的无版权图片,但是如果您有兴趣,可以在这里找到他的图片。

安德森博士1897年出生于纽约,并于21世纪初在美国密歇根州长大。 作为植物学家,安德森博士曾在圣路易斯华盛顿大学任教。 1929年,他接受了一项奖学金,与包括费舍尔爵士在内的一些科学家一起在英国工作。 通过这次合作机会,费舍尔获得了安德森博士的许可,可以使用上述文章中的数据。

除了收集这个著名的数据集的数据外,安德森博士还为植物遗传学做出了重要贡献,并出版了有关该领域的题为"渐渗杂交"的原著。 他的科学贡献使他于1934年当选为美国艺术与科学院院士,并于1954年当选为美国国家科学院院士。

鸢尾花生物学

你们当中有多少人实际上在花园或图片中看到了鸢尾花,特别是数据集中包含的那三种花? 我怀疑这个数字会很高,因为根据周围朋友和同事的回应,只有一小部分人告诉我他们以前见过鸢尾花追随者。 当然,我必须给他们看一些鸢尾花的照片,否则其中许多人甚至可能都不知道鸢尾花是什么。

撇开所有这些,我们知道数据集中的三个鸢尾物种:鸢尾鸢尾,鸢尾鸢尾和杂色鸢尾,并且我们也知道数据集记录了这些花的萼片和花瓣的长度和宽度。 让我们用一块石头杀死两只鸟-参见下图。

> Petals & Sepals for Iris setosa, Iris versicolor, and Iris virginica (Sources: 1, 2, 3, Licenses:

如上图所示,这些物种之间确实在形态上存在相似之处。 因此,有趣的是,费舍尔爵士在30年代开发的判别函数可以从统计角度很好地解决此问题。 然而,植物学家有更好的 *** 来区分这些物种。 实际上,安德森博士本人发表了题为"虹膜中的物种问题"的手稿,以讨论虹膜物种的歧视,您可以在此处阅读本文。 在文章中,安德森(Anderson)博士指出,这些花的种子形态更为丰富。 除花瓣和萼片的大小不同外,这三个物种之间的种子大小也存在明显差异。


最终思想

大数据,人工智能,机器学习,深度学习和许多其他数据科学短语几乎是每个学术和工业领域的热门话题。 鉴于市场上数据科学家的大量工作需求,许多人进入了这些领域。 一些数据科学家错误地认为,他们唯一的工作就是处理提供给他们的数据。

他们并没有真正意识到我们的所有数据都有其来源和内容背景。 数据的处理,分析和解释都需要相关领域的内容知识。 因此,如果我们想做更好的数据科学,我们将永远不会忽略我们正在处理的数据所基于的内容知识。

关于当前文章的快速笔记。 我之一次了解Iris数据集是在我使用SAS学习判别分析时。 坦白说,我对数据集本身并没有太多考虑。 但是,当我学习更多有关数据科学研究的知识时,我发现对数据进行深入了解至关重要。 因此,事后看来,我想找出Iris数据集背后的故事,并与您分享。 我希望您喜欢本文的一部分,并学到了一些东西–至少,您应该知道鸢尾花的萼片和花瓣对不对?


(本文翻译自Yong Cui, Ph.D.的文章《The Iris Dataset — A Little Bit of History and Biology》,参考:https://towardsdatascience.com/the-iris-dataset-a-little-bit-of-history-and-biology-fb4812f5a7b5)

如何入门AI?五大新手项目奉上

鱼羊 编译整理

量子位 报道 | 公众号 QbitAI

这年头不学点AI知识,可能都不好意思说自己是新时代的接班人了。

人工智能风头正盛,无论你是支持还是怀疑,AI对这个时代的影响都已逐渐渗透到各行各业当中,哪怕身处非互联网行业,也能感受到AI的滚滚浪潮。

学习已成刚需,不过对于初学者而言,要正正经经上手机器学习,如何入门就有点让人头大了。

好在计算机领域向来有和谐互助之风,德国程序猿Michiel Mulders近日就精心炮制了一份机器学习入门新手指南。一起来看看AI大法该当如何修炼吧。

入门指南

欲练此功,首先要知道,纸上谈兵是本门大忌。

吴恩达就曾经说到,想要入门机器学习,应该进行一些项目实践。

所以入门之一步,从选择一个数据集开始:

  • 找到一个大小合宜,并且相对容易分析的数据集。UCL ML RepositoryKaggle盛产此物。
  • 对数据集进行试验。挑几个顶级的机器学习算法跑一跑这些数据,看看数据的表现,了解一下每种算法的性能。
  • 挑选表现更佳的算法, *** 它。

这就完事了?no,no,no,本份指南还贴心奉上五佳项目,任君挑选。

↓↓↓↓↓↓

TOP 5

项目:监督式机器学习

数据集:鸢尾花数据集

鸢尾花数据集堪称机器学习领域的“Hello World”。对数据一无所知?那么选择它就对了。

这个数据集的好处是足够小,仅仅只有150行,并且它只有四个属性:花瓣长度,花瓣宽度,萼片长度和萼片宽度。

通过判别四个已知属性,四种不同类型的鸢尾花在数据集中被标记出来,所以你可以拿它来学学监督式机器学习。

这里建议使用多元分类训练 *** 。

另外,记得给自己设立一个小目标:根据花瓣和萼片的大小对三种花进行分类。

相关链接:

UCI机器学习仓库(UCI ML Repository):

https://archive.ics.uci.edu/ml/index.php

Kaggle数据集:

https://www.kaggle.com/datasets

项目:交易预测

平台:GNY

很多流行的机器学习服务价格高昂,对于新手十分不友好。不如选择GNY团队的机器学习平台,这个平台挺好挺强大,最重要的是提供免费的下载安装。

GNY团队还发布了一个通过神经 *** 预测零售交易的demo,正式版本将在今夏登陆,还将提供定制服务。

对于机器学习新人小白来说,这个demo不失为一个有趣的入门项目。你可以到MLWave上找一个数据集,根据消费历史来预测哪些人会成为回头客。

相关链接:

GNY机器学习平台:

https://www.gny.io/

MLWave回头客数据集:

https://mlwave.com/predicting-repeat-buyers-vowpal-wabbit/

项目:情绪分析

数据集:twitter

情绪分析是机器学习里非常有趣的一种应用,检索数据也很容易获得,Reddit、Facebook和Linkedln都提供了易于使用的API。不过首选还是Twitter的数据,Twitter平台上的数据格式一致,预处理也要容易得多。

首先!pip install Python -twitter,然后就开动吧,不过过度使用可是会被列入黑名单的哟。

再列几个具体的方向以供参考:

  • 分析对新发布电影的情绪,并将其与IMDB和其他评级网站上的评论进行比较。
  • 分析围绕特定选举或任何其他政治话题的情绪。
  • 根据推文的情绪预测前50种加密货币未来的价格。

相关链接:

Twitter数据集:

https://github.com/shaypal5/awesome-twitter-data

项目:推荐系统

数据集:Movielens

想必没有人会对推荐系统感到陌生。

推荐系统是机器学习技术在商业中最成功和最广泛的应用之一,几乎渗入到了日常生活的每一个角落。网易云音乐的个性推荐,神奇的抖音算法都属于这一范畴。

关于推荐系统,可以使用两种算法:

  • 基于内容推荐算法:寻找内容的相似性。
  • 协作过滤算法:寻找交互中的相似性。即对一大群人进行分析,确认品位相近的人。

Movielens是更受欢迎的电影评级数据集之一,对初学者来说是试验推荐算法的理想数据集。

于是你可以再立一个小目标了:根据用户评分来预测他们会喜欢哪部电影。

项目:股票价格预测

数据集:Quandl

对于股民来说,如果能预测股票价格,那岂不是亦可赛艇?

但不管你是不是股民,都可以试试用机器学习来实现股票价格预测。

我们先来列列关键字:

  • 波动率指数
  • 历史价格
  • 全球宏观经济指标
  • 基本面分析
  • 指标技术分析

股票市场具有更短的反馈周期,也就是预测的结果可以更快被验证,十分适合新手学习。

选择一个简单的机器学习示例,到Quandl.com上下载股票市场数据集,就可以动手预测未来6个月的股票价格变化了。友情提醒:AI只负责产生结果,不对结果负责

相关链接:

Quandl数据集:

https://www.quandl.com/

新手向TOP 5项目介绍完毕。看到这里,是不是已经摩拳擦掌,感觉自己可以分分钟入门AI啦?快拎上数据集,AI江湖等你亮剑~

— 完 —

诚挚 ***

量子位正在招募编辑/记者,工作地点在北京中关村。期待有才气、有热情的同学加入我们!相关细节,请在量子位公众号(QbitAI)对话界面,回复“ *** ”两个字。

量子位 QbitAI · 头条号签约作者

?'?' ? 追踪AI技术和产品新动态

我的之一个Python机器学习应用:鸢尾花分类

初识数据

鸢(yuan,一声)尾花(Iris)数据集,是机器学习中的一个经典数据集。

鸢尾花是一种植物,我们需要通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica,对应数据集中的标签0,1,2)三个种类中的哪一类。

鸢尾花数据集包含在sklearn中的datasets类中,可以通过调用load_iris()函数来加载这个数据集,代码如下。

from sklearn.datasets import load_irisiris_dataset=load_iris()

说明:这里用到模块sklearn,需要自己安装。

拆分训练集和测试集

机器学习中,通常需要将收集好的带标签的数据分成两部分,一部分数据用于构建机器学习模型,叫做训练集(train set),其余的数据用来评估模型性能,叫做测试集(test set)。

from sklearn.model_selection import train_test_splitX_train,X_test,y_train,y_test=train_test_split(iris_dataset<'data'>,iris_dataset<'target'>,test_size=0.25,random_state=0)
  • sklearn中的train_test_split函数可以将数据按照一定比例分成测试集和训练集。
  • 这里将总体数据的75%作为训练集,25%作为验证集。
  • andom_state指定随机数种子,使得函数的输出固定不变,让结果可重现。

构建之一个模型:K近邻算法

这里选择k近邻算法,这是机器学习中一个最基本,也是最容易理解的一个算法。

from sklearn.neighbors import KNeighborsClassifierknn=KNeighborsClassifier(n_neighbors=1)knn.fit(X_train,y_train)

模型评估

衡量模型的优劣可以通过计算精度来衡量模型的优劣,精度就是品种预测正确的花所占的比例。

knn.score(X_test,y_test)

输出结果:

0.9736842105263158

从输出结果可以看出,测试集的精度约为0.97。

预测

例如,我们在野外发现了一朵鸢尾花,花萼长5cm宽2.9cm,花瓣长1cm宽0.2cm,这朵鸢尾花属于哪个品种呢?

import numpy as npX1=np.array(<<5,2.9,1,0.2>>)y1=knn.predict(X1)print(y1)

输出:

<0>

从上面看出,这朵新的鸢尾花的类别标签是0,也就是说它属于Setosa品种。

鸢尾花数据集,鸢尾花数据集下载-第1张图片-

Python数据分析之Seaborn(分类分析绘图 )


?Seaborn分类分析绘图

%matplotlib inlineimport numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltimport seaborn as snssns.set(style="whitegrid", color_codes=True)
np.random.seed(sum(map(ord, "categorical")))titanic = sns.load_dataset("titanic") #导入泰坦尼克数据集tips = sns.load_dataset("tips") #导入小费数据集iris = sns.load_dataset("iris") #导入鸢尾花数据集

散点图

sns.stripplot(x="day", y="total_bill", data=tips)

问题:有重叠,无法看见数据的密度

  • 解决 *** 一:通过jitter抖动

抖动是平时可视化中的常用的观察“密度”的 *** ,除了使用参数抖动,特定的抖动需求也可以用numpy在数据上处理实现

sns.stripplot(x="day", y="total_bill", data=tips, jitter=True) # jitter抖动
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a3216a0>

  • 解决 *** 二:通过swarmplot()函数
sns.swarmplot(x="day", y="total_bill", data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x22d87f3b128>

sns.swarmplot(x="day", y="total_bill", hue="sex",data=tips) #hue 参数控制分组绘图
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a428860>

箱型图

箱形图(Box-plot)又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。

如上图所示,标示了图中每条线表示的含义,其中应用到了分位值(数)的概念。
主要包含六个数据节点,将一组数据从大到小排列,分别计算出它的上边缘,上四分位数Q3,中位数,下四分位数Q1,下边缘,还有一个异常值。

举例说明,以下是箱形图的具体例子:


这组数据显示出:


  • 最小值(minimum)=5
  • 下四分位数(Q1)=7
  • 中位数(Med--也就是Q2)=8.5
  • 上四分位数(Q3)=9
  • 更大值(maximum)=10
  • 平均值=8
  • 四分位间距=Q3-Q1=2 (即ΔQ)
  • 更大值区间: Q3+1.5ΔQ = 12
  • 最小值区间: Q1-1.5ΔQ = 4
  • mild outlier = 3.5
  • extreme outlier = 0.5
sns.boxplot(x="day", y="total_bill", hue="time", data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x22d8bbd7240>

琴形图

seaborn.violinplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, bw='scott', cut=2, scale='area', scale_hue=True, gridsize=100, width=0.8, inner='box', split=False, orient=None, linewidth=None, color=None, palette=None, saturation=0.75, ax=None, **kwargs)
  • split: bool, optional #琴形图是否从中间分开两部分
  • scale: {“area”, “count”, “width”}, optional #用于调整琴形图的宽带。
    • area——每个琴图拥有相同的面域;
    • count——根据样本数量来调节宽度;
    • width——每个琴图则拥有相同的宽度。
  • inner: {“box”, “quartile”, “point”, “stick”, None}, optional #控制琴图内部数据点的形态。
    • box——绘制微型 boxplot;
    • quartiles——绘制四分位的分布;
    • point/stick——绘制点或小竖条。
sns.violinplot(x="total_bill", y="day", hue="time", data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a9f97b8>

sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, split=True) #split: bool, optional #琴形图是否从中间分开两部分

条形图

显示值的集中趋势可以用条形图

sns.barplot(x="sex", y="survived", hue="class", data=titanic)
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a5bc358>

点图

点图可以更好的描述变化差异

sns.pointplot(x="sex", y="survived", hue="class", data=titanic)
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a5bcda0>

#详细指定属性值sns.pointplot(x="class", y="survived", hue="sex", data=titanic,              palette={"male": "g", "female": "m"}, #  指定颜色              markers=<"^", "o">,  # 指定点样式              linestyles=<"-", "--">); # 指定线型样式

组合

#琴型图 + 分散点图sns.violinplot(x="day", y="total_bill", data=tips, inner=None)sns.swarmplot(x="day", y="total_bill", data=tips, color="w", alpha=.5)
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a3f4908>

多层面板分类图

factorplot()函数是对各种图形的一个更高级别的API封装,在Seaborn中非常常用。

seaborn.factorplot(x=None, y=None, hue=None, data=None, row=None, col=None, col_wrap=None, estimator=<function mean>, ci=95, n_boot=1000, units=None, order=None, hue_order=None, row_order=None, col_order=None, kind='point', size=4, aspect=1, orient=None, color=None, palette=None, legend=True, legend_out=True, sharex=True, sharey=True, margin_titles=False, facet_kws=None, **kwargs)

参数说明:

  • x,y 数据集变量(变量名)
  • hue 控制分组绘图(变量名)
  • date 数据集 (数据集名)
  • row,col 更多分类变量进行平铺显示 (变量名)
  • col_wrap 每行的更高平铺数 (整数)
  • estimator 在每个分类中进行矢量到标量的映射 (矢量)
  • ci 置信区间 (浮点数或None)
  • n_boot 计算置信区间时使用的引导迭代次数 (整数)
  • units 采样单元的标识符,用于执行多级引导和重复测量设计 (数据变量或向量数据)
  • order, hue_order 对应排序列表 (字符串列表)
  • row_order, col_order 对应排序列表 (字符串列表)
  • kind : 可选:point 默认, bar 柱形图, count 频次, box 箱体, violin 提琴, strip 散点,swarm 分散点
  • size 每个面的高度(英寸) (标量)
  • aspect 纵横比 (标量)
  • orient 方向 ("v"/"h")
  • color 颜色 (matplotlib颜色)
  • palette 调色板 (seaborn颜 *** 板或字典)
  • legend hue的信息面板 (True/False)
  • legend_out 是否扩展图形,并将信息框绘制在中心右边 (True/False)
  • share{x,y} 共享轴线 (True/False)
  • facet_kws FacetGrid的其他参数 (字典)
sns.factorplot(x="day", y="total_bill", hue=" *** oker", data=tips) #默认是点图
<seaborn.axisgrid.FacetGrid at 0x22d8a79def0>

sns.factorplot(x="day", y="total_bill", hue=" *** oker", data=tips, kind="bar") #绘制条形图
<seaborn.axisgrid.FacetGrid at 0x22d8a648748>

sns.factorplot(x="day", y="total_bill", hue=" *** oker",               col="time", data=tips, kind="swarm") #绘制分散点图
<seaborn.axisgrid.FacetGrid at 0x22d8a867be0>

sns.factorplot(x="time", y="total_bill", hue=" *** oker",               col="day", data=tips, kind="box", size=4, aspect=.5) #绘制箱型图
<seaborn.axisgrid.FacetGrid at 0x22d8a8bcb00>

参考