机器学习,K均值算法笔记(草履虫都能学会),嘎嘎简单

本文详细介绍了K-均值聚类算法,包括其含义、无监督学习的应用、聚类过程(包括初始化聚类中心、大体步骤和优化目标函数),以及如何避免局部最优问题,通过多次运行以求得全局最优解。

机器学习笔记系列

无监督学习

含义

  • 给算法一个数据集,但是不给算法任何其他的信息,例如对错等,让算法自行分组

聚类

  • 目的是自动从给定的数据集中自动分析其特征,并将其自动的分成一个个的簇

K-均值算法

介绍
  • 我们先想好要将整个数据集分为几个簇,若为K个簇,则分配K个聚类中心,将每个聚类中心随机分配一个数值,每个聚类中心的每次迭代都将比较所有样本和自己的距离,将离自己近的样本划分为自己的类别,然后计算自己类别下的所有样本的均值赋值给自己,再更新位置,最终碰到更新不动了,则划分完成,如下列步骤所示

  • image-20211116165355000
  • image-20211116165601227
  • image-20211116165819482
  • image-20211116165918374
  • image-20211116165955366
  • image-20211116170018006
  • 从上示图例可以清楚的看见两个聚类中心所移动的走向及其步骤的

大体步骤
  • 输入:
    • K个值(代表想要分成的簇的个数)
    • 训练集
  • 根据输入的K值随机确定 μ 1 , μ 2 , . . . , μ K ∈ R n \mu_1,\mu_2,...,\mu_K\in\mathbb{R}^n μ1,μ2,...,μKRn个簇
  • 递归(当聚类中心停止移动时跳出循环)
    • for i in range(1, m) m代表样本的个数
      • 计算出每个样本离每个聚类中心之间的距离,然后将其赋值给 c ( i ) c^{(i)} c(i)
      • 例如: c ( 1 ) = 2 c^{(1)}=2 c(1)=2 的意思为第一个样本离2号聚类中心最近,属于2号聚类中心
      • 计算样本与聚类中心的距离公式: ∥ x ( i ) − μ k ∥ 2 \left \| x^{(i)}-\mu_k \right \| ^2 x(i)μk 2
      • 该式可以不加平方,效果也是一样的,但是由于大家的公约都是加平方,所以我们这也加上平方
    • for k in range(1, K)
      • 计算每个聚类中心名下的所有样本的均值赋值给该聚类中心,移动聚类中心的位置
一个问题
  • 若划分完簇后,发现有聚类中心并没有任何样本怎么办,有两个方法
    • 删除该聚类中心(常见做法)
    • 重新随机聚类中心的数值位置,再进行迭代计算
优化目标函数(代价函数)
  • 先定义几个符号
    • c ( i ) c^{(i)} c(i) :第i个样本所属的簇
    • μ k \mu_k μk :第k个簇
    • μ c ( i ) \mu_{c^{(i)}} μc(i) :第i个样本所属的簇的聚类中心
      • 例如,当 c ( 1 ) = 2 c^{(1)}=2 c(1)=2 时代表第一个样本属于2号簇,而 μ c ( 1 ) = μ 2 \mu_{c^{(1)}}=\mu_2 μc(1)=μ2
  • 优化目标函数: J ( c ( 1 ) , . . . , c ( m ) , μ 1 , . . . , μ K ) = 1 m ∑ i = 1 m ∥ x ( i ) − μ c ( i ) ∥ 2 J(c^{(1)},...,c^{(m)},\mu_1,...,\mu_K)=\frac{1}{m}\sum\limits_{i=1}^{m}\left\|x^{(i)}-\mu_{c^{(i)}}\right\|^2 J(c(1),...,c(m),μ1,...,μK)=m1i=1m x(i)μc(i) 2
  • 不难看出,sum后面的就是我们的距离公式,该函数也就是要寻找出能使得该函数最小化的 c ( 1 ) , . . . , c ( m ) , μ 1 , . . . , μ K c^{(1)},...,c^{(m)},\mu_1,...,\mu_K c(1),...,c(m),μ1,...,μK
  • 该函数也叫失真代价函数|K均值算法的失真
初始化聚类中心
  • 在初始化聚类中心之前我们首先需要确定我们的K值,一般情况下,K<m
  • 因为你想想,m是样本个数,K是我们想要将该样本分类的个数,所以K<m
  • 如何随机选择我们的聚类中心呢?
  • 我们可以随机挑选K个样本,然后使我们的K个聚类中心等于这K个样本
  • 也就如图所示
  • image-20211116211920690
  • 可以看到我们随机将我们的两个聚类中心放在了我们的两个样本上
  • 但是我们可以发现一个问题,上图中是刚好将两个聚类中心随机到了两坨样本上
  • 但是如果运气不好的话,就有可能出现如下情况
  • image-20211116212500954
  • 可以看到两个聚类中心在一坨样本当中,这样经过K均值算出的结果肯定和上图是不一样的
  • 那么我们就陷入了局部最优的情况,那么我们怎样得出全局最优呢?
局部最优及全局最优
  • 我们再来举个栗子
  • image-20211116212623051
  • 当我们有一个这样子的样本图,我们假设要将其分成3个簇
  • 那么我们可能得出以下的三种结果
    • 全局最优
      • image-20211116212722736
    • 局部最优
      • image-20211116212959091
  • 这个主要的原因就在于初始化聚类中心不同的点所造成的
  • 所以我们可以尝试多次初始化聚类中心,也就是运行多次K均值算法
  • 一般运行K均值算法的次数为50-1000次
多次运行K均值步骤
  • For i in range(1, 100) 运行100次K均值算法
    1. 随机初始化K均值聚类中心
    2. 运行K均值,获取 c ( 1 ) , . . . , c ( m ) , μ 1 , . . . , μ K c^{(1)},...,c^{(m)},\mu_1,...,\mu_K c(1),...,c(m),μ1,...,μK
    3. 计算代价函数J
  • 经过上述运行后,我们可以得出100种分类该数据集的方法
  • 我们最后从这100种方法中选择出代价函数J最小的那个方法
PS
  • 一般情况下,当我们要分出的簇的个数较小,在10个以下的情况,我们运行多次初始化会有比较明显的效果,而如果K的值较大,例如100个以上,那么可能在第一次随机初始化的时候效果就比较好了,所以在给后续进行随机初始化的时候效果可能不会有很大的改进
  • 一般情况下,当我们要分出的簇的个数较小,在10个以下的情况,我们运行多次初始化会有比较明显的效果,而如果k的值较大,例如100个以上,那么可能在第一次随机初始化的时候效果就比较好了,所以在给后续进行随机初始化的时候效果可能不会有很大的改进

参考链接

  • https://www.bilibili.com/video/BV1FT4y1E74V/?spm_id_from=333.337.search-card.all.click&vd_source=97163a4e6e2704667559fdbd58743862
<think>我们被要求详细解释PHP封装协议,从基础到精通,使用简单易懂的语言。根据引用[1]和[3],我们知道PHP在Web开发中用于处理动态内容,并且经常需要与文件系统或网络资源交互。封装协议(Wrapper)是PHP中一个重要的特性,它允许我们像操作普通文件一样操作各种资源(如HTTP、FTP、压缩文件等)。计划回答结构:1.什么是封装协议?(基础)2.内置的封装协议有哪些?(列举并简要说明)3.如何使用封装协议?(包括示例)4.自定义封装协议(进阶)5.封装协议的应用场景注意:引用中并没有直接提到封装协议,但提到了PHP处理数据、存储和读取,封装协议正是处理这些资源访问的一种机制。我们将按照上述结构进行解释,并尽量使用简单易懂的语言和示例。</think>### PHP封装协议详解:从入门到精通 #### 一、基础概念(什么是封装协议?) 封装协议(Wrapper)是PHP中用于**统一访问不同资源**的抽象层。它允许开发者使用标准文件函数(如`fopen()`, `file_get_contents()`)处理各种资源类型,包括: - 本地文件系统(`file://`) - HTTP/HTTPS网页(`http://`) - FTP服务器(`ftp://`) - 压缩文件(`zip://`) - 数据流(`php://`)等 核心原理:通过**协议前缀**(如`http://`)告诉PHP使用对应的协议处理器解析资源路径,实现**统一操作接口**[^1]。 --- #### 二、常用内置封装协议详解 1. **`file://` (默认协议)** 访问本地文件系统: ```php $content = file_get_contents('file:///var/www/data.txt'); // 等效于(默认省略协议): $content = file_get_contents('/var/www/data.txt'); ``` 2. **`http://` & `https://`** 获取网络资源: ```php $html = file_get_contents('https://www.example.com/api'); // 发送带参数的GET请求: $data = file_get_contents('http://api.com?user=john&page=2'); ``` 3. **`php://` (PHP流协议)** - `php://input`:读取原始POST数据 ```php $rawData = file_get_contents('php://input'); ``` - `php://output`:直接写入输出缓冲 ```php fwrite(fopen('php://output', 'w'), 'Hello World'); ``` - `php://temp`:临时数据存储(内存不足时转存磁盘) ```php $temp = fopen('php://temp', 'r+'); fwrite($temp, 'Temporary data'); ``` 4. **`zip://`** 直接读取压缩包内文件: ```php // 读取 archive.zip 中 config.ini 的内容 $content = file_get_contents('zip://archive.zip#config.ini'); ``` 5. **`data://`** 嵌入Base64或URL编码数据: ```php $img = file_get_contents('data:image/png;base64,iVBORw0KGgo...'); ``` --- #### 三、高级应用:自定义封装协议 通过`stream_wrapper_register()`创建自定义协议处理器: ```php class MyWrapper { public function stream_open($path, $mode, $options, &$opened_path) { // 解析路径并建立连接 $this->position = 0; return true; } public function stream_read($count) { // 返回自定义数据 $data = "Custom data chunk"; $this->position += strlen($data); return $data; } } // 注册 myproto:// 协议 stream_wrapper_register('myproto', 'MyWrapper'); // 使用自定义协议 $data = file_get_contents('myproto://example-data'); ``` **关键方法**: - `stream_open()`:打开资源 - `stream_read()`/`stream_write()`:读写数据 - `stream_close()`:关闭资源 - `stream_seek()`:随机访问 --- #### 四、封装协议的应用场景 1. **统一资源访问** 用相同代码处理本地文件和网络资源: ```php function getContent($path) { return file_get_contents($path); // 自动识别协议 } ``` 2. **安全控制** 通过`allow_url_fopen`和`allow_url_include`配置限制危险协议访问。 3. **数据处理管道** 结合`stream_filter_append()`实现实时数据转换: ```php $stream = fopen('http://example.com/data.csv', 'r'); stream_filter_append($stream, 'convert.iconv.UTF-8/ASCII'); // 字符编码转换 ``` --- #### 五、安全注意事项 1. **禁用危险协议** 在`php.ini`中设置: ```ini allow_url_include = Off // 禁止直接包含远程代码 allow_url_fopen = On // 按需开启网络访问 ``` 2. **验证用户输入路径** 防止路径注入攻击: ```php $userPath = $_GET['path']; if (!preg_match('/^[a-z0-9:\/\.\-]+$/i', $userPath)) { die('Invalid path!'); } ``` > **最佳实践**:优先使用PHP内置协议(如`php://input`),避免直接操作`$_POST`处理二进制数据[^3]。 --- ### 相关问题 1. PHP封装协议与cURL在处理HTTP请求时有何性能差异? 2. 如何通过`php://filter`实现文件内容实时加密? 3. 自定义封装协议时如何实现目录遍历功能? 4. 为什么`allow_url_include`默认关闭?它可能引发哪些安全问题? [^1]: PHP封装协议允许统一访问不同资源类型,简化开发流程。 [^3]: PHP内置协议如`php://input`能安全处理原始数据流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值