2024年1月

与往年一样,2023 年的 InfoWorld 最佳开源软件奖评选了诸多令人惊叹且不拘一格的开源项目。在这25个获奖项目中,您会了解到和编程语言、运行时、应用程序框架、数据库、分析引擎、机器学习库、大型语言模型 (LLM) 有关的工具,以及至少一两个超出预期的项目。

Apache Hudi

在构建开放数据湖或湖仓一体时,许多行业都需要一个更可发展和可变化的平台。以出版商、广告商和媒体买家的广告平台为例——仅有快速分析是不够的。Apache Hudi 不仅提供了快速的数据格式、表格和 SQL,还使它们能够进行低延迟的实时分析。它是与 Apache Spark、Apache Flink 以及 Presto、StarRocks(见下文)和 Amazon Athena 等工具集成。简而言之,如果您想在数据湖上进行实时分析,Hudi 是一个非常不错的选择。

详情请见:
https://github.com/apache/hudi

Apache Iceberg

事实上,如果结果需要花费很长时间,开发人员一般不会在乎 “扩展性能” 是否好。而Apache Iceberg 却兼备这两个优势。不仅能与 Hive 兼容,还能直接与 Apache Spark 和 Apache Flink 以及 ClickHouse、Dremio 和 StarRocks 等其他系统协同工作。Iceberg 可为所有这些系统提供高性能的表格式,同时支持完整的模式演进、数据压缩和版本回滚。它或许能成为许多现代开放数据湖的关键组成部分。

详情请见:
https://github.com/apache/iceberg

Apache Superset

多年来,Apache Superset 一直是数据可视化领域的标杆。对于想要大规模部署自助服务、面向客户或面向用户的分析工具的人来说,Superset 似乎是唯一的选择。Superset 几乎可以为任何分析场景提供可视化功能,包括从饼状图到复杂的地理空间图表。它可与大多数 SQL 数据库对话,并提供拖放生成器和 SQL IDE。如果您要对数据进行可视化,Superset 值得您一试。

详情请见:
https://github.com/apache/superset

Bun

就在开发人员普遍认为 JavaScript 即将进入可预测的常规工作时,Bun 出现了。这个轻佻的名字掩盖了它严肃的目标:将服务器端 JS--运行时、捆绑程序、包管理器——所需的一切都集成到一个工具中。让它成为 Node.js 和 NPM 的直接替代品,但速度要快得多。这一简单的主张似乎让 Bun 成为了自 Node 推翻苹果购物车以来最具颠覆性的 JavaScript 工具。

Bun 的速度部分归功于 Zig(见下文),其余则归功于创始人 Jared Sumner 对性能的执着追求。您可以在命令行上立即感受到它的与众不同。除了性能之外,将所有工具集成在一个数据包中,也让 Bun 成为 Node 和 Deno 的有力替代品。

详情请见:
https://github.com/oven-sh/bun

Claude 2

Anthropic 的 Claude 2 在单个提示中最多可接受 10 万个标记(约 7 万字),并可生成多达数千个标记的故事。它可以编辑、改写、总结、分类、提取结构化数据、根据内容进行问答等。虽然它在英语方面的训练最多,但在其他一系列常用语言方面也表现出色。Claude 还掌握了大量常用编程语言的知识。

Claude 从一开始就被训练的乐于助人、诚实、无害(HHH),并经过广泛的重新训练,变得更难产生攻击性或危险的输出。它不会根据您的数据进行训练,也不会在互联网上查询答案。美国和英国的用户可以免费下载 Claude 测试版,Jasper、Sourcegraph 和 AWS 等商业合作伙伴也已采用。

详情请见:
https://claude.ai/

CockroachDB

CockroachDB 是一个分布式 SQL 数据库,可实现强一致性 ACID 事务,通过实现数据库读写的水平可扩展性,为高性能、事务繁重的应用程序解决了一个关键的可扩展性问题。CockroachDB 还支持多区域和多云部署,以减少延迟并遵守数据法规。部署实例包括 Netflix 的数据平台,该平台有 100 多个 CockroachDB 生产集群,支持媒体应用和设备管理。主要客户还包括 Hard Rock Sportsbook、JPMorgan Chase、 Santander 和 DoorDash。

详情请见:
https://github.com/cockroachdb/cockroach

CPython

机器学习、数据科学、任务自动化、网络开发......都是 Python 编程语言具备的优势。但运行时性能却不是其中之一,不过这种情况正在改变。在 Python 3.11 和 Python 3.12 这两个版本中,Python 核心开发团队对 Python 解释器的参考实现 CPython 进行了一系列变革性升级。其结果是,Python 运行时对所有人来说都更快了,而不仅仅是那些选择使用新库或前沿语法的少数人。Global Interpreter Lock 是阻碍 Python 真正实现多线程并行的一个长期障碍。

详情请见:
https://github.com/python/cpython

DuckDB

OLAP 数据库很庞大,因为没有人会把 IBM Cognos、Oracle OLAP、SAP Business Warehouse 或 ClickHouse 描述为 "轻量级"。但是,如果您需要的只是足够的 OLAP--一个嵌入式、进程内运行、无外部依赖的分析数据库呢?DuckDB 作为一种分析数据库,它秉承了 SQLite 等小型但功能强大的项目的精神。DuckDB 提供所有熟悉的 RDBMS 功能——SQL 查询、ACID 事务、二级索引--但增加了分析功能,如大型数据集的连接和聚合。它还可以摄取和直接查询常见的大数据格式,如 Parquet。

详情请见:
https://github.com/duckdb/duckdb

HTMX 和 Hyperscript

HTMX 采用了开发人员们熟悉和喜爱的 HTML,并通过增强功能对其进行了扩展,使编写现代网络应用程序变得更加容易。HTMX 消除了用于连接网络前端和后端的大量模板 JavaScript。并且,它使用直观的 HTML 属性来执行任务,如发出 AJAX 请求和用数据填充元素。同类项目 Hyperscript 引入了类似于 HyperCard 的语法,简化了许多 JavaScript 任务,包括异步操作和 DOM 操作。总之,HTMX 和 Hyperscript 为当前的反应式框架趋势提供了一个大胆的替代方案。

详情请见:
https://github.com/bigskysoftware/htmx

https://github.com/hyperhype/hyperscript

Istio

Istio 是一个服务网格,可为基于容器的微服务简化网络和通信,提供流量路由、监控、日志记录和可观察性,同时通过加密、验证和授权功能增强安全性。Istio 将通信及其安全功能与应用程序和基础架构分离开来,从而实现了更安全、更一致的配置。该架构由部署在 Kubernetes 集群中的控制平面和用于控制通信策略的数据平面组成。2023年,Istio 从 CNCF 孵化项目中毕业,在云原生社区中获得了显著的发展,包括谷歌、IBM、红帽、Solo.io 等公司的支持和贡献。

详情请见:
https://github.com/istio/istio

Kata Containers

Kata Containers 结合了容器的速度和虚拟机的隔离性,是一种安全的容器运行时,它使用英特尔 Clear Containers 和 Hyper.sh runV(一种基于管理程序的运行环境)。Kata Containers 可与 Kubernetes 和 Docker 协同工作,同时支持多种硬件架构,包括 x86_64、AMD64、Arm、IBM p 系列和 IBM z 系列。谷歌云、微软、AWS 和阿里巴巴云是基础设施赞助商。其他支持 Kata Containers 的公司包括 Cisco, Dell, Intel, Red Hat, SUSE, and Ubuntu。最近发布的版本为 GPU 设备和抽象设备管理带来了保密容器。

详情请见:
https://github.com/kata-containers/kata-containers

LangChain

LangChain 是一个模块化框架,可简化由语言模型驱动的应用程序的开发。LangChain 使语言模型能够连接到数据源,并与其环境进行交互。LangChain 组件是模块化抽象和抽象实现的集合。LangChain 现成的链是组件的结构化组合,用于完成特定的高级任务。您可以使用组件定制现有的链,也可以构建新的链。LangChain 目前有三个版本:一个是 Python 版本,一个是 TypeScript/JavaScript 版本,还有一个是 Go 版本。截至目前,已有大约 160 个 LangChain 集成。

详情请见:
https://github.com/langchain-ai/langchain

语言模型评估 Harness

当一个新的大型语言模型(LLM)发布时,您通常会看到一组评估分数,将该模型与 ChatGPT 在某个基准上进行比较。更有可能的是,该模型背后的公司会使用 lm-eval-harness 来生成这些分数。lm-eval-harness 由分布式人工智能研究所 EleutherAI 创建,包含 200 多个基准,而且很容易扩展。该工具甚至被用来发现现有基准中的不足,以及为 Hugging Face 的开放式 LLM 排行榜提供支持。

详情请见:
https://github.com/EleutherAI/lm-evaluation-harness

Llama 2

Llama 2 是 Meta AI 的下一代大型语言模型,与 Llama 1 相比,其训练数据量增加了 40%(2 万亿个来自公开来源的词库),上下文长度增加了一倍(4096)。Llama 2 是一个自动回归语言模型,使用优化的转换器架构。调整后的版本使用了监督微调(SFT)和人类反馈强化学习(RLHF),以符合人类对有用性和安全性的偏好。Code Llama 是通过在代码特定数据集上对 Llama 2 进行微调而训练出来的,它可以根据代码或自然语言提示生成代码和有关代码的自然语言。

详情请见:
https://github.com/facebookresearch/llama

Ollama

Ollama 是一款命令行工具,可在 macOS 和 Linux 上本地运行 Llama 2、Code Llama 和其他模型,并计划支持 Windows。Ollama 目前支持近二十多个语言模型系列,每个模型系列都有许多 "标签"。标签是模型的变体,这些模型使用不同的微调方法以不同的规模进行训练,并以不同的级别进行量化,以便在本地良好运行。量化级别越高,模型越精确,但运行速度越慢,所需的内存也越大。

Ollama 支持的模型包括一些未删减的变体。这些模型是使用埃里克-哈特福德(Eric Hartford)设计的一种程序建立的,可以在不使用通常的防护措施的情况下训练模型。例如,如果您问 Llama 2 如何制造火药,它会警告您制造火药是非法和危险的。如果您问未经审查的 Llama 2 模型同样的问题,它会直接告诉您。

详情请见:
https://github.com/jmorganca/ollama

Polars

既然我们已经有了著名的 Pandas,为什么 Python 还需要另一个数据框架重组库呢?但深入了解一下,您会发现 Polars 正是您要找的。Polars 做不了 Pandas 能做的所有事情,但它能做的事情都能以极快的速度完成——比 Pandas 快 10 倍,使用的内存只有 Pandas 的一半。来自 PySpark 的开发人员会觉得 Polars API 比 Pandas 中的深奥操作更容易上手。如果您正在处理大量数据,Polars 会让您的工作速率更快。

详情请见:
https://github.com/pola-rs/polars

QLoRA

Tim Dettmers 和他的团队似乎肩负着一项使命,那就是让大型语言模型能够一切设备上运行。去年,他们的 bitsandbytes 库将大型语言模型的推理引入了消费级硬件。今年,他们转向了训练,将已经令人印象深刻的 LoRA 技术缩小到量化模型上。使用 QLoRA 意味着您可以在台式机上微调 30B 以上的庞大参数模型,与在多个 GPU 上进行全面调整相比,精度损失很小。事实上,QLoRA 有时甚至做得更好。低位推理和训练意味着更多的人可以使用 LLM——这也正是开源的意义所在。

详情请见:
https://github.com/artidoro/qlora

RAPIDS

RAPIDS 是一系列 GPU 加速库,用于常见的数据科学和分析任务。每个库都处理特定的任务,如用于数据帧处理的 cuDF、用于图形分析的 cuGraph 和用于机器学习的 cuML。其他库涵盖镜像处理、信号处理和空间分析,而集成则将 RAPIDS 带到 Apache Spark、SQL 和其他工作负载中。如果现有的库都不符合要求,RAPIDS 还包括 RAFT,这是一个 GPU 加速基元集合,用于构建自己的解决方案。RAPIDS 还可与 Dask 携手在多个节点上扩展,并与 Slurm 携手在高性能计算环境中运行。

详情请见:
https://github.com/rapidsai

Spark NLP

Spark NLP 是一个自然语言处理库,可在 Apache Spark 上运行,支持 Python、Scala 和 Java。该库可帮助开发人员和数据科学家尝试使用大型语言模型,包括来自谷歌、Meta、OpenAI 等公司的转换器模型。Spark NLP 的模型中心有 2 万多个模型和管道可供下载,用于语言翻译、命名实体识别、文本分类、问题解答、情感分析和其他用例。2023 年,Spark NLP 发布了许多 LLM 集成、新的镜像到文本注释器,用于为镜像添加标题并支持所有主要的公共云存储系统以及ONNX。

详情请见:
https://github.com/JohnSnowLabs/spark-nlp

StarRocks

如今,公司经常向数百万并发用户实时提供复杂的数据。即使是 PB 级查询,也必须在数秒内完成。StarRocks 是一个查询引擎,它结合了本地代码(C++)、高效的基于成本的优化器、使用 SIMD 指令集的矢量处理、缓存和物化视图,可以高效地处理大规模连接。StarRocks 甚至能在直接查询数据湖和湖仓一体(包括 Apache Hudi 和 Apache Iceberg)时提供接近原生的性能。无论您是在追求实时分析、提供面向客户的分析服务,还是只是想在不移动数据的情况下查询数据湖,StarRocks 都值得您一试。

详情请见:
https://github.com/StarRocks/starrocks

TensorFlow.js

TensorFlow.js 将谷歌 TensorFlow 机器学习框架的强大功能打包到 JavaScript 软件包中,以最低的学习成本为 JavaScript 开发人员带来非凡的功能。您可以在浏览器、带有 WebGL 加速功能的纯 JavaScript 栈或服务器上的 tfjs-node 库中运行 TensorFlow.js。Node 库为您提供了相同的 JavaScript API,但运行于 C 二进制程序之上,可最大限度地提高速度和 CPU/GPU 使用率。

如果您是对机器学习感兴趣的 JS 开发人员,TensorFlow.js 显然是您的首选。它为 JS 生态系统做出了值得欢迎的贡献,让广大开发者更容易接触到人工智能。

详情请见:
https://github.com/tensorflow/tfjs

vLLM

vLLM 是最有前途的框架之一,它支持 Hugging Face 模型、兼容 OpenAI 的 API 和 PagedAttention 算法,该算法的生产量是 Hugging Face 变换器库的 20 倍。目前,它是为生产中的 LLM 提供服务的不二之选,FlashAttention 2 支持等新功能也在快速添加中。

详情请见:
https://github.com/vllm-project/vllm

Weaviate

GenAI 的蓬勃发展激发了对新型数据库的需求,这种数据库可以支持大量复杂的非结构化数据。矢量数据库应运而生。Weaviate 在部署模式、生态系统集成和数据隐私方面为开发人员提供了大量灵活性。Weaviate 将关键词搜索与矢量搜索相结合,可快速、可扩展地发现多模态数据(文本、图像、音频、视频)。它还有用于 RAG 开箱即用模块,可为 chatbots 和其他 GenAI 应用程序提供特定领域的数据,使其更加有用。

详情请见:
https://github.com/weaviate/weaviate

Zig

在当今所有的开源项目中,Zig 可能是最重要的一个。Zig 致力于创建一种具有程序级内存控制功能的通用编程语言,其性能优于 C 语言,同时提供更强大、更不易出错的语法。其目标是取代 C 语言,成为编程生态系统中的基准语言。由于 C 语言无处不在(即系统和设备中最常见的组件),Zig 的成功意味着性能和稳定性的广泛提高。这是我们都应该期待的。另外,Zig 是一个优秀的、老式的草根项目,有着巨大的抱负和开源精神。

详情请见:
https://github.com/ziglang/zig

本文分享自华为云社区《
K8s集群CoreDNS监控告警最佳实践
》,作者:可以交个朋友。

一 背景

coreDNS作为K8s集群中的关键组成部分。主要负责k8s集群中的服务发现,域名解析等功能。如果在使用过程中出现域名解析失败,域名解析超时等情况,需要引起注意。

二 方案简介

可以通过CCE集群插件kube-prometheus-stack进行coreDNS服务的指标监控,并提供开箱即用的仪表盘视图。时刻观察coreDNS的各项运行指标是否处于健康状态。

【加一下怎么到这个图的,选监控-仪表盘】

image.png

CCE普罗监控数据统一吐到华为云AOM2.0服务,可以在AOM2.0服务中根据展示各种普罗指标数据,并根据业务实际诉求,实现基于指标的的告警通知。

【CCE普罗对接哪个AOM实例】

【加一个AOM2.0图,可以看到AOM实例指标数据】

三 coreDNS关键指标

确保Prometheus已经成功抓取coreDNS相关指标

image.png

  • coreDNS请求速率:
    sum(rate(coredns_dns_requests_total{}[5m])) by (proto,instance)

  • coreDNS请求速率(记录类型分组):
    sum(rate(coredns_dns_requests_total{}[5m])) by (type,instance)

  • coreDNS请求速率(DO标志位):
    sum(rate(coredns_dns_do_requests_total{}[5m])) by (instance)

  • coreDNS UDP请求数据包大小:
    P99:
    histogram_quantile(0.99,sum(rate(coredns_dns_request_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))
    P90:
    histogram_quantile(0.90,sum(rate(coredns_dns_request_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))
    P50:
    histogram_quantile(0.50,sum(rate(coredns_dns_request_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))

  • coreDNS TCP请求数据包大小:
    P99:
    histogram_quantile(0.99,sum(rate(coredns_dns_request_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))
    P90:
    histogram_quantile(0.90,sum(rate(coredns_dns_request_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))
    P50:
    histogram_quantile(0.50,sum(rate(coredns_dns_request_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))

  • coreDNS响应速率(根据响应状态码分组):
    sum(rate(coredns_dns_responses_total{}[5m])) by(rcode,instance)

  • coreDNS响应时延:
    P99:
    histogram_quantile(0.99,sum(rate(coredns_dns_request_duration_seconds_bucket{}[5m])) by(le,job,instance))
    P90:
    histogram_quantile(0.90,sum(rate(coredns_dns_request_duration_seconds_bucket{}[5m])) by(le,job,instance))
    P50:
    histogram_quantile(0.50,sum(rate(coredns_dns_request_duration_seconds_bucket{}[5m])) by(le,job,instance))

  • coreDNS UDP响应数据包大小:
    P99:
    histogram_quantile(0.99,sum(rate(coredns_dns_response_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))
    P90:
    histogram_quantile(0.90,sum(rate(coredns_dns_response_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))
    P50:
    histogram_quantile(0.50,sum(rate(coredns_dns_response_size_bytes_bucket{proto="udp"}[5m])) by(le,proto,instance))

  • coreDNS TCP响应数据包大小
    P99:
    histogram_quantile(0.99,sum(rate(coredns_dns_response_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))
    P90:
    histogram_quantile(0.90,sum(rate(coredns_dns_response_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))
    P50:
    histogram_quantile(0.50,sum(rate(coredns_dns_response_size_bytes_bucket{proto="tcp"}[5m])) by(le,proto,instance))

  • coreDNS缓存的DNS记录数:
    sum (coredns_cache_entries{}) by(type,instance)

  • coreDNS缓存命中率:
    sum (rate(coredns_cache_hits_total{}[5m])) by (type,instance)

  • coreDNS缓存丢失率:
    sum (rate(coredns_cache_misses_total{}[5m])) by (type,instance)

其中主要关注:p99coreDNS响应时延、coreDNS请求速率、coreDNS缓存命中率指标,其中p99coreDNS响应时延基于域名解析超时时间一般为2s,可以初步设置高级阈值为1s,后续再根据实际监控数据根据指标进一步设置一个更加精细阈值。

四: 如何根据coreDNS指标进行告警

前往AOM告警管理tab页

【怎么导入这个图】

配置告警规则

选择指标告警规则,配置方式可使用PromQL语句

image.png

配置告警通知规则

image.png

触发指标告警规则,邮箱收到告警

模型评估
在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力。

本篇主要介绍
模型评估
时,如何利用
scikit-learn
帮助我们快速进行各种
偏差
的分析。

1. **R² ** 分数

R² 分数
(也叫
决定系数
),用于衡量模型预测的拟合优度,它表示模型中
因变量
的变异中,可由
自变量
解释的部分所占的比例。


接近1

的话,表示模型能够很好地解释因变量的变异,
接近0
的话,则表示模型解释能力较差。

需要注意的是,虽然
R² 分数
是一个很有用的指标,但它也有一些局限性。
例如,当模型中自变量数量增加时,
R² 分数
可能会增加,即使这些自变量对因变量没有真正的解释力。
因此,在使用
R² 分数
评估模型时,还需要结合其他诊断指标和领域知识进行综合判断。

1.1. 计算公式

\(R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{n} (y_i - \bar{y})^2}\)

\(\bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_i\)
其中,
\(n\)
是样本数量,
\(y_i\)
是真实值,
\(\hat{y_i}\)
是预测值。

1.2. 使用示例

from sklearn.metrics import r2_score

y_true = [1, 2, 3, 4]

y_pred = [0, 1, 3, 5]
r2_score(y_true, y_pred)
# 结果: 0.4

y_pred = [0, 2, 3, 4]
r2_score(y_true, y_pred)
# 结果: 0.8

r2_score
就是
scikit-learn
中用来计算 **R² 分数 **的函数。

2. 解释方差分数

解释方差分数

Explained Variance Score
,简称
EVS
),它用于量化模型对目标变量的解释程度。
解释方差分数
比较高则表示模型能够较好地解释数据中的方差,即模型的预测与实际观测值较为接近。

需要注意的是,
解释方差分数
仅关注模型对方差的解释程度,并不直接反映预测的准确度。

2.1. 计算公式

\(explained\_{}variance(y, \hat{y}) = 1 - \frac{Var\{ y - \hat{y}\}}{Var\{y\}}\)
其中,
\(y\)
是真实值,
\(\hat{y}\)
是预测值。
\(Var\)
表示计算方差,比如:
\(Var{\{y\}} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \bar{y})^2\)

2.2. 使用示例

from sklearn.metrics import explained_variance_score

y_true = [1, 2, 3, 4]

y_pred = [0, 1, 3, 5]
explained_variance_score(y_true, y_pred)
# 结果: 0.45

y_pred = [0, 2, 3, 4]
explained_variance_score(y_true, y_pred)
# 结果: 0.85

explained_variance_score
就是
scikit-learn
中用来计算 **解释方差分数 **的函数。

3. Tweedie 偏差

Tweedie 偏差
是一种用于评估广义线性模型的指标,它衡量了预测值与实际观测值之间的差异,并考虑了模型的方差结构和分布假设。

Tweedie 偏差
根据
Tweedie分布
的定义而来,参数不同,表示不同的分布。
Tweedie 偏差
较小,表示模型的预测与实际观测值之间的差异较小,即模型能够更好地拟合数据。

需要注意的是,在使用
Tweedie 偏差
时,需要确保所选的
Tweedie 分布
适合数据的特性,否则可能会导致不准确的评估结果。

3.1. 计算公式

\(\text{D}(y, \hat{y}) = \frac{1}{n}
\sum_{i=0}^{n - 1}
2\left(\frac{\max(y_i,0)^{2-p}}{(1-p)(2-p)}-
\frac{y_i\,\hat{y}_i^{1-p}}{1-p}+\frac{\hat{y}_i^{2-p}}{2-p}\right)\)

其中,
\(n\)
是样本数量,
\(y_i\)
是真实值,
\(\hat{y_i}\)
是预测值。

上面的公式中,
\(p=0\)
时,
Tweedie 偏差
相当于
均方误差

\(\text{D}(y, \hat{y}) = \frac{1}{n}
\sum_{i=0}^{n - 1} (y_i-\hat{y}_i)^2\)


\(p=1\)
时,
Tweedie 偏差
相当于
平均泊松偏差

\(\text{D}(y, \hat{y}) = \frac{1}{n}
\sum_{i=0}^{n - 1} 2(y_i \log(y_i/\hat{y}_i) + \hat{y}_i - y_i)\)


\(p=2\)
时,
Tweedie 偏差
相当于
平均Gamma偏差

\(\text{D}(y, \hat{y}) = \frac{1}{n}
\sum_{i=0}^{n - 1} 2(\log(\hat{y}_i/y_i) + y_i/\hat{y}_i - 1)\)

3.2. 使用示例

from sklearn.metrics import mean_tweedie_deviance

mean_tweedie_deviance([1], [2], power=0)
# 运行结果: 1.0
mean_tweedie_deviance([100], [200], power=0)
# 运行结果: 10000.0

mean_tweedie_deviance([1], [2], power=1)
# 运行结果: 0.6137056388801092
mean_tweedie_deviance([100], [200], power=1)
# 运行结果: 61.370563888010906

mean_tweedie_deviance([1], [2], power=2)
# 运行结果: 0.3862943666666698908
mean_tweedie_deviance([100], [200], power=2)
# 运行结果: 0.3862943666666698908

power
参数不同,同样是预测值和实际值
差两倍
的情况下,不同分布,
Tweedie 偏差
的结果差别很大。

4. 总结

总之,
scikit-learn
中提供的回归模型偏差的计算方式,能够帮助我们了解模型的性能、选择适合的模型、优化模型以及辅助决策。
对于回归问题的建模和预测具有重要的实际意义。

前言

近期在琢磨Zabbix邮箱报警的功能,但是网上的教程通常是4.0或5.0版本Zabbix,并使用Python2.7环境,运行在新版本Zabbix6.0上有颇多问题,为此我基于原先教程修改基于Zabbix6.0并使用Python3+的解决方案。期间遇到不少坑,特此分享。

Zabbix自带报警

Zabbix是自带的邮箱的报警功能有限,比如不能实现诸如邮件插入图片的功能,而可以使用执行脚本功能则可以调用本地程序,调用Python脚本从而实现许多如发送企业微信、钉钉使用的功能。

前端设置

报警媒介

在zabbix中保存脚本文件的目录为
/usr/lib/zabbix/alertscripts/
,目前4.0\5.0\6.0都通用,将shell脚本文件保存于此可以直接在
报警媒介类型
调用。

参数需要传递给脚本,对于着Shell脚本中的
$1

$2

$3

{ALERT.SENDTO} //发件人(对应着用户\报警媒介中配置的发件人)
{ALERT.SUBJECT} //主题(对应着主题模版)
{ALERT.MESSAGE} //消息内容(对应着消息模版)

发件人

主题\消息内容

报警媒介消息模版

在消息模版中,添加问题发生

// 问题发生
// 主题
发生故障:服务器:{HOSTNAME}->{TRIGGER.NAME}警告!
// 消息
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}

添加问题恢复

//问题恢复
// 主题
问题恢复:服务器:{HOST.NAME}->{TRIGGER.NAME}已恢复!
// 消息
监控ID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}

设置用户报警媒介

在管理\用户<用户名>\报警媒介
如果有多个收件人,用
,
分割,我在python中做了定义

设置动作

要想要脚本触发问题后执行还需要设置

脚本实现

涉及到两个脚本

Shell脚本
/usr/lib/zabbix/alertscripts/sedmail.zabbix.sh
主要是用于实现连接Python脚本,测试、删除图片
创建
/usr/lib/zabbix/alertscripts/graph
Python脚本
主要是实现Zabbix中图片的下载、邮件发送

Shell脚本

新版本的Zabbix6.0貌似不支持直接执行Python脚本,为此我使用一个shell脚本作为中转,且可实现简单的测试、删除图片文件。

/usr/lib/zabbix/alertscripts/sedmail.zabbix.sh

#!/bin/bash
cd `dirname $0`
echo "{ALERT.SENDTO} = $1" > debug.txt
echo "{ALERT.SUBJECT} = $2" >> debug.txt
echo "{ALERT.MESSAGE} = $3" >> debug.txt
python3 sedmail.zabbix.py "$1" "$2" "$3" >> debug.txt
echo "shell success" >> debug.txt
find graph -type f -name "*.png" | xargs rm

Python脚本

主要是实现Zabbix中图片的下载、邮件发送,本Python脚本使用Python3环境,如果你需

脚本过程

  1. 解析传递过来的
    主题{ALERT.SENDTO}

    主题{ALERT.SUBJECT}

    消息{ALERT.MESSAGE}
    消息中的
    监控ID:
    后的数字,即itemid,此项极为重要
itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)
# 如果你改了消息模版记得修改一下search匹配规则
  1. 登录Zabbix:使用Post登录http://zabbix:8080/index.php
 "name":user, # 用户
 "password":password, # 密码
 "autologin":"1", # 30天内自动登录
 "enter":"登录", # 请注意这个对应你语言,如果是英文为login on,可以抓包看看

抓包

  1. 故障的统计图下载,对应着先前的
    itemid
    参数,可以使用get请求
    http://zabbix:8080/chart.php
    后带的参数
 "from" :"now-30m",
 "to" : "now",
 "itemids[0]" : itemid,# 请注意,Zabbix6.0中是itemid[0],在更老的4.0\5.0使用的itemid
 "width" : "300",
 #对应的url,以itemid[0]=79672为例
 http://zabbix:8080/chart.php?from=now-30m&to=now&itemids%5B0%5D=79672&width=300

注意需要在登录的前提下,并且login的headers消息头一致,不然对提示错误
文件会保存在
graph_path='/usr/lib/zabbix/alertscripts/graph'
如果没有此文件夹需要创建

完整脚本

/usr/lib/zabbix/alertscripts/sedmail.zabbix.py

#!/usr/bin/python3
#coding=utf-8
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import smtplib,sys,os,time,re,requests,logging
from smtplib import SMTP

user='Admin'    #定义zabbix用户名
password='password'    #定义zabbix用户密码
graph_path='/usr/lib/zabbix/alertscripts/graph'   #定义图片存储路径
graph_url='http://127.0.0.1:8080/chart.php'     #定义图表的url
loginurl="http://127.0.0.1:8080/index.php"          #定义登录的url
host='127.0.0.1'
to_email=sys.argv[1].split(',')    #传入的第一个参数为收件人邮箱
subject=sys.argv[2]  #传入的第二个参数为邮件主题
subject=subject.encode('utf-8').decode('utf-8')
smtp_host = 'smtp.xxx.net'  #定义smtp主机地址
from_email = 'alittlemc@xxx.com'     #定义发件人地址
mail_pass = 'xxx'       #发件人邮箱校验码\密码

def get_itemid():
    #获取报警的itemid
    itemid=re.search(r'监控ID:(\d+)',sys.argv[3]).group(1)
    return itemid

def get_graph(itemid):
    #获取报警的图表并保存
    session=requests.Session()   #创建一个session会话
    try:
        loginheaders={
        "Host":host,
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
        }
        #定义请求消息头

        payload = {
        "name":user,
        "password":password,
        "autologin":"1",
        "enter":"登录",
        }
        #定义传入的data
        login=session.post(url=loginurl,headers=loginheaders,data=payload)
        # print(login.text)
        #进行登录
        graph_params={
            "from" :"now-30m",
            "to" : "now",
            "itemids[0]" : itemid,
            "width" : "300",
        }
        # print(itemid)
        # http://zabbix:8080/chart.php?from=now-1m&to=now&itemids%5B0%5D=79672

        #定义获取图片的参数
        graph_req=session.get(url=graph_url,params=graph_params,headers=loginheaders)
        #发送get请求获取图片数据
        time_tag=time.strftime("%Y%m%d%H%M%S", time.localtime())
        graph_name='baojing_'+time_tag+'.png'
        #用报警时间来作为图片名进行保存
        graph_name = os.path.join(graph_path, graph_name)
        #使用绝对路径保存图片
        with open(graph_name,'wb') as f:
            f.write(graph_req.content)
            #将获取到的图片数据写入到文件中去
        return graph_name

    except Exception as e:
        # print(e)
        return False
def text_to_html(text):
    #将邮件内容text字段转换成HTML格式
    d=text.splitlines()
    #将邮件内容以每行作为一个列表元素存储在列表中
    html_text=''
    for i in d:
        i='' + i + '<br>'
        html_text+=i + '\n'
    #为列表的每个元素后加上html的换行标签
    return html_text

def send_mail(graph_name):
    #将html和图片封装成邮件进行发送
    msg = MIMEMultipart('related')  #创建内嵌资源的实例

    with open(graph_name,'rb') as f:
        #读取图片文件
        graph=MIMEImage(f.read())  #读取图片赋值一个图片对象
    graph.add_header('Content-ID','imgid1')  #为图片对象添加标题字段和值
    text=text_to_html(sys.argv[3])
    html="""
    <html>
      <body>
      %s  <br><img src="cid:imgid1">
      </body>
    </html>
    """ % text
    html=MIMEText(html,'html','utf-8')  #创建HTML格式的邮件体
    msg.attach(html)   #使用attach方法将HTML添加到msg实例中
    msg.attach(graph)  #使用attach方法将图片添加到msg实例中
    msg['Subject'] = subject
    msg['From'] = from_email
    try:
        server=SMTP(smtp_host,"587")   #创建一个smtp对象
        server.starttls()    #启用安全传输模式
        server.login(from_email,mail_pass)  #邮箱账号登录
        for x in to_email:
            server.sendmail(from_email,x,msg.as_string())  #发送邮件
        server.quit()   #断开smtp连接
    except smtplib.SMTPException as a:
        print(a)

def run():
    itemid=get_itemid()
    graph_name=get_graph(itemid)
    send_mail(graph_name)

if __name__ =='__main__':
    run()
    print('success',sys.argv[1],sys.argv[2],sys.argv[3])

测试

可以直接使用报警媒介的测试功能,对应的传输
主题{ALERT.SENDTO}

主题{ALERT.SUBJECT}

消息{ALERT.MESSAGE}
消息

本文介绍基于
VMware Workstation Pro
虚拟机软件,配置
Linux Ubuntu
操作系统环境的方法。

首先,我们需要进行
VMware Workstation Pro
虚拟机软件的下载与安装。需要注意的是,
VMware Workstation Pro
软件是一个收费软件,而互联网中有很多可以下载后
直接免费激活、使用
这一软件的方法与资源,这里就不再赘述,直接从
VMware Workstation Pro
软件的安装开始介绍。

第一步,将大家下载好的
VMware Workstation Pro
软件安装包打开,进入安装步骤。

其中,在如下窗口中,我们可以指定软件安装的路径(如果系统盘不是很大的话建议更换到其他盘符下);同时,将以下两个勾选项都选中。

在完成
VMware Workstation Pro
软件的安装后,如果我们是通过输入许可证密钥(这个密钥网上也有很多资源)来激活软件,我们就需要选择“
许可证
”进入密钥输入界面,并完成软件的激活。

安装完毕后,需要重启电脑。

重启电脑后,打开
VMware Workstation Pro
虚拟机软件,将出现如下图所示的界面。

以上即完成了
VMware Workstation Pro
虚拟机软件的下载与安装。

接下来,我们需要下载
Linux Ubuntu
操作系统的镜像文件,用以后期在虚拟机中安装
Linux Ubuntu
操作系统。
Linux Ubuntu
操作系统是免费使用的,因此我们可以直接从其
官网
进行下载。

Linux Ubuntu
操作系统的镜像文件相对比较大;大家下载的时候可以先继续进行着下文的步骤。

Linux Ubuntu
操作系统的镜像文件下载同时,我们首先需要在
VMware Workstation Pro
虚拟机软件中配置新的虚拟机。如下图所示,我们选择“
创建新的虚拟机
”选项。

在弹出的窗口中,选择“
典型
”选项。

随后,在如下所示的界面中,如果我们此时已经完成了
Linux Ubuntu
操作系统镜像文件的下载,那么可以选中第二项“
安装程序光盘映像文件(iso)
”选项,并选择我们下载好的
Linux Ubuntu
操作系统的镜像文件;如果此时还没有下载好镜像文件,那么选择下图中红色框内的选项即可。

随后,在如下所示的界面中,选择我们创建虚拟机的操作系统(本文中就是
Linux
)及其版本(本文中就是
Ubuntu 64位
)。

随后,配置这台虚拟机的名称与其存储位置;这里同样建议将“
位置
”选择为除系统盘以外的其他盘符。

接下来,我们需要配置虚拟机所占用的磁盘大小。这里我们选择默认即可;后续使用虚拟机的过程中如果该项不合适,还可以再修改。

随后,在接下来的窗口中,我们可以选择“
自定义硬件
”,从而对虚拟机的更多属性进行配置。

其中,我们可以对内存进行修改;这里也建议大家使用默认的内存即可;后续使用虚拟机的过程中如果该项不合适,还可以再修改。

此外,如果此时我们的
Linux Ubuntu
操作系统镜像文件已经下载好,可以在如下所示的位置将其选中;如果还没有下载好,继续进行后续的步骤即可。

随后,我们完成了虚拟机的建立与配置。

这个时候,我们就需要等待
Linux Ubuntu
操作系统镜像文件的下载进度了,需要其下载完毕后进行接下来的操作。

首先,如果
Linux Ubuntu
操作系统镜像文件是刚刚下载好的,我们需要在“
编辑虚拟机设置
”选项中,找到如下所示的界面,并在“
使用ISO映像文件
”处选择我们下载好的
Linux Ubuntu
操作系统镜像文件。

接下来,选择“
开启此虚拟机
”选项。

如果虚拟机是第一次开启,一开始会先有一个界面,让大家选择要进入哪一个模式(大概是这个意思,我这里没来得及截图);如果出现这个选择,大家就选择第一项,即包含有
try or install
字样的那一项即可;或者直接稍等片刻,系统会自动进入我们需要的模式。

随后,虚拟机将开机。

接下来,我们需要为虚拟机安装
Linux Ubuntu
操作系统。选择“
Install Ubuntu
”选项。

接下来,配置好虚拟机之后
Linux Ubuntu
操作系统的语言。如果需要中文,大家按照下图所示的选项进行选择即可;我这里
Linux Ubuntu
操作系统语言则选择了默认的英文。

接下来,在下图所示的界面中,选择默认的选项,并点击“
Continue
”。

在弹出的提示窗口中,依然选择“
Continue
”。

接下来,我们选择我们所在的地理位置,并设置虚拟机
Linux Ubuntu
操作系统的账户名称、电脑名称与账户密码等。

这里需要注意一点,如果大家此时发现自己的虚拟机不能用小键盘,可以参考本文最后一部分内容来设置;我们这里还是先继续
Linux Ubuntu
操作系统的安装。完成前述全部配置后,即可开始
Linux Ubuntu
操作系统的安装;这一安装步骤大概需要十几分钟。

安装完毕后,虚拟机将提示需要重启;我们重启虚拟机即可。

如果这一次重启时,一直卡在下图所示的界面,则直接按下
回车
键即可。这里要注意,要先用鼠标在虚拟机屏幕内点一下,然后再按下
回车
键;否则可能这个
回车
是按在我们的主机环境下,导致虚拟机一直没有反应。

接下来,即可完成开机。这里我们输入刚刚创建的账户密码即可。

以上,即完成了
VMware Workstation Pro
虚拟机配置
Linux Ubuntu
操作系统的方法。

最后,介绍一下如何在虚拟机中开启小键盘。首先,如果此时虚拟机是开着的,那么需要点击最上方的
橘色暂停
按钮,并右键虚拟机名称选择“
设置
”(或者选择“
编辑虚拟机设置
”)。

在弹出的窗口中,选择“
选项
”→“
常规
”,并将“
增强型键盘
”一栏选为“
在可用时使用(推荐)
”;如下图所示。

最后,确保在虚拟机中通过
Num Lock
键开启小键盘,便可以在虚拟机中使用小键盘了。