K近邻算法(KNN)K-means聚类算法

news/2024/5/20 9:13:38 标签: 聚类, 算法, kmeans

K近邻算法(KNN)

有监督机器学习

KNN是分类算法

1.思想:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。简单来说就是你离那个样本最近你就属于那个类别。

2.运用欧式距离作为公式

 3.KNN需要做标准归一化处理。

参数n_neighbors=5:取最近的5个值

  # 训练数据
    knn = KNeighborsClassifier(n_neighbors=5)

    # fit, predice, score
    knn.fit(X_train, y_train)
    y_predict = knn.predict(X_test)
    print("预测目标位置为", y_predict)

    # 得出准确率
    print("预测准确率", knn.score(X_test, y_test))

KNN优点:

算法简单,易于实现,无需估计参数,无需训练

KNN存在的问题:

(1)K的取值:

    K的取值小,容易受异常点的影响(K值选择不当则分类精度不能保证)

    K的取值大,容易受K值数量(类别)的波动

(2)性能问题

KNN是所有样本对中心点计算距离,所以时间复杂度高。

KNN在实际场景中运用很少,适合小数据场景,几千几万的样本。

K-means

1.思想:

初始随机给定K(超参数)个簇中心,这K个簇中心是在样本点中随机选择。

按照最邻近原则把待分类的样本点分到各个簇。

划分完成后按平均法重新计算各个簇的质心,从而在确定新的簇心。

一直迭代,直到簇心的移动距离小于某个给定的值。

2.k-means算法评价准则:误差平方和准则,误差平方和达到最优(小)时,可以使类内尽可能紧凑,聚类之间尽可能分开。

loss损失:是一个非凸函数,所以有许多最小值,不一定每次都能落到全局最优,有可能落到局部最优。

k:簇的个数

Ci:某个簇

p:某个簇中的点

mi:是簇Ci的均值

3.k-means是假设不同的簇服从了方差一样,均值不同的高斯分布。

 k-means算法loss损失函数推导

我们直到k-means聚类算法是把样本分成k个聚类,每个聚类服从不同方差的正态分布,所以有最大似然估计将每个聚类中的每个样本的概率进行相乘得到以下公式。

\prod_{i=1}^{k}\prod_{j=1}^{n}N(x_{j}|\mu _{i},\sigma ^{2})

取log相乘变相加

log[\prod_{i=1}^{k}\prod_{j=1}^{n}N(x_{j}|\mu _{i},\sigma ^{2})]

\sum_{i=1}^{k}\sum_{j=1}^{n}N(x_{j}|\mu _{i},\sigma ^{2})

因为k-means是假设数据服从期望是不同的,方差是一样的(定值)的正态分布

所以带入正态分布的概率密度函数,化简求得k-means损失函数

 k-medoids算法

k-means聚类算法的改进

中位数代替均值,防止数据中有异常值导致分类错误

当然如果分类前就通过数据预处理把离群值处理掉,就可以直接使用k-means

K-means在sklearn中的应用

重要参数n_cluster:随着n-cluster越来越大,误差平方和inertia_越来越小

from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

data = load_iris()
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y)

km = KMeans(n_clusters=3, random_state=10)
# km.fit()这一步已经完成聚类了,质心已经求出来了,簇也已经分类好了。
km.fit_transform(X_train, y_train)
# 返回预测结果
print(km.predict(X_test))
# 返回质心坐标
print(km.cluster_centers_)
# 返回总距离的平方和,我们希望他越小越好
print(km.inertia_)

kmeans没有一个固定的评估指标

我们可以通过衡量簇内的差异越小,簇外的差异越大来衡量kmeans效果。

轮廓系数:

a:样本与同一簇中其他点之间的距离之和

b:样本与下一个最近的簇中所有点的距离之和

 轮廓系数范围是(-1,1)其中值越接近于1代表样本与自己所在的簇样本很相似,与其他簇样本不相似。

当样本点与簇外样本点更相似的时候,轮廓系数为负。

当轮廓系数为0时,代表两个簇相似度一直,两个簇本应该是一个簇。

所以簇的轮廓系数高,说明聚类是合适的

簇的轮廓系数小甚至是负值,则说明聚类不合适,超参数k设置太大或者太小。

from sklearn.metrics import silhouette_score
print(silhouette_score(X_train, km.labels_))

K个质心初始化

一个好的质心会让算法计算的更快。

init:可输入k-means++或者random,默认是k-means++使得初始质心彼此远离。

正常情况下k-means++比random迭代次数更少。

如何让迭代停下来(当质心不在移动的时候)

max_inter:最大迭代次数,默认300

tol:默认1e-4,两次Inertia下降的量,如果两次迭代之间Inertia下降的量小于tol所设定的值,迭代就会停下来。


 


http://www.niftyadmin.cn/n/1443267.html

相关文章

hdu 4616 Game(树形dp)

题目链接&#xff1a;hdu 4616 Game 解题思路 dp维护不以trap为起点的最优&#xff0c;ed维护以trap为起点的最优。注意&#xff0c;当前节点如果不为trap的话&#xff0c;不能从dp[K]转移过来。 代码 #include <cstdio> #include <cstring> #include <algo…

ARM汇编伪指令详解

我们做一些操作会有一点麻烦&#xff0c;比方进行一个if then的判断操作。比如要比较a&#xff1e;b&#xff0c;则去调用某个函数&#xff0c;这就要先去比较a,b的值&#xff0c;然后就会跳转&#xff0c;跳转又会比较大小&#xff0c;less than&#xff0c;就是BLLT&#xff…

口令保护(转)

password.asp:提供一个输入界面 <!--- This example is a simple login system ---&gt Password.aspUser Name: Password:      engine.asp:检验用户输入项 Connects and opens the text file    DATA FORMAT IN TEXT FILE "usernamepassword" Set My…

ORACLE关于bin目录下各文件的意义及使用方法(转)

ORACLE关于bin目录下各文件的意义及使用方法,sql,sql教程,Oracle基础$ORACLE_HOME/bin下的utilities解释Binary First Available Description--------- ---------------- ------------------------------------------adapters (7.3.4) Installed Network Adaptersagentctl 9.0.…

hdu 4617 Weapon(几何)

题目链接&#xff1a;hdu 4617 Weapon 解题思路 异面直线之间距离。 代码 #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <vector> #include <algorithm>using namespace std; const double ep…

生成决策树所需要的分裂指标(基尼系数)

1.基尼系数&#xff1a; 最大为1&#xff0c;最小为0。越接近于0代表收入越平等&#xff0c;越接近于1代表收入越悬殊。 那么在决策树分类中&#xff0c;Gini系数越小&#xff0c;数据集合大小越平等&#xff0c;代表集合数据越纯。 我们可以在分类前计算一下Gini系数&#…

动态网站设计十八般武艺——ASP篇(十八)(转)

ASP篇18期&#xff0c;终于又可以同大家见面了&#xff0c;前不久由于工作繁忙&#xff0c;实在无暇继续ASP的写作。为此&#xff0c;很多朋友来信对我进行了“严厉”的批评&#xff0c;并鼓励我继续坚持写作&#xff0c;令我深受鼓舞。从去年我开始ASP篇的写作开始&#xff0c…

输入一个已经按升序排序的数组和一个数字 ,在数组中查找两个数,使得他们的和是输入的那个数字...

package bianchengti; /** 输入一个已经按升序排序的数组和一个数字* 在数组中查找两个数&#xff0c;使得他们的和是输入的那个数字&#xff0c;要求时间复杂度为o(n)* 如果有多对数字的和等于输入的数字&#xff0c;输出任意一对即可。*/ public class findTwoNumber {public…