手工实现水果分类器
手工实现水果分类器,没用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))