机器学习(七)

一,监督学习和无监督学习聚类的数据集比较:

监督学习: 数据集包括输入的数据和与之对应的标签

无监督学习: 数据集仅含有输入的数据,要求算法自己通过所给的数据集来确定决策边界

二,聚类(Clustering):

聚类,即通过给定的数据集,模型自己尝试看看是否可以将其分组为集群

聚类的实现:

K-means(K均值算法):

一种无监督学习,将未标记的数据集划分为K个不同的群集,其核心目标是最小化簇内平方误差和(即实现数据集到集群中心的距离的最小化)

核心步骤:

将群集中心中心随机分配给簇,然后再重复将点分配给群集中心并移动群集中心,直到达到停止条件

实现步骤:

①给群集中心赋点: 首先进行随机猜测,确定集群的中心(如下图中的红蓝叉)

②移动群集中心: 通过所给数据集计算,每个数据更靠近红叉还是蓝叉,通过比较来把数据分配给更近的群集中心(把数据分给群集中心)

③重复上述①②操作,根据已有的数据到群集中心的距离,分别算出平均值,再根据平均值来继续移动群集中心,重复操作知道找到最优的群集中心

K-means的成本函数:

损失函数示意图:

K-means具体实现:

随机生成集群中心,并分别计算其损失函数,不断循环(通常在50-1000次)来找到最小损失函数,实现最优

集群数目的选取:

①Elbow method:(图像法选择K)

通过绘制以集群数目K为X轴,损失函数J为Y轴的函数图像,来找到图像的"Elbow",即函数图像下降最明显的点,负梯度最小的部分,即为最合适的集群数目。

②计算法:(根据实际情况而选择K)

实践中对集群数目的选择大多都是模棱两可的,可以根据实际情况以及自己希望模型后期的表现来选择集群数目

python 复制代码
# -*- coding: gbk -*-  # 改为GBK编码声明(临时解决方案)
# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs  # 用于生成演示数据集

# 生成模拟数据
X, y = make_blobs(
    n_samples=300,  # 样本数量
    centers=4,      # 聚类中心数量
    cluster_std=0.6, # 簇的标准差(控制离散程度)
    random_state=0   # 随机种子(确保结果可复现)
)

class KMeans:
    """K-means聚类算法实现"""
    
    def __init__(self, k=4, max_iter=1000):
        """初始化参数
        Args:
            k: 要形成的簇数(聚类中心数)
            max_iter: 最大迭代次数
        """
        self.k = k
        self.max_iter = max_iter
    
    def fit(self, X):
        """训练方法:寻找数据的最佳聚类中心
        
        Args:
            X: 输入数据矩阵,形状为(n_samples, n_features)
        """
        # 随机选择k个数据点作为初始聚类中心
        self.centers = X[np.random.choice(len(X), self.k, replace=False)]
        
        # 开始迭代优化
        for _ in range(self.max_iter):
            # 步骤1:将每个样本分配到最近的聚类中心(E步)
            labels = self._assign_clusters(X)
            
            # 步骤2:根据分配结果重新计算聚类中心(M步)
            new_centers = self._compute_centers(X, labels)
            
            # 如果聚类中心不再变化,提前终止迭代
            if np.allclose(self.centers, new_centers):
                break
                
            self.centers = new_centers  # 更新聚类中心
        
        return self
    
    def _assign_clusters(self, X):
        """计算每个样本所属的最近聚类中心"""
        # 计算每个样本到所有聚类中心的欧氏距离(未开平方以提升性能)
        distances = np.sum((X[:, np.newaxis] - self.centers) ** 2, axis=2)
        # 返回最近中心的索引(即所属簇的标签)
        return np.argmin(distances, axis=1)
    
    def _compute_centers(self, X, labels):
        """根据当前分配结果重新计算聚类中心"""
        new_centers = np.zeros((self.k, X.shape[1]))
        for i in range(self.k):
            # 获取属于当前簇的所有样本
            cluster_samples = X[labels == i]
            # 计算新的聚类中心(样本均值)
            if len(cluster_samples) > 0:
                new_centers[i] = cluster_samples.mean(axis=0)
            else:
                # 如果出现空簇,保持原中心(避免除零错误)
                new_centers[i] = self.centers[i]
        return new_centers
    
    def predict(self, X):
        """预测新样本的所属簇"""
        return self._assign_clusters(X)

# 实例化并训练模型
model = KMeans(k=4)
model.fit(X)

# 获取预测结果
labels = model.predict(X)

# 可视化结果
plt.figure(figsize=(8,6))

# 绘制所有样本点,按聚类结果着色
plt.scatter(
    X[:, 0], X[:, 1],  # 使用前两个特征作为坐标
    c=labels,           # 按预测标签着色
    cmap='viridis',     # 颜色映射方案
    s=50,              # 点的大小
    edgecolor='k'      # 点边缘颜色
)

# 标注聚类中心
plt.scatter(
    model.centers[:, 0], model.centers[:, 1],
    c='red',           # 中心点颜色
    s=200,             # 点的大小
    alpha=0.7,         # 透明度
    marker='X',        # 标记形状
    edgecolor='k',     # 边缘颜色
    linewidth=2        # 边缘线宽
)

# 添加图表元素
plt.title('K-means Clustering Result')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.grid(True, linestyle='--', alpha=0.6)
plt.show()

三,异常检测(Anomaly Detection):

异常检测,一种无需标签数据的异常检测方法。所输入的大多数数据都是正常的,若再输入异常的数据,则模型会根据异常数据和正常数据在特征空间中的分布不同来判断。

实现:

1.Density:

为特征X的概率建立模型,试图找出最佳特征值(如下图,最里面的椭圆内数据分布最为集中,概率最大,更适合选做为特征;越往外特征X的概率越小,越不适合成为特征)。建立模型后,加以验证集验证,设定阈值,若所预测概率小于阈值,则判定为异常;反之则正常。

2.正态分布:

核心思想与Density一致。基于正态分布的假设,通过所给数据集来计算每个特征的均值和方差,绘制正态分布曲线。设定阈值,利用3σ原则,计算新的数据的方差和均值,来判断其是否异常。比较快速,但是无法处理复杂分布。

3.孤立森林:

基于决策树结构的无监督异常检测。异常数据点通过决策树模型二分类后,异常数据由于在特征空间中分布稀疏,可以通过更少的分割次数被孤立;还可以随机划分特征空间,通过随机选择特征和划分值构建二叉搜索树,异常值的路径长度更短。

算法的建立:
Density Estimation(密度估计):

参数方法:假设数据服从正态分布,通过估计参数的均值,方差来构建概率密度函数。

非参数方法:无需预设分布,直接从数据本身推断分布或者模式。

异常点往往位于数据分布的低概率区域。在训练阶段,利用正常数据来构建概率密度函数;计算新样本的密度值,其值越低异常可能性越高;决策阶段设定阈值,低于阈值的样本则判定为异常。(下图是通过构建多个正态分布,使用多个正态分布的加权和拟合数据来计算样本的加权概率密度)

但是该方法所得模型不够稳定,易受极端值的影响而导致偏差。

异常检测系统的评估:

通过交叉验证的方法来实现参数的调整。

通过正常数据(可以少量异常)进行训练模型,验证集进行调整阈值,测试集评估。如果异常数据太少,可以考虑去掉测试集,只要验证集。但这样无法评估。

异常检测 VS 监督学习:

数据量大小: 异常检测适合只有少量数据集(如0-20正面例子),但反面例子相对较多的情况;监督学习适合数据集量足够大,正面例子和反面例子都充足。

种类多少: 异常检测适合数据集种类多的,未知的异常情况;而监督学习适合已知异常的种类,种类较少的。(即异常检测是通过正常的训练集来判断异常,不正常的数据就算异常;而监督学习则是让模型知道异常数据长什么样,才能判断异常,所以监督学习异常的数据要多些)

举个例子:

异常检测 VS 监督学习在诈骗检测系统中的应用:

异常检测是相信天上掉馅饼是小概率事件,所以判断为诈骗;而监督学习则是见过诈骗的案例,来判断其为诈骗,若没见过,则难以判断。

异常检测特征的选取:

通过特征工程,并实时生成特征的正态分布曲线,通过其是否为标准正太分布来实时调整特征。

相关推荐
NAGNIP3 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab4 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab4 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP7 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年8 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼8 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS8 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区9 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈9 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang10 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx