手工实现水果分类器,没用knn\svm等算法。
分类原理是:待预测值与训练集中的每一个值都计算欧式距离,其中距离最短的分类就是预测值的分类
还包括对原始数据的可视化,能对原始数据的分布有一个大致的了解。
原始数据格式如下:
fruit_name mass width height color_score
apple 192 8.4 7.3 0.55
apple 180 8 6.8 0.59
apple 176 7.4 7.2 0.6
mandarin 86 6.2 4.7 0.8
mandarin 84 6 4.6 0.79
mandarin 80 5.8 4.3 0.77
输出结果截选如下:
41行,预测值是:apple,真实值是:orange
38行,预测值是:orange,真实值是:orange
54行,预测值是:lemon,真实值是:lemon
35行,预测值是:lemon,真实值是:orange
预测准确率是:66.67%
import pandas as pd
from sklearn.model_selection import train_test_split
from scipy.spatial.distance import euclidean
import seaborn as sns
import matplotlib.pyplot as plt
data_path = \'./data/fruit_data.csv\'
output_dir = \'./output/\'
category = [\'apple\',\'mandarin\', \'lemon\', \'orange\']
feat_cols = [\'mass\',\'width\',\'height\',\'color_score\']
# 成对变量展示图
def pair_plot(df,category):
sns.pairplot(data=df,hue=category) # hue:针对某一字段进行分类
plt.tight_layout()
plt.savefig(output_dir + category) # 默认保存为fruit_name.png
plt.show()
# 对fruit数据的探索图
def eda_plot_for_fruit(data_df):
fruit_color_dict = {\'apple\':\'red\',
\'mandarin\':\'green\',
\'lemon\':\'blue\',
\'orange\':\'yellow\'
}
fig, axes = plt.subplots(2, 1, figsize=(8, 8))
for name,color in fruit_color_dict.items():
data_df[data_df[\'fruit_name\'] == name].plot(ax=axes[0],kind=\'scatter\',x=\'width\',y=\'height\',
label=name,color=color)
for name,color in fruit_color_dict.items():
data_df[data_df[\'fruit_name\'] == name].plot(ax=axes[1], kind=\'scatter\', x=\'mass\', y=\'color_score\',
label=name, color=color)
plt.tight_layout()
plt.savefig(output_dir+\'fruit_eda.png\')
plt.show()
#给定带预测的特征值和训练数据集,计算欧氏距离,输出预测值
def pred_cate(feat_values,train_data_df):
dis_list = []
for idx,row in train_data_df.iterrows():
dis = euclidean(feat_values,row[feat_cols].values) # 计算欧氏距离
dis_list.append(dis)
min_idx = dis_list.index(min(dis_list)) # 最短距离值的索引
# pos = np.argmin(dis_list) # 这种方法也能求最小值的索引
pred_rst = train_data_df.iloc[min_idx][\'fruit_name\'] # 必须用整数索引.iloc
return pred_rst
if __name__ == \'__main__\':
data_df = pd.read_csv(data_path)
# 看看数据可视化的大体情况
eda_plot_for_fruit(data_df)
pair_plot(data_df,\'fruit_name\')
# 分成训练集和测试集;random_state相当于设定一个随机数种子。
train_data,test_data = train_test_split(data_df,test_size=0.2, random_state=19)
acc_count = 0
for idx,row in test_data.iterrows():
pred_result = pred_cate(row[feat_cols].values,train_data)
if pred_result == row[\'fruit_name\']:
acc_count += 1
print(\'{}行,预测值是:{},真实值是:{}\'.format(idx, pred_result,row[\'fruit_name\']))
acc_rate = acc_count / test_data.shape[0]
print(\'预测准确率是:{:.2f}%\'.format(acc_rate * 100))