python代码实现KNN

python代码实现KNN暴力算法,难点在于循环计算每个预测点、循环计算每个特征数据。以后需要优化。

from sklearn.datasets import load_iris
import pandas as pd
import numpy as np

# print set
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)


def load_data():
    # 导入鸢尾花数据集
    iris = load_iris()
    # 鸢尾花特征数据和类别数据合并
    df_data = pd.DataFrame(iris.data, columns=iris.feature_names)
    df_target = pd.Series(iris.target)
    df_target.name = 'class'
    df_train_ = pd.concat([df_data, df_target], axis=1, sort=False)
    # 创建预测数据
    df_predict_ = pd.DataFrame(np.arange(12).reshape((3, 4)), columns=iris.feature_names)
    return df_train_, df_predict_


# 只判断一行预测数据的类型
def get_max_po_class(df_train, df_predict, k):
    class_dic = {}  # 存放最大可能类别的频率
    distinct = []
    feature_list = df_predict.columns.to_list()  # 预测数据的特征名称
    # 对训练数据的每一行分别计算其与预测数据的欧氏距离
    for row in range(df_train.shape[0]):
        d = 0
        for feature in feature_list:
            d = np.square(abs(df_train.loc[row][feature] - df_predict[feature])) + d
        distinct.append(np.sqrt(d[0]))
    s_distinct = pd.Series(distinct)    # 所有训练数据和预测数据的欧氏距离
    s_distinct.name = 'distinct'
    df_class = pd.concat([df_train['class'], s_distinct], axis=1)   # 合并类别和距离序列
    df_class.sort_values(['distinct'], ascending=True, inplace=True)    # 距离升序排序
    df_class_2 = df_class.head(k)['class'].value_counts()   # 取前k项类别并计数
    max_po_class = df_class_2.idxmax()  # 计数最大的即为预测数据最有可能属于的类别
    class_dic[max_po_class] = df_class_2.max() / k  # 计算最可能类别的频率
    return max_po_class, class_dic


# 主函数,主要是对每个预测数据都进行预测
def main(df_train, df_predict, k):
    for row in range(df_predict.shape[0]):
        max_po_class, class_dic = get_max_po_class(df_train, df_predict, k)
        print(max_po_class)
        print(class_dic)


if __name__=='__main__':
    k = 5   # 近邻数量
    df_train, df_predict = load_data()
    main(df_train, df_predict, k)

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值