python 分类_如何用Python解决一个简单的分类问题(水果版)?

在本文,我们会用 Scikit-learn 应用几个 Python 写的机器学习算法,Scilit-learn 是用于 Python 的最流行的机器学习工具。我们会用一个简单的数据集训练一个分类器,以区分不同种类的水果。

我(作者Susan Li——译者注)写本文的目的是找出最适合解决手头问题的机器学习算法,希望通过比较几种不同的算法,选择最好的那个。我们开始吧!

数据

我们用到的水果数据集由爱丁堡大学教授 Iain Murray 所创。他买了很多种类的橙子、柠檬和苹果,并把它们的相关数据记录在表格中。然后密歇根大学的一些学者将这些水果数据编排了格式,点击这里可以下载这些数据:https://github.com/susanli2016/Machine-Learning-with-Python/blob/master/fruit_data_with_colors.txt​github.com

我们先来看看这些数据的头几行,输入代码:

%matplotlib inline

import pandas as pd

import matplotlib.pyplot as plt

fruits = pd.read_table('fruit_data_with_colors.txt')

fruits.head()

结果如图:

数据集的每一行代表水果的一个种类,每个种类有几个特征,在图表中以列表示。

在数据集中,一共有 59 个水果和 7 个特征:print(fruits.shape)

(59, 7)

数据集中一共有 4 种水果:

print(fruits['fruit_name'].unique())

[‘apple’ ‘mandarin’ ‘orange’ ‘lemon’]

[‘苹果’‘柑橘’‘橙子’‘柠檬’]

除了柑橘外,数据相当均衡,我们还是接着用它。

print(fruits.groupby('fruit_name').size())

import seaborn as sns

sns.countplot(fruits['fruit_name'],label="Count")

plt.show()

可视化

每一个数字变量的箱型图会让我们更清楚地看到输入变量的分布状况:

fruits.drop('fruit_label', axis=1).plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False, figsize=(9,9),

title='Box Plot for each input variable')

plt.savefig('fruits_box')

plt.show()

每个输入变量的箱型图

从图中可以看出,颜色分值(color score)可能有很近的高斯分布。

import pylab as pl

fruits.drop('fruit_label' ,axis=1).hist(bins=30, figsize=(9,9))

pl.suptitle("Histogram for each numeric input variable")

plt.savefig('fruits_hist')

plt.show()

每个数字输入变量的直方图

有几对属性相互关联(质量和宽度),表明存在很高的关联性和可预测关系。

from pandas.tools.plotting import scatter_matrix

from matplotlib import cm

feature_names = ['mass', 'width', 'height', 'color_score']

X = fruits[feature_names]

y = fruits['fruit_label']

cmap = cm.get_cmap('gnuplot')

scatter = pd.scatter_matrix(X, c = y, marker = 'o', s=40, hist_kwds={'bins':15}, figsize=(9,9), cmap = cmap)

plt.suptitle('Scatter-matrix for each input variable')

plt.savefig('fruits_scatter_matrix')

每个输入变量的散布矩阵

数据统计总结

我们可以看到,数值的规模并不相同。我们需要对计算后用于训练集的测试集进行缩放。

创建训练集和数据集,并进行缩放

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()

X_train = scaler.fit_transform(X_train)

X_test = scaler.transform(X_test)

搭建模型

逻辑回归

from sklearn.linear_model import LogisticRegression

logreg = LogisticRegression()

logreg.fit(X_train, y_train)

print('Accuracy of Logistic regression classifier on training set: {:.2f}'

.format(logreg.score(X_train, y_train)))

print('Accuracy of Logistic regression classifier on test set: {:.2f}'

.format(logreg.score(X_test, y_test)))

逻辑回归分类器在训练集中的准确率:70%

逻辑回归分类器在测试集中的准确率:40%

决策树

from sklearn.tree import DecisionTreeClassifier

clf = DecisionTreeClassifier().fit(X_train, y_train)

print('Accuracy of Decision Tree classifier on training set: {:.2f}'

.format(clf.score(X_train, y_train)))

print('Accuracy of Decision Tree classifier on test set: {:.2f}'

.format(clf.score(X_test, y_test)))

决策树分类器在训练集中的准确率:100%

决策树分类器在测试集中的准确率:73%

K最近邻算法(K-NN)

from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier()

knn.fit(X_train, y_train)

print('Accuracy of K-NN classifier on training set: {:.2f}'

.format(knn.score(X_train, y_train)))

print('Accuracy of K-NN classifier on test set: {:.2f}'

.format(knn.score(X_test, y_test)))

K最近邻算法分类器在训练集中的准确率:95%

K最近邻算法分类器在测试集中的准确率:100%

线性判别分析(LDA)

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

lda = LinearDiscriminantAnalysis()

lda.fit(X_train, y_train)

print('Accuracy of LDA classifier on training set: {:.2f}'

.format(lda.score(X_train, y_train)))

print('Accuracy of LDA classifier on test set: {:.2f}'

.format(lda.score(X_test, y_test)))

线性判别分析分类器在训练集中的准确率:86%

线性判别分析分类器在测试集中的准确率:67%

高斯朴素贝叶斯

from sklearn.naive_bayes import GaussianNB

gnb = GaussianNB()

gnb.fit(X_train, y_train)

print('Accuracy of GNB classifier on training set: {:.2f}'

.format(gnb.score(X_train, y_train)))

print('Accuracy of GNB classifier on test set: {:.2f}'

.format(gnb.score(X_test, y_test)))

高斯朴素贝叶斯分类器在训练集中的准确率:86%

高斯朴素贝叶斯分类器在测试集中的准确率:67%

支持向量机

from sklearn.svm import SVC

svm = SVC()

svm.fit(X_train, y_train)

print('Accuracy of SVM classifier on training set: {:.2f}'

.format(svm.score(X_train, y_train)))

print('Accuracy of SVM classifier on test set: {:.2f}'

.format(svm.score(X_test, y_test)))

支持向量机分类器在训练集中的准确率:61%

支持向量机分类器在训练集中的准确率:33%

综合来看,K 最近邻算法是我们尝试过的模型中准确率最高的那个。混淆矩阵显示它在测试集中毫无差错。不过,我们用的测试集太小了。

from sklearn.metrics import classification_report

from sklearn.metrics import confusion_matrix

pred = knn.predict(X_test)

print(confusion_matrix(y_test, pred))

print(classification_report(y_test, pred))

绘出K-NN分类器的决策边界

import matplotlib.cm as cm

from matplotlib.colors import ListedColormap, BoundaryNorm

import matplotlib.patches as mpatches

import matplotlib.patches as mpatches

X = fruits[['mass', 'width', 'height', 'color_score']]

y = fruits['fruit_label']

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

def plot_fruit_knn(X, y, n_neighbors, weights):

X_mat = X[['height', 'width']].as_matrix()

y_mat = y.as_matrix()

# Create color maps

cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF','#AFAFAF'])

cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF','#AFAFAF'])

clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)

clf.fit(X_mat, y_mat)

# Plot the decision boundary by assigning a color in the color map

# to each mesh point.

mesh_step_size = .01 # step size in the mesh

plot_symbol_size = 50

x_min, x_max = X_mat[:, 0].min() - 1, X_mat[:, 0].max() + 1

y_min, y_max = X_mat[:, 1].min() - 1, X_mat[:, 1].max() + 1

xx, yy = np.meshgrid(np.arange(x_min, x_max, mesh_step_size),

np.arange(y_min, y_max, mesh_step_size))

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

# Put the result into a color plot

Z = Z.reshape(xx.shape)

plt.figure()

plt.pcolormesh(xx, yy, Z, cmap=cmap_light)

# Plot training points

plt.scatter(X_mat[:, 0], X_mat[:, 1], s=plot_symbol_size, c=y, cmap=cmap_bold, edgecolor = 'black')

plt.xlim(xx.min(), xx.max())

plt.ylim(yy.min(), yy.max())

patch0 = mpatches.Patch(color='#FF0000', label='apple')

patch1 = mpatches.Patch(color='#00FF00', label='mandarin')

patch2 = mpatches.Patch(color='#0000FF', label='orange')

patch3 = mpatches.Patch(color='#AFAFAF', label='lemon')

plt.legend(handles=[patch0, patch1, patch2, patch3])

plt.xlabel('height (cm)')

plt.ylabel('width (cm)')

plt.title("4-Class classification (k =%i, weights = '%s')"

% (n_neighbors, weights))

plt.show()

plot_fruit_knn(X_train, y_train, 5, 'uniform')

4种水果的分类

k_range = range(1, 20)

scores = []

for k in k_range:

knn = KNeighborsClassifier(n_neighbors = k)

knn.fit(X_train, y_train)

scores.append(knn.score(X_test, y_test))

plt.figure()

plt.xlabel('k')

plt.ylabel('accuracy')

plt.scatter(k_range, scores)

plt.xticks([0,5,10,15,20])

在该数据集情况中,当 K 等于 5 时,我们获得了最高的准确率。

总结

在本文,我们主要是关注了预测准确率。我们的目标是学习找到一个有很好的泛化性能的模型。这个模型可以将预测准确率最大化。我们想找到最适合解决手头问题的机器学习算法(比如文中的水果分类问题),所以比较了几种不同的算法,最终选择了最优的K最近邻算法。

可以点击这里获取本文所用的源代码:susanli2016/Machine-Learning-with-Python​github.comv2-2f9fdad0602187fd7497d93e4ff7d731_ipico.jpg

参考资料:

作者:Susan Li

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值