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~
  • 相关阅读:
    升级windows 11小工具
    windows 10更新升级方法
    您需要了解的有关 Oracle 数据库修补的所有信息
    Step by Step Apply Rolling PSU Patch In Oracle Database 12c RAC Environment
    Upgrade Oracle Database Manually from 12.2.0.1 to 19c
    如何应用版本更新 12.2.0.1.210420(补丁 32507738 – 2021 年 4 月 RU)
    xtrabackup 安装、备份和恢复
    Centos_Lvm expand capacity without restarting CentOS
    Centos_Lvm_Create pv vg lv and mount
    通过全备+relaylog同步恢复被drop的库或表
  • 原文地址:https://www.cnblogs.com/-X-peng/p/14214306.html
Copyright © 2011-2022 走看看