构建没有数据集的辣辣椒分类器,准确性达到96%

2020-08-31 16:37:12 浏览数 (2)

作者 | Michelangiolo Mazzeschi

来源 | Medium

编辑 | 代码医生团队

在没有数据集的情况下使用分类模型。Github存储库中提供了完整的代码。

https://github.com/arditoibryan/Projects/upload

在本文中,我将创建一个能够通过测量和颜色识别辣辣椒的AI。因为将无法在线找到任何关于辣胡椒测量的数据集,所以将使用统计方法自行生成该数据集。

处理:

  1. 查找可用数据
  2. 进行测量
  3. 从分布创建数据集
  4. 创建模型
  5. 绩效评估

1.查找可用数据

如前所述,不太可能找到要构建的所有内容的数据集。想构建一个辣味分类器,如果没有任何数据开始,这将是一项艰巨的任务。在互联网上唯一能找到的是一张不同麻辣胡椒的比较表(希望是相同的比例)。

将需要将此数据转换为数字数据。所能做的就是对这些图像进行测量,并将它们作为特征放置在数据集中。

2.进行测量

为了进行测量,可以使用像素。在了解了像素到厘米的转换率之后,可以测量每个香辛椒的大小(以像素为单位),并将其转换为现实世界的比例。

这是最终表,其中所有度量(名称,高度,宽度和颜色)均已转换为特征。

代码语言:javascript复制
#   measurements
pepper_measurements_px = [
                          ['Anaheim', 262, 63, 'Green'],
                          ['Cubanelle', 222, 70, 'Green'],
                          ['Cayenne', 249, 22, 'Red'],
                          ['Shishito', 140, 21, 'Green'],
                          ['Hungarian Wax', 148, 63, 'Orange'],
['Jimmy Nardello', 190, 23, 'Red'],
                          ['Fresno', 120, 43, 'Red'],
                          ['Jalapeno', 106, 40, 'Dark Green'],
                          ['Aji Amarillo', 92, 13, 'Yellow'],
                          ['Aji Dulce', 81, 30, 'Red'],
['Serrano', 74, 14, 'Dark Green'],
                          ['Padron', 62, 38, 'Dark Green'],
                          ['Scotch Bonnet', 37, 42, 'Yellow'],
                          ['Habanero', 67, 21, 'Orange'],
                          ['Cumari', 18, 11, 'Yellow'],
]

现在,将生成一个100.000个辛辣辣椒样本的数据集。

3.从分布创建数据集

在开始创建分布之前,首先需要将像素转换为厘米。然后对于长度和宽度,将需要使用此数据作为均值的两个单独的正态分布。对于标准差,将使用平均值的10%(这样就不必在Google上搜索每个辛辣胡椒的详细信息)。

创建功能

正在创建一组函数,将允许创建n个数据集,并输入大小。将用100,000个样本制作辣胡椒。

代码语言:javascript复制
#simulated probability distribution of one stock
from scipy.stats import skewnorm
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
def create_peppers(sd, mean, alfa, size):
  #invertire il segno di alfa
  x = skewnorm.rvs(-alfa, size=size)
  def calc(k, sd, mean):
    return (k*sd) mean
  x = calc(x, sd, mean) #standard distribution
#graph the distribution
  #pd.DataFrame(x).hist(bins=100)
#pick one random number from the distribution
  #formally I would use cdf, but I just have to pick randomly from the 1000000 samples
  df = [np.random.choice(x) for k in range(size)]
  #return the DataFrame
  return pd.DataFrame(df)
def cm_converter(px_measurements):
  pc_cm = 0.05725
  for _ in range(len(px_measurements)):
    px_measurements[_][1] *= pc_cm
    px_measurements[_][2] *= pc_cm
  return px_measurements

创建数据集

现在准备创建数据集。可以指定使用平均值的10%作为标准偏差(可以很容易地从height_sd和widht_sd进行更改):

代码语言:javascript复制
#   create converted list
pepper_measurements_cm = cm_converter(pepper_measurements_px)
#   create final datasets
heigh_sd = 0.1
width_sd = 0.1
df = pd.DataFrame()
for _ in pepper_measurements_cm:
  #   create height
  #SD is 10% of the height
  df_height = create_peppers(_[1]*heigh_sd, _[1], 0, 100000)
  #   create width
  #SD is 10% of the width
  df_width = create_peppers(_[2]*width_sd, _[2], 0, 100000)
  #create DataFrame
  df_single = pd.concat([df_height, df_width], axis=1)
  df_single.columns = ['height', 'width']
  #create name
  df_single['name'] = str(_[0])
  df_single['color'] = str(_[3])
df = pd.concat([df, df_single], axis=0)
df

单个生成特征的正态分布

这是最终结果:合并后,数据集计数了150万个样本:

最终数据集

如果在不同的直方图中绘制高度和宽度:

分开的直方图中的高度和宽度

4.创建模型

将使用的模型是朴素贝叶斯分类器。而不是许多其他模型,该模型专用于以下数据:

  • 是独立的
  • 服从正态分布

因为是按照这些前提建立数据集的,所以该分类器非常适合我要构建的内容。

预处理

唯一要做的预处理步骤是使用one_hot编码算法对颜色进行编码:

代码语言:javascript复制
#backup
X = df.copy()
def one_hot(df, partitions):
  #togliamo le colonne da X
  for col in partitions:
    k = df.pop(col)
    k = pd.get_dummies(k, prefix=col)
    df = pd.concat([df, k] , axis=1)
  return df
X = one_hot(X, ['color'])
X

选择功能和标签

代码语言:javascript复制
y = X.pop('name')
y

标签

代码语言:javascript复制
X

one_hot编码后的功能

分割

代码语言:javascript复制
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

现在将随机分割特征和标签,比率为80:20就足够了。

训练模型

代码语言:javascript复制
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf.fit(X_train, y_train)

该模型已经过训练:

代码语言:javascript复制
GaussianNB(priors=None, var_smoothing=1e-09)

5.绩效评估

训练完模型后,将在AI在训练过程中从未见过的数据集部分进行测试:

代码语言:javascript复制
clf.score(X_test, y_test, sample_weight=None)
0.9659133333333333

该模型达到了出色的96%精度!

0 人点赞