初识机器学习

k近邻算法

距离度量
常见的距离公式:

欧氏距离:两点之间的距离  => sqrt[ (x1 - x2)^2  + y1 - y2)^2 +…… ]

曼哈顿距离:=> |x1 - x2| + |y1 - y2| + ……

切比雪夫距离:=> max( |x1 - x2| , |y1 - y2| )

闵氏距离

闵氏距离缺点:将各个分量的单位相同看待了;未考虑各个分量的分布(期望、方差等)可能是不同的

其他距离公式:标准化距离公式、余弦距离……

离散属性距离计算:

若存在序关系(身高:高,中,矮),可转化为连续值(1,0.5,0)

若不存在序关系(男,女),可转化为向量的形式((1,0)  (0,1))

K值选择

k过小:容易受到异常点的影响

k过大:受到样本的均衡问题

实际应用中,k值一般取一个比较小的数值,采用交叉验证法找合适的k值(把训练数据分为训练集和验证集)

近似误差:对现有训练集的训练误差(过小可能会导致过拟合,对现有训练集有很好的预测,对未知测试样本会出现较大的偏差)

估计误差:对测试集的测试误差(估计误差小说明对未知数据的预测能力好)

原理

(如果数据集特别大,要找到距离最近的那个数据太难了,brute复杂度O(n),怎么解决?)

大概思想

为了避免每次都重新计算一次距离,算法会把距离保存在一颗树里,在计算之前从树里查询距离信息。(如果A和B距离很远,B和C距离很近,那么就认为A和C的距离也很远,在合适的时候跳过距离远的点)

构建原理

构造过程:数据集中取一个中间数,把数据分成两部分,然后在两部分中再分别取一个中间数……

分割的那条线叫做分割超平面

kd_tree:先构造根节点、然后通过递归的方法,不断地对k维空间进行切分,生成子节点、直到子区域内没有实例时终止

(在数据比较分散的那一维度进行划分比较好)

(一般选择中位数进行划分)

最近邻域搜索

ball tree:测试点根据树往下找,把途径的节点放到search_path数组(或栈)中,找到一个最相似的点,计算距离r;然后向上回溯,以测试点为圆心,r为半径做圆,观察是否与该回溯点的分割超平面相交,如果没有相交,就不必跳到该回溯点的另一侧搜索了,因为该回溯点的另一侧不会有更小的距离了;然后接着回溯,接着看是否相交;不相交就不再另一侧搜索,相交的话就在另一侧搜索(把另一侧的点放到search_path数组(或栈)中,沿着数组(或栈)回溯 ),看看有没有距离更小的点;最终回溯到search_path数组(或栈)为空(回溯一次,就pop一次),就知道测试点距离哪个点最近了

案例分析 

给一个二维数据集:T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}

第一个维度:2,5,9,4,8,7(方差更大,更分散)

中位数:6(5和7都接近中位数6,这次选7)

第二个维度:3,4,6,7,1,2

第一次分完之后:A:{(2,3),(4,7),(5,4)},B: {(8,1),(9,6)}

然后用y轴划分

然后开始搜索

 

这样就行了(这个样例比较简单,没有超过分割超平面) 

来个难一点的测试点

 

 小案例

鸢尾花种类预测

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier


# 设置字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

iris = load_iris()

x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)

# 标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 机器学习  使用估计器进行模型训练
estimator = KNeighborsClassifier(n_neighbors=9)   # auto
estimator.fit(x_train,y_train)

# 模型评估
y_predict = estimator.predict(x_test)
print("预测结果为\n",y_predict)
print("比对真实值和预测值\n",y_predict==y_test)

score = estimator.score(x_test,y_test)
print("准确率为\n",score)
总结

k近邻算法

简单有效,适合类域交叉样本(属性重叠多),适合大样本自动分类

lazy learning效率低,计算量大,输出可解释性不强,对不均衡的样本不擅长

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值