python-socketio 文档翻译

Python018

python-socketio 文档翻译,第1张

教程: https://tutorialedge.net/python/python-socket-io-tutorial/

python-socketio 原文地址 ,在google浏览器中可以翻译为中文去使用。

首先要搞明白几个问题:

说明

1)第一种room是每一个单独的客户端都有的。(通过 session ID 可以找到)

2)第二种是应用程序自己创建的。

在下面这个方法中,如果省略掉room参数,将会自动发送给所有的连接了的客户端。

译文:

Python-socketio实现了一个Python Socket.IO 服务,这个服务可以单独运行也可以综合于一个web项目中。下面是一些它的特征:

什么是Socket.IO?

Socket.IO是一个基于事件的双向通讯的传输协议(一般是web浏览器),和一个服务端。原始的客户端和服务端组件实现是通过JavaScript写的。

入门指南

可以使用 pip 安装Socket.IO:

下面是一个使用 aiohttp 框架(只支持Python 3.5+)实现异步IO的 Socket.IO server 简单的例子:

下面是一个类似的例子,但是使用的Flask和Eventlet的例子,兼容Python2.7和3.3+:

客户端应用必须引入 socket.io-client 库(1.3.5版本以及以上,越高越好)。

每次客户端连接到服务器的连接事件处理程序调用sid(会话ID)分配给连接和WSGI环境字典。

每次客户端连接到服务端的 conenct 事件都是由sid(session ID)分配到连接和WSGI环境字典调用的。服务端可以检查身份认证或者其他的头部信息去决定是否这个客户端允许被连接。要想拒绝一个客户端的连接,这个处理器必须返回 False 。

当客户端发送发送一个事件给服务端,相应的事件处理器会被 sid 和这个信息调用,可以是单个或者多个参数。这个应用可以定义尽量多的如果被需要的可以被事件处理器关联的事件。一个事件可以通过一个名称简单定义。

当一个客户端连接中断了, disconnect 事件就被调用,允许应用去执行清理工作。

服务端

Socket.IO 服务端是 socketio.Server 类的实例,他们可以被一个WSGI适用应用程序使用 socketio.Middleware 去合并:

使用 socketio.Server.on() 方法来注册服务端的事件处理器:

对于异步服务端来说,事件处理器可以是常规方法,或者是协程:

聊天室

因为Socket.IO是一个双向的协议,服务端可以在任意时间发送消息给任意的连接到的客户端。为了让它方便去将客户端定位到组中,应用程序可以将客户端放入到聊天室中去,然后将消息定位到整个聊天室中。

当客户端第一次连接,他们是被分配到他们自己的聊天室中,这个聊天是是以session ID(sid 参数会传递给所有的事件处理器)命名的。应用可以通过 socketio.Server.enter_room() 和 socketio.Server.leave_room() 自由地去创建聊天室和管理客户端。客户端可以在尽量多的房间里,也可以根据需求尽量频繁地被拉入拉出聊天室。当他们的连接不在特别的时候,单独的聊天室将会分配给她它们,应用程序可以自由地增加和移除客户端从聊天室中,尽管它只要这样做就会失去定位独立客户端的能力。

socketio.Server.emit() 方法会获得一个事件名称,一个可能是 str , bytes , list , dict 或者 tuple 类型的消息载体。当发送一个 tuple ,在其中的元素必须是上面的其他类型。元组中的元素将会被传递给客户端的回调函数为多个参数。定位一个个人客户端,客户端的 sid 将会被给一个聊天室(假设这个应用没有修改这些初始的聊天室)。定位所有的连接的客户端们,这个聊天室参数将会被触发。

通常在聊天室中当广播一个消息到一个用户组的时候,发送者是否接受他自己的消息是可选的。 soicketio.Server.emit() 方法提供了一个可选的 skip_sid 参数去指定一个想在广播中跳过的客户端。

Response

当一个客户端发送一个事件给服务端,它可以选择提供一个回调方法,当服务端返回一个响应的时候会被触发。服务端可以便捷地从相应的事件处理器返回它从而提供一个响应。

事件处理器可以返回一个单独的值,一个带多个值的元组。这个在客户端的回调函数将会调用这些返回的值。

Callbacks

回调

服务端可以请求一个响应通过发送一个事件给客户端。 socketio.Server.emit() 方法有一个可选的 callback 参数能够被设置为可回调的。当这个参数被传递之后,当客户端返回相应的时候,这个可回调的方法将会被请求。

当广播给多个客户端的时候使用回调函数是不被推荐的,因为回调方法将会被只执行一次。

Namespace

命名空间

Socket.IO 协议支持多个逻辑性连接,所有的多路复用都是在相同的物理连接上。客户端可以通过给每个连接指定不同的 namespace 从而开多个连接。一个命名空间是由 主机名+端口+路径名称构成的。比如,连接到 http://example.com:8000/chat 将会开一个连接到命名空间 /chat 。

由于分离的不同的session ID( sid s),不同的事件处理器,不同的聊天室,每一个命名空间都是独立的。应用程序使用多个命名空间从而来区分命名空间,是非常重要的。可以参考 socketio.Server 类。

当 namespace 参数被触发了,比如设置为 None 或者 / , 那么一个默认的命名空间将会被使用。

Class-Based Namespaces

作为一个基于装饰器的事件处理器的代替,这个属于一个命名空间事件处理器可以被创建为 socketio.Namesapce 的子类:

对于基于异步io的服务端,域名空间必须继承与 socketio.AsyncNamespace , 也可以定义普通的方法或者协程作为事件处理器:

当使用基于类的命名空间的时候,任何被服务端接受的事件将会被分派到一个被事件名称命名的方法中作为方法名称(with the on_pfrefix )。比如:事件 my_event 将会被一个名叫 on_my_event 的方法处理。

本文翻译自 https://jakevdp.github.io/PythonDataScienceHandbook/05.12-gaussian-mixtures.html

上一节中探讨的k-means聚类模型简单易懂,但其简单性导致其应用中存在实际挑战。具体而言,k-means的非概率特性及简单地计算点与类蔟中心的欧式距离来判定归属,会导致其在许多真实的场景中性能较差。本节,我们将探讨高斯混合模型(GMMs),其可以看成k-means的延伸,更可以看成一个强有力的估计工具,而不仅仅是聚类。

我们将以一个标准的import开始

我们看下k-means的缺陷,思考下如何提高聚类模型。正如上一节所示,给定简单,易于分类的数据,k-means能找到合适的聚类结果。

举例而言,假设我们有些简单的数据点,k-means算法能以某种方式很快地将它们聚类,跟我们肉眼分辨的结果很接近:

从直观的角度来看,我可能期望聚类分配时,某些点比其他的更确定:举例而言,中间两个聚类之间似乎存在非常轻微的重叠,这样我们可能对这些数据点的分配没有完全的信心。不幸的是,k-means模型没有聚类分配的概率或不确定性的内在度量(尽管可能使用bootstrap 的方式来估计这种不确定性)。为此,我们必须考虑泛化这种模型。

k-means模型的一种理解思路是,它在每个类蔟的中心放置了一个圈(或者,更高维度超球面),其半径由聚类中最远的点确定。该半径充当训练集中聚类分配的一个硬截断:任何圈外的数据点不被视为该类的成员。我们可以使用以下函数可视化这个聚类模型:

观察k-means的一个重要发现,这些聚类模式必须是圆形的。k-means没有内置的方法来计算椭圆形或椭圆形的簇。因此,举例而言,假设我们将相同的数据点作变换,这种聚类分配方式最终变得混乱:

高斯混合模型(GMM)试图找到一个多维高斯概率分布的混合,以模拟任何输入数据集。在最简单的情况下,GMM可用于以与k-means相同的方式聚类。

但因为GMM包含概率模型,因此可以找到聚类分配的概率方式 - 在Scikit-Learn中,通过调用predict_proba方法实现。它将返回一个大小为[n_samples, n_clusters]的矩阵,用于衡量每个点属于给定类别的概率:

我们可以可视化这种不确定性,比如每个点的大小与预测的确定性成比例;如下图,我们可以看到正是群集之间边界处的点反映了群集分配的不确定性:

本质上说,高斯混合模型与k-means非常相似:它使用期望-最大化的方式,定性地执行以下操作:

有了这个,我们可以看看四成分的GMM为我们的初始数据提供了什么:

同样,我们可以使用GMM方法来拟合我们的拉伸数据集;允许full的协方差,该模型甚至可以适应非常椭圆形,伸展的聚类模式:

这清楚地表明GMM解决了以前遇到的k-means的两个主要实际问题。

如果看了之前拟合的细节,你将看到covariance_type选项在每个中都设置不同。该超参数控制每个类簇的形状的自由度;对于任意给定的问题,必须仔细设置。默认值为covariance_type =“diag”,这意味着可以独立设置沿每个维度的类蔟大小,并将得到的椭圆约束为与轴对齐。一个稍微简单和快速的模型是covariance_type =“spherical”,它约束了类簇的形状,使得所有维度都相等。尽管它并不完全等效,其产生的聚类将具有与k均值相似的特征。更复杂且计算量更大的模型(特别是随着维数的增长)是使用covariance_type =“full”,这允许将每个簇建模为具有任意方向的椭圆。

对于一个类蔟,下图我们可以看到这三个选项的可视化表示:

尽管GMM通常被归类为聚类算法,但从根本上说它是一种密度估算算法。也就是说,GMM适合某些数据的结果在技术上不是聚类模型,而是描述数据分布的生成概率模型。

例如,考虑一下Scikit-Learn的make_moons函数生成的一些数据:

如果我们尝试用视为聚类模型的双成分的GMM模拟数据,则结果不是特别有用:

但是如果我们使用更多成分的GMM模型,并忽视聚类的类别,我们会发现更接近输入数据的拟合:

这里,16个高斯分布的混合不是为了找到分离的数据簇,而是为了对输入数据的整体分布进行建模。这是分布的一个生成模型,这意味着GMM为我们提供了生成与我们的输入类似分布的新随机数据的方法。例如,以下是从这个16分量GMM拟合到我们原始数据的400个新点:

GMM非常方便,可以灵活地建模任意多维数据分布。

GMM是一种生成模型这一事实为我们提供了一种确定给定数据集的最佳组件数的自然方法。生成模型本质上是数据集的概率分布,因此我们可以简单地评估模型下数据的可能性,使用交叉验证来避免过度拟合。校正过度拟合的另一种方法是使用一些分析标准来调整模型可能性,例如 Akaike information criterion (AIC) 或 Bayesian information criterion (BIC) 。Scikit-Learn的GMM估计器实际上包含计算这两者的内置方法,因此在这种方法上操作非常容易。

让我们看看在moon数据集中,使用AIC和BIC函数确定GMM组件数量:

最佳的聚类数目是使得AIC或BIC最小化的值,具体取决于我们希望使用的近似值。 AIC告诉我们,我们上面选择的16个组件可能太多了:大约8-12个组件可能是更好的选择。与此类问题一样,BIC建议使用更简单的模型。

注意重点:这个组件数量的选择衡量GMM作为密度估算器的效果,而不是它作为聚类算法的效果。我鼓励您将GMM主要视为密度估算器,并且只有在简单数据集中保证时才将其用于聚类。

我们刚刚看到了一个使用GMM作为数据生成模型的简单示例,以便根据输入数据定义的分布创建新样本。在这里,我们将运行这个想法,并从我们以前使用过的标准数字语料库中生成新的手写数字。

首先,让我们使用Scikit-Learn的数据工具加载数字数据:

接下来让我们绘制前100个,以准确回忆我们正在看的内容:

我们有64个维度的近1,800位数字,我们可以在这些位置上构建GMM以产生更多。 GMM可能难以在如此高维空间中收敛,因此我们将从数据上的可逆维数减少算法开始。在这里,我们将使用一个简单的PCA,要求它保留99%的预测数据方差:

结果是41个维度,减少了近1/3,几乎没有信息丢失。根据这些预测数据,让我们使用AIC来计算我们应该使用的GMM组件的数量:

似乎大约110个components最小化了AIC;我们将使用这个模型。我们迅速将其与数据拟合并确保它已收敛合:

现在我们可以使用GMM作为生成模型在这个41维投影空间内绘制100个新点的样本:

最后,我们可以使用PCA对象的逆变换来构造新的数字:

大部分结果看起来像数据集中合理的数字!

考虑一下我们在这里做了什么:给定一个手写数字的样本,我们已经模拟了数据的分布,这样我们就可以从数据中生成全新的数字样本:这些是“手写数字”,不是单独的出现在原始数据集中,而是捕获混合模型建模的输入数据的一般特征。这种数字生成模型可以证明作为贝叶斯生成分类器的一个组成部分非常有用,我们将在下一节中看到。

python是一门动态解释性语言不像c语言一样还有编译器,动态语言都是对应一个解释器,python的解释器有很多版本,其中用得最多最广泛的是cpython,大家一提python基本就是值得喜欢个版本,目前cpython已经更新到3.9版本,希望可以帮到你