在python机器学习 | K近邻算法学习(1)一文中,我们介绍了K近邻算法的一些基础知识,包括算法原理、实现流程等。这里基于前一篇,以完整的鸢尾花示例,介绍K近邻算法在分类和回归上的应用。
K近邻算法分类和回归应用
1 K近邻算法的分类应用
这里以鸢尾花数据为示例,步骤为:
- 获取数据
- 数据基本处理
- 特征工程
- 机器学习(模型训练)
- 模型评估
"""导入模块"""
# 加载数据
from sklearn.datasets import load_iris
# 数据分割
from sklearn.model_selection import train_test_split
#交叉验证和网格搜索
from sklearn.model_selection import GridSearchCV
#数据标准化
from sklearn.preprocessing import StandardScaler
#分类器模型
from sklearn.neighbors import KNeighborsClassifier
#获取数据集
iris = load_iris()
#数据处理和数据分割
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2)
#特征工程标准化
##实例化
transfer = StandardScaler()
##训练集和测试集标准化
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 建立模型
knn = KNeighborsClassifier(n_neighbors=7)
#建立模型和交叉验证和网格化搜索
params_grid = {"n_neighbors":[1,3,5,7,9]}
knn = GridSearchCV(knn,param_grid=params_grid,cv=3)
#训练
knn.fit(x_train,y_train)
#模型评估
##样本数据 进行预测
y_pre = knn.predict(x_test)
print("预测值:",y_pre)
print("实际值:",y_test)
## 输出准确率
ret = knn.score(x_test,y_test)
print("准确率为:",ret)
print("最好的模型:",knn.best_estimator_)
print("最好的结果:",knn.best_score_)
print("最好的cv:",knn.cv_results_)
2 K近邻算法的回归应用
- K近邻算法除了应用于分类,还可以用于回归,原理也是基于距离得出预测值
- 模块为:from sklearn.neighbors import KNeighborsRegressor
2.1 K近邻算法的回归原理
下面预测一个房间的价格来介绍 K近邻算法的回归原理
问题:假如我有一个1室的房子,可以租多少钱?
现有数据:有一个不同房子架构的数据
实现方法:通过已有的房子价格(1室的房子价格)数据的均值,推测出这间房子的价格,如图
"""
获取数据:
accommodates:可以容纳的旅客
bedrooms:卧室的数量
bathrooms:厕所的数量
beds:床的数量
price:每晚的费用
minimum_nights:客人最少租了几天
maximum_nights:客人最多租了几天
number_of_reviews:评论的数量
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
features = ['accommodates','bedrooms','bathrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews']
air_df = pd.read_csv("listings.csv",usecols=features)
air_df.info()
air_df.head()
"""
距离的定义:确定 训练数据的房间数量 与 我的测试数据的房间数量相近?-->做差
"""
# 初始化我的房间个数
our_acc_value = 1
# 将训练集中的bedrooms 与 我的个数 求差
air_df["distance"] = np.abs(air_df.bedrooms - our_acc_value)
air_df.head()
# 差异 0 1 2 ... n 的分别统计个数
air_df.distance.value_counts()
"""
从以上数据得出:
与我房间个数一致的:2533
2个房间:903
...
"""
"""
随机获取k个临近的样本价格
DataFrame使用pd.sample()随机选取N行数据:https://blog.csdn.net/gaolijing_/article/details/104771080
"""
# 随机 洗牌 air_df.sample 洗牌 默认随机取一个 frac=1,抽取100%样本,只是 洗牌 Return a random sample of items from an axis of object.
dis_df = air_df.sample(frac=1)
# 按照差异列进行排序
dis_df = dis_df.sort_values("distance")
# 获取价格列
dis_df["price"].head()
# 求k个样本的平均价格
##用正则表达式提取数字
air_df["price"] = air_df["price"].str.replace("\$|,","").astype("float")
#预测一间房间的价格
mean_price = air_df["price"].iloc[:5].mean() # 均值
mean_price
需要注意的是,我们这里只是通过同类1间房子拥有的房间数量推测假如我拥有1间1室的房子的价值。但事实1间1室的房子存在其他很多质量的差异,例如向阳与否,独卫与否等等。所以,这种预测是粗糙的,但是比较更多特征也是同理求差异求距离求均值。
了解了原理之后,我们进行数据分割,分为训练集和预测集,看看效果:
"""
# 分为训练集 测试集
# 训练集 在训练模型
# 将测试数据中 房间个数 都 传递到 一个模型里面 去预测价格
"""
# 删除 distance 列
air_df2 = air_df.drop("distance",axis=1)
# 3723*0.75 将样本分为75%的训练集,25%的预测集
train_df = air_df2.iloc[:2792].dropna()
test_df = air_df2.iloc[2792:].dropna()
# 预测函数的编写
# bedroomds_x:test_df中每行房间个数
# feature_column:bedrooms字符串
def predict_price(bedroomds_x,feature_column):
# 训练集训练
temp_df = train_df
# 求训练集 与 测试集 差异列
temp_df["distance"] = np.abs(air_df[feature_column] - bedroomds_x)
# 给差异列 排序
temp_df = temp_df.sort_values("distance")
# 取5个
knn_5 = temp_df["price"].iloc[:5]
# 求均值
predict_price = knn_5.mean()
return predict_price
# 将 series 中 的每一行 映射到 函数中 去做预测
test_df["predict_price"] = test_df.bedrooms.apply(predict_price,feature_column="bedrooms")
test_df
模型评估:使用RMSE,
test_df["squared_error"] = (test_df["predict_price"] - test_df["price"])**2
mse = test_df["squared_error"].mean()
np.sqrt(mse)
2.2 K近邻算法的回归实现
# 导入模块
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
# 构建 训练特征列标签
cols = ["accommodates","bedrooms"]
# 构建模型
re_knn = KNeighborsRegressor()
# 训练 训练特征 训练目标
re_knn.fit(train_df[cols],train_df["price"])
# 预测
predict_price = re_knn.predict(test_df[cols])
predict_price
# 模型评估
mse = mean_squared_error(test_df["price"],predict_price)
np.sqrt(mse)