* 题目描述:创建一个水果识别器,根据水果的属性,判断该水果的种类。
* 题目要求:
* 模仿课堂的讲解内容,根据“近朱者赤”的原则,手工实现一个简单的分类器
* 选取1/5的数据作为测试集
* 数据文件:
* 数据源下载地址:https://video.mugglecode.com/fruit_data.csv
* fruit_data.csv,包含了59个水果的的数据样本。
* 共5列数据
* fruit_name:水果类别
* mass: 水果质量
* width: 水果的宽度
* height: 水果的高度
* color_score: 水果的颜色数值,范围0-1。
* 0.85 - 1.00:红色
* 0.75 - 0.85: 橙色
* 0.65 - 0.75: 黄色
* 0.45 - 0.65: 绿色
* 如图所示:https://video.mugglecode.com/color_score.jpg
# 数据源下载地址:https://video.mugglecode.com/fruit_data.csv
查看提示
- * 问题拆解提示:
- 1. 如何分割数据集,用于训练和验证模型?
- 2. 如何计算样本的距离?
- 3. 如何找到最近的样本?
- 4. 如何验证模型?
- * 问题解决提示:
- 1. 利用scikit-learn模块中的train_test_split()(http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)方法进行数据集的划分,其中
- * test_size',':用于指定测试集的大小,这里test_size=1/5;
- * random_state:用于指定随机状态,通常设定一个固定的数字用于重复实验,这里random_state=20;
- 2. 利用SciPy模块中的欧式距离euclidean()(https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.euclidean.html)计算空间中两个点的距离,及样本间的距离;
- 3. 利用NumPy模块中的argmin()(https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmin.html)找到距离值最小的样本,即最近的样本
- 4. 使用“准确率”进行模型的验证,即识别对的样本数目除以总的测试样本数目。
查看答案
# -*- coding: utf-8 -*-
import pandas as pd
from sklearn.model_selection import train_test_split
from scipy.spatial.distance import euclidean
import numpy as np
# 使用的特征列
FEAT_COLS = ['mass', 'width', 'height', 'color_score']
def get_prediction(test_sample_feat, train_data):
"""
在训练集中找出和test_sample_feat最近的训练样本,并以训练样本的标签作为预测值
参数:
-test_sample_feat: 测试样本的特征
-train_data: 训练集
返回:
-pred_label: 预测结果
"""
dis_list = []
for idx, row in train_data.iterrows():
# 训练样本特征
train_sample_feat = row[FEAT_COLS].values
# 2. 样本间距离计算
dis = euclidean(train_sample_feat, test_sample_feat)
dis_list.append(dis)
# 3. 找到最近的样本
pos = np.argmin(dis_list)
pred_label = train_data.iloc[pos]['fruit_name']
return pred_label
def main():
"""
主函数
"""
# 读取数据文件
fruit_data = pd.read_csv('./fruit_data.csv')
# 1. 分割数据集
train_data, test_data = train_test_split(fruit_data, test_size=1/5, random_state=20)
# 预测准确的个数
acc_count = 0
# 对测试集中每个样本做预测
for idx, row in test_data.iterrows():
# 测试样本特征
test_sample_feat = row[FEAT_COLS].values
# 在训练集中找出和该样本最近的训练样本,并以训练样本的标签作为预测值
pred_label = get_prediction(test_sample_feat, train_data)
# 真实标签
true_label = row['fruit_name']
print('样本{}的真实标签:{},预测标签:{}'.format(idx, true_label, pred_label))
if pred_label == true_label:
acc_count += 1
# 4. 使用准确率验证模型
accuracy = acc_count / test_data.shape[0]
print('预测准确率为:{:.2f}%'.format(accuracy * 100))
if __name__ == '__main__':
main()