zoukankan      html  css  js  c++  java
  • (转)knn算法简单实例分享

    1 背景

    KNN算法采用测量不同特征值之间的距离方法进来分类,思想类似成语近朱者赤近墨者黑。

    1.1 KNN流程

    最常用的度量距离方法是欧式距离,即计算测试集与待预测数据差值的平方和开方(1)。若多维度数据数值范围差异较大,需要先对所有数据进行标准化(2)或归一化(3)处理.

                                                 d = sqrt{(q_1-p_1)^2+(q_2-p_2)^2+ cdots +(q_n-p_n)^2}                                                         ------(1)

                                                 z = frac{x - mu}{varrho}                                                                                                                                 ------(2)

                                                 X_{norm} = frac {X - X_{min}}{X_{max} - X_{min}}                                                                                                         ------(3)

    计算相关变量的欧式距离,取出距离最小的k个值,离散值取其中所属类最多的作为类别,连续值取k个值得平均值。

    1.2 KNN的优缺点

    (引用自https://blog.csdn.net/wangmumu321/article/details/78576916

    优点

    ① 简单,易于理解,易于实现,无需参数估计,无需训练; 
    ② 对异常值不敏感(个别噪音数据对结果的影响不是很大); 
    ③ 适合对稀有事件进行分类; 
    ④ 适合于多分类问题(multi-modal,对象具有多个类别标签),KNN要比SVM表现要好;

    缺点

    ① 对测试样本分类时的计算量大,内存开销大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本; 
    ② 可解释性差,无法告诉你哪个变量更重要,无法给出决策树那样的规则; 
    ③ K值的选择:最大的缺点是当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进; 
    ④ KNN是一种消极学习方法、懒惰算法。

    2 案例

    2.1 案例背景

    假如我有一套房子打算出租,但不知道市场价格,我就可以根据自己房子的规格(面积、房间数量、厕所数量、容纳人数等),在已有数据集中查找相似(K近邻)规格的房子价格,看别人的相同或相似户型租了多少钱。下图是数据集前10行。

    2.2 分类过程

    已知的数据集中,每个已出租住房都有房间数量、厕所数量、容纳人数等字段,并有对应出租价格。

    将我的房子数据与数据集中每条记录比较计算欧式距离,取出距离最小的5条记录,将其价格取平均值,可以将其看做我的规格房子的市场平均价格。

    过程中有值得注意的点:

    1、最好不要将所有数据全部拿来测试,需要分出训练集和测试集,我的习惯是75%训练&25%测试,具体划分比例按数据集确定;

    2、理想情况下,数据集中每个字段取值范围都相同,但实际上这是几乎不可能的,如果计算时直接用原数数据计算,则会造成较大训练误差,所以需要对各列数据进行标准化或归一化操作,尽量减少不必要的训练误差;

    3、数据集中非数值类型的字段需要转换,替换掉美元$符号和千分位逗号(金额1000以上的数字千分位都有一个逗号,不剔掉不能转换为float类型,这个搞死我了)

    2.3 代码示例

    import pandas as pd
    import numpy as np
    from scipy.spatial import distance#用于计算欧式距离
    from sklearn.preprocessing import StandardScaler#用于对数据进行标准化操作
    from sklearn.neighbors import KNeighborsRegressor#KNN算法
    from sklearn.metrics import mean_squared_error#用于计算均方根误差

    #导入数据并提取目标字段
    path = r'listings.csv'
    file = open(path, encoding = 'gb18030', errors = 'ignore')
    dc_listings = pd.read_csv(file)
    features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']
    dc_listings = dc_listings[features]

    #数据初步清洗
    our_acc_value = 3
    dc_listings['distance'] = np.abs(dc_listings.accommodates - our_acc_value)
    dc_listings = dc_listings.sample(frac=1, random_state=0)
    dc_listings = dc_listings.sort_values('distance')
    dc_listings['price'] = dc_listings.price.str.replace("$|,", "").astype(float)
    dc_listings = dc_listings.dropna()

    #数据标准化
    dc_listings[features] = StandardScaler().fit_transform(dc_listings[features])
    normalized_listings = dc_listings

    #取得训练集和测试集
    norm_train_df = normalized_listings[:2792]
    norm_test_df = normalized_listings[2792:]

    #scipy包distance模块计算欧式距离
    first_listings = normalized_listings.iloc[0][['accommodates', 'bathrooms']]
    fifth_listings = normalized_listings.iloc[20][['accommodates', 'bathrooms']]

    #用python方法做多变量KNN模型
    def predict_price_multivariate(new_listing_value, feature_columns):
    temp_df = norm_train_df
    #distance.cdist计算两个集合的距离
    temp_df['distance'] = distance.cdist(temp_df[feature_columns], [new_listing_value[feature_columns]])
    temp_df = temp_df.sort_values('distance')#temp_df按distance排序
    knn_5 = temp_df.price.iloc[:5]
    predicted_price = knn_5.mean()
    return predicted_price

    cols = ['accommodates', 'bathrooms']
    norm_test_df['predicted_price'] = norm_test_df[cols].apply(predict_price_multivariate, feature_columns=cols, axis=1)
    norm_test_df['squared_error'] = (norm_test_df['predicted_price'] - norm_test_df['price']) ** 2
    mse = norm_test_df['squared_error'].mean()
    rmse = mse ** (1/2)

    print(rmse)

    #利用sklearn完成KNN
    col = ['accommodates', 'bedrooms']
    knn = KNeighborsRegressor()
    #将自变量和因变量放入模型训练,并用测试数据测试
    knn.fit(norm_train_df[cols], norm_train_df['price'])
    two_features_predictions = knn.predict(norm_test_df[cols])

    #计算预测值与实际值的均方根误差
    two_features_mse = mean_squared_error(norm_test_df['price'], two_features_predictions)
    two_features_rmse = two_features_mse ** (1/2)
    print(two_features_rmse)

    原文链接:https://blog.csdn.net/weixin_41897403/article/details/82531129

    Keep moving forwards~
  • 相关阅读:
    BurpSuite—-Spider模块(蜘蛛爬行)
    BurpSuite系列(一)----Proxy模块(代理模块)
    hadoop HA集群搭建步骤
    HBase详解
    MapReduce两种执行环境介绍:本地测试环境,服务器环境
    HBase性能优化方法总结
    HDFS原理解析
    ZooKeeper 典型应用场景
    Redis总结
    基于Apache Curator框架的ZooKeeper使用详解
  • 原文地址:https://www.cnblogs.com/-X-peng/p/14214306.html
Copyright © 2011-2022 走看看