分类 技术 下的文章

这个快速指南解释了在 Fedora 34 及以上版本中安装 Shutter 所需的步骤。

截图工具有很多替代和选择。但在我个人看来,没有一个能接近 Shutter 的灵活性。不幸的是,由于各种依赖性问题,特别是它的设计方式,多年来,Linux 发行版,如 Ubuntu、Fedora,都面临着将这个应用打包到官方仓库的问题。

主要问题是它仍然基于 GTK2 和 Perl。当大多数应用转移到 GTK3 时,它仍然是 GTK2。这就造成了一个依赖性问题,因为 Debian/Ubuntu、Fedora 删除了某些包的依赖的 GTK2 版本。

在 Fedora 34 及以上版本中安装 Shutter 截图工具需要采用另一种方法。

现在,你只能通过个人包存档(PPA)来安装这个工具。下面是如何在 Fedora 34 及以上版本中安装它。

Shutter in Fedora

在 Fedora 34 及以上版本中安装 Shutter

在你的 Fedora 中打开一个终端,启用以下 Shutter 的 copr 仓库。这个包存档为 Fedora 的 Shutter 提供了一个单独的构建,其中包含了所有未满足的依赖项。

sudo dnf copr enable geraldosimiao/shutter

完成后,你就可以通过 dnf 在 Fedora 34 及以上版本中简单地安装 Shutter。

sudo dnf install shutter

尽管目前最新的版本是 v0.97。遗憾的是,该仓库目前包含旧的 v0.94.x。我希望版本库的所有者尽快包括最新的版本。

安装后,你可以通过应用菜单启动它。

卸载 Shutter

如果你愿意,你可以通过命令轻松地删除这个第三方仓库:

sudo dnf copr remove geraldosimiao/shutter

然后按照下面的方法,完全删除 Shutter,包括依赖关系。

sudo dnf autoremove shutter

在其他 Linux 发行版中安装 Shutter

如果你想在 Debian、Ubuntu 或相关发行版中安装它,请 查看此指南

Shutter 的开发

最近,这个项目 转移到了 GitHub,以便更好地协作,并且正在进行 GTK3 移植。而且它相当活跃,最近还发布了一个版本。我们希望它能尽快被移植到 GTK3 上,并在各发行版的原生仓库中可用。

如果你在安装 Shutter 时遇到任何错误,请在评论栏告诉我。


via: https://www.debugpoint.com/2021/07/install-shutter-fedora/

作者:Arindam 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用 Podman Machine 创建一个基本的 Fedora CoreOS 虚拟机来使用容器和容器化工作负载。

 title=

Fedora CoreOS 是一个自动更新、最小化的基于 rpm-ostree 的操作系统,用于安全地、大规模地运行容器化工作负载。

Podman “是一个用于管理容器和镜像、挂载到这些容器中的卷,以及由这些容器组组成的吊舱的工具。Podman 基于 libpod,它是一个容器生命周期管理库”。

当你使用 Podman Machine 时,神奇的事情发生了,它可以帮助你创建一个基本的 Fedora CoreOS 虚拟机(VM)来使用容器和容器化工作负载。

开始使用 Podman Machine

第一步是安装 Podman。如果你已经安装了最新版本的 Podman,你可以跳过这个步骤。在我的 Fedora 34 机器上,我用以下方式安装 Podman:

$ sudo dnf install podman

我使用的是 podman-3.2.2-1.fc34.x86\_64。

初始化 Fedora CoreOS

Podman 安装完成后,用以下方法初始化它:

❯ podman machine init vm2
Downloading VM image: fedora-coreos-34.20210626.1.0-qemu.x86_64.qcow2.xz: done 
Extracting compressed file

这个命令创建了 vm2,并下载了 .xz 格式的 Fedora CoreOS 的 qcow2 文件并将其解压。

列出你的虚拟机

了解你的虚拟机和它们的状态是很重要的,list 命令可以帮助你做到这一点。下面的例子显示了我所有的虚拟机的名称,它们被创建的日期,以及它们最后一次启动的时间:

❯ podman machine list 
NAME          VM TYPE     CREATED     LAST UP
podman-machine-default* qemu      6 days ago   Currently running
vm2           qemu      11 minutes ago 11 minutes ago

启动一个虚拟机

要启动一个虚拟机,请运行:

❯ podman machine start
Waiting for VM ...

SSH 到虚拟机

你可以使用 SSH 来访问你的虚拟机,并使用它来运行工作负载,而没有任何麻烦的设置:

❯ podman machine ssh  
Connecting to vm podman-machine-default. To close connection, use `~.` or `exit`
Fedora CoreOS 34.20210611.1.0
Tracker: https://github.com/coreos/fedora-coreos-tracker
Discuss: https://discussion.fedoraproject.org/c/server/coreos/
 
Last login: Wed Jun 23 13:23:36 2021 from 10.0.2.2
[core@localhost ~]$ uname -a
Linux localhost 5.12.9-300.fc34.x86_64 #1 SMP Thu Jun 3 13:51:40 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[core@localhost ~]$

目前,Podman 只支持一次运行一个虚拟机。

停止你的虚拟机

要停止运行中的虚拟机,请使用 stop 命令:

❯ podman machine stop

[core@localhost ~]$ Connection to localhost closed by remote host.
Connection to localhost closed.
Error: exit status 255

我希望这能帮助你开始使用 Podman Machine。请试一试,并在评论中告诉我们你的想法。


via: https://opensource.com/article/21/7/linux-podman

作者:Sumantro Mukherjee 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

bpftrace 是一个 基于 eBPF 的新型追踪工具,在 Fedora 28 第一次引入。Brendan Gregg、Alastair Robertson 和 Matheus Marchini 在网上的一个松散的黑客团队的帮助下开发了 bpftrace。它是一个允许你分析系统在幕后正在执行的操作的追踪工具,可以告诉你代码中正在被调用的函数、传递给函数的参数、函数的调用次数等。

这篇文章的内容涉及了 bpftrace 的一些基础,以及它是如何工作的,请继续阅读获取更多的信息和一些有用的实例。

eBPF( 扩展的伯克利数据包过滤器 extended Berkeley Packet Filter

eBPF 是一个微型虚拟机,更确切的说是一个位于 Linux 内核中的虚拟 CPU。eBPF 可以在内核空间以一种安全可控的方式加载和运行小型程序,使得 eBPF 的使用更加安全,即使在生产环境系统中。eBPF 虚拟机有自己的指令集架构(ISA),类似于现代处理器架构的一个子集。通过这个 ISA,可以很容易将 eBPF 程序转化为真实硬件上的代码。内核即时将程序转化为主流处理器架构上的本地代码,从而提升性能。

eBPF 虚拟机允许通过编程扩展内核,目前已经有一些内核子系统使用这一新型强大的 Linux 内核功能,比如网络、安全计算、追踪等。这些子系统的主要思想是添加 eBPF 程序到特定的代码点,从而扩展原生的内核行为。

虽然 eBPF 机器语言功能强大,由于是一种底层语言,直接用于编写代码很费力,bpftrace 就是为了解决这个问题而生的。eBPF 提供了一种编写 eBPF 追踪脚本的高级语言,然后在 clang / LLVM 库的帮助下将这些脚本转化为 eBPF,最终添加到特定的代码点。

安装和快速入门

在终端 使用 sudo 执行下面的命令安装 bpftrace:

$ sudo dnf install bpftrace

使用“hello world”进行实验:

$ sudo bpftrace -e 'BEGIN { printf("hello world\n"); }'

注意,出于特权级的需要,你必须使用 root 运行 bpftrace,使用 -e 选项指明一个程序,构建一个所谓的“单行程序”。这个例子只会打印 “hello world”,接着等待你按下 Ctrl+C

BEGIN 是一个特殊的探针名,只在执行一开始生效一次;每次探针命中时,大括号 {} 内的操作(这个例子中只是一个 printf)都会执行。

现在让我们转向一个更有用的例子:

$ sudo bpftrace -e 't:syscalls:sys_enter_execve { printf("%s called %s\n", comm, str(args->filename)); }'

这个例子打印了父进程的名字(comm)和系统中正在创建的每个新进程的名称。t:syscalls:sys_enter_execve 是一个内核追踪点,是 tracepoint:syscalls:sys_enter_execve 的简写,两种形式都可以使用。下一部分会向你展示如何列出所有可用的追踪点。

comm 是一个 bpftrace 内建指令,代表进程名;filenamet:syscalls:sys_enter_execve 追踪点的一个字段,这些字段可以通过 args 内建指令访问。

追踪点的所有可用字段可以通过这个命令列出:

bpftrace -lv "t:syscalls:sys_enter_execve"

示例用法

列出探针

bpftrace 的一个核心概念是 探针点 probe point ,即 eBPF 程序可以连接到的(内核或用户空间的)代码中的测量点,可以分成以下几大类:

  • kprobe——内核函数的开始处
  • kretprobe——内核函数的返回处
  • uprobe——用户级函数的开始处
  • uretprobe——用户级函数的返回处
  • tracepoint——内核静态追踪点
  • usdt——用户级静态追踪点
  • profile——基于时间的采样
  • interval——基于时间的输出
  • software——内核软件事件
  • hardware——处理器级事件

所有可用的 kprobe / kretprobetracepointssoftwarehardware 探针可以通过这个命令列出:

$ sudo bpftrace -l

uprobe / uretprobeusdt 是用户空间探针,专用于某个可执行文件。要使用这些探针,通过下文中的特殊语法。

profileinterval 探针以固定的时间间隔触发;固定的时间间隔不在本文的范畴内。

统计系统调用数

映射 是保存计数、统计数据和柱状图的特殊 BPF 数据类型,你可以使用映射统计每个系统调用正在被调用的次数:

$ sudo bpftrace -e 't:syscalls:sys_enter_* { @[probe] = count(); }'

一些探针类型允许使用通配符匹配多个探针,你也可以使用一个逗号隔开的列表为一个操作块指明多个连接点。上面的例子中,操作块连接到了所有名称以 t:syscalls:sysenter_ 开头的追踪点,即所有可用的系统调用。

bpftrace 的内建函数 count() 统计系统调用被调用的次数;@[] 代表一个映射(一个关联数组)。该映射的键 probe 是另一个内建指令,代表完整的探针名。

这个例子中,相同的操作块连接到了每个系统调用,之后每次有系统调用被调用时,映射就会被更新,映射中和系统调用对应的项就会增加。程序终止时,自动打印出所有声明的映射。

下面的例子统计所有的系统调用,然后通过 bpftrace 过滤语法使用 PID 过滤出某个特定进程调用的系统调用:

$ sudo bpftrace -e 't:syscalls:sys_enter_* / pid == 1234 / { @[probe] = count(); }'

进程写的字节数

让我们使用上面的概念分析每个进程正在写的字节数:

$ sudo bpftrace -e 't:syscalls:sys_exit_write /args->ret > 0/ { @[comm] = sum(args->ret); }'

bpftrace 连接操作块到写系统调用的返回探针(t:syscalls:sys_exit_write),然后使用过滤器丢掉代表错误代码的负值(/arg->ret > 0/)。

映射的键 comm 代表调用系统调用的进程名;内建函数 sum() 累计每个映射项或进程写的字节数;args 是一个 bpftrace 内建指令,用于访问追踪点的参数和返回值。如果执行成功,write 系统调用返回写的字节数,arg->ret 用于访问这个字节数。

进程的读取大小分布(柱状图):

bpftrace 支持创建柱状图。让我们分析一个创建进程的 read 大小分布的柱状图的例子:

$ sudo bpftrace -e 't:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'

柱状图是 BPF 映射,因此必须保存为一个映射(@),这个例子中映射键是 comm

这个例子使 bpftrace 给每个调用 read 系统调用的进程生成一个柱状图。要生成一个全局柱状图,直接保存 hist() 函数到 @(不使用任何键)。

程序终止时,bpftrace 自动打印出声明的柱状图。创建柱状图的基准值是通过 args->ret 获取到的读取的字节数。

追踪用户空间程序

你也可以通过 uprobes / uretprobes 和 USDT(用户级静态定义的追踪)追踪用户空间程序。下一个例子使用探测用户级函数结尾处的 uretprobe ,获取系统中运行的每个 bash 发出的命令行:

$ sudo bpftrace -e 'uretprobe:/bin/bash:readline { printf("readline: \"%s\"\n", str(retval)); }'

要列出可执行文件 bash 的所有可用 uprobes / uretprobes, 执行这个命令:

$ sudo bpftrace -l "uprobe:/bin/bash"

uprobe 指向用户级函数执行的开始,uretprobe 指向执行的结束(返回处);readline()/bin/bash 的一个函数,返回键入的命令行;retval 是被探测的指令的返回值,只能在 uretprobe 访问。

使用 uprobes 时,你可以用 arg0..argN 访问参数。需要调用 str()char * 指针转化成一个字符串。

自带脚本

bpftrace 软件包附带了许多有用的脚本,可以在 /usr/share/bpftrace/tools/ 目录找到。

这些脚本中,你可以找到:

  • killsnoop.bt——追踪 kill() 系统调用发出的信号
  • tcpconnect.bt——追踪所有的 TCP 网络连接
  • pidpersec.bt——统计每秒钟(通过 fork)创建的新进程
  • opensnoop.bt——追踪 open() 系统调用
  • bfsstat.bt——追踪一些 VFS 调用,按秒统计

你可以直接使用这些脚本,比如:

$ sudo /usr/share/bpftrace/tools/killsnoop.bt

你也可以在创建新的工具时参考这些脚本。

链接


via: https://fedoramagazine.org/trace-code-in-fedora-with-bpftrace/

作者:Augusto Caringi 选题:lujun9972 译者:YungeG 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过使用 pipx 隔离运行 Python 应用来避免版本冲突并提高安全性。

 title=

如果你使用 Python,你可能会安装很多 Python 应用。有些是你只想尝试的工具。还有一些是你每天都在使用的久经考验的应用,所以你把它们安装在你使用的每一台计算机上。这两种情况下,在虚拟环境中运行你的 Python 应用是非常有用的,这可以使它们以及它们的依赖关系相互分离,以避免版本冲突,并使它们与你系统的其它部分隔离,以提高安全性。

这就是 pipx 出场的地方。

大多数 Python 应用可以使用 pip 进行安装,它只安装 Python 包。然而,pipx 为你的 Python 应用创建并管理一个虚拟环境,并帮助你运行它们。

安装 pipx

pipx 主要是一个 RPM 包,你可以在任何 Fedora、RHEL 或 CentOS 机器上安装它:

$ sudo dnf install pipx

使用 pipx

我将通过 Cowsay 以及 Concentration 工具演示如何使用 pipx

安装软件包

安装完 pipx 后,你可以用以下方法安装 Python 包:

$ pipx install <python_package>

要安装 Cowsay 包:

$ pipx install cowsay                         ✔ │ 20:13:41 
 installed package cowsay 4.0, Python 3.9.5
 These apps are now globally available
    - cowsay
done! ✨ ? ✨

现在你可以在系统的任何地方运行 Cowsay,通过终端与你对话!

$ cowsay "I <3 OSDC"                         
  _________
| I <3 OSDC |
  =========
        \
        \
                ^__^
                (oo)\_______
                (__)\           )\/\
                ||----w |
                ||      ||

 title=

以特殊权限进行安装

不是所有的应用都像 Cowsay 一样简单。例如,Concentration 会与你系统中的许多其他组件交互,所以它需要特殊的权限。用以下方式安装它:

$ pipx install concentration                                      ✔ │ 10s │ │ 20:26:12 
 installed package concentration 1.1.5, Python 3.9.5
 These apps are now globally available
    - concentration
done! ✨ ? ✨

Concentration 通过阻止 distractors 文件中列出的特定网站来帮助你集中注意力。要做到这点,它需要以 sudo 或 root 权限运行。你可以用 OpenDoas 来做到这点,这是 doas 命令的一个版本,可以用特定的用户权限运行任何命令。要使用 doassudo 权限来运行 Concentration:

$ doas concentration improve                                 ✔ │ │ 20:26:54 
doas (sumantrom) password: 
Concentration is now improved :D!

如你所见,这个独立的应用能够改变系统中的一些东西。

列出已安装的应用

pipx list 命令显示所有用 pipx 安装的应用和它们的可执行路径:

$ pipx list                                                                       
venvs are in /home/sumantrom/.local/pipx/venvs
apps are exposed on your $PATH at /home/sumantrom/.local/bin
 package concentration 1.1.5, Python 3.9.5
    - concentration
 package cowsay 4.0, Python 3.9.5
    - cowsay

卸载应用

当你使用完毕后,知道如何卸载它们是很重要的。pipx 有一个非常简单的卸载命令:

$ pipx uninstall <package name>

或者你可以删除每个软件包:

$ pipx uninstall-all

pipx uninstall-all                           2 ✘ │ 20:13:35 
uninstalled cowsay! ✨ ? ✨
uninstalled concentration! ✨ ? ✨

尝试 pipx

pipx 是一个流行的 Python 应用的包管理器。它可以访问 PyPi 上的所有东西,但它也可以从包含有效 Python 包的本地目录、Python wheel 或网络位置安装应用。

如果你安装了大量的 Python 应用,可以试试 pipx


via: https://opensource.com/article/21/7/python-pipx

作者:Sumantro Mukherjee 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

用朴素贝叶斯分类器解决现实世界里的机器学习问题。

 title=

朴素贝叶斯 Naïve Bayes 是一种分类技术,它是许多分类器建模算法的基础。基于朴素贝叶斯的分类器是简单、快速和易用的机器学习技术之一,而且在现实世界的应用中很有效。

朴素贝叶斯是从 贝叶斯定理 Bayes' theorem 发展来的。贝叶斯定理由 18 世纪的统计学家 托马斯·贝叶斯 提出,它根据与一个事件相关联的其他条件来计算该事件发生的概率。比如,帕金森氏病 患者通常嗓音会发生变化,因此嗓音变化就是与预测帕金森氏病相关联的症状。贝叶斯定理提供了计算目标事件发生概率的方法,而朴素贝叶斯是对该方法的推广和简化。

解决一个现实世界里的问题

这篇文章展示了朴素贝叶斯分类器解决现实世界问题(相对于完整的商业级应用)的能力。我会假设你对机器学习有基本的了解,所以文章里会跳过一些与机器学习预测不大相关的步骤,比如 数据打乱 date shuffling 数据切片 data splitting 。如果你是机器学习方面的新手或者需要一个进修课程,请查看 《An introduction to machine learning today》 和 《Getting started with open source machine learning》。

朴素贝叶斯分类器是 有监督的 supervised 、属于 生成模型 generative 的、非线性的、属于 参数模型 parametric 的和 基于概率的 probabilistic

在这篇文章里,我会演示如何用朴素贝叶斯预测帕金森氏病。需要用到的数据集来自 UCI 机器学习库。这个数据集包含许多语音信号的指标,用于计算患帕金森氏病的可能性;在这个例子里我们将使用这些指标中的前 8 个:

  • MDVP:Fo(Hz):平均声带基频
  • MDVP:Fhi(Hz):最高声带基频
  • MDVP:Flo(Hz):最低声带基频
  • MDVP:Jitter(%)MDVP:Jitter(Abs)MDVP:RAPMDVP:PPQJitter:DDP:5 个衡量声带基频变化的指标

这个例子里用到的数据集,可以在我的 GitHub 仓库 里找到。数据集已经事先做了打乱和切片。

用 Python 实现机器学习

接下来我会用 Python 来解决这个问题。我用的软件是:

  • Python 3.8.2
  • Pandas 1.1.1
  • scikit-learn 0.22.2.post1

Python 有多个朴素贝叶斯分类器的实现,都是开源的,包括:

  • NLTK Naïve Bayes:基于标准的朴素贝叶斯算法,用于文本分类
  • NLTK Positive Naïve Bayes:NLTK Naïve Bayes 的变体,用于对只标注了一部分的训练集进行二分类
  • Scikit-learn Gaussian Naïve Bayes:提供了部分拟合方法来支持数据流或很大的数据集(LCTT 译注:它们可能无法一次性导入内存,用部分拟合可以动态地增加数据)
  • Scikit-learn Multinomial Naïve Bayes:针对离散型特征、实例计数、频率等作了优化
  • Scikit-learn Bernoulli Naïve Bayes:用于各个特征都是二元变量/布尔特征的情况

在这个例子里我将使用 sklearn Gaussian Naive Bayes

我的 Python 实现在 naive_bayes_parkinsons.py 里,如下所示:

import pandas as pd

# x_rows 是我们所使用的 8 个特征的列名
x_rows=['MDVP:Fo(Hz)','MDVP:Fhi(Hz)','MDVP:Flo(Hz)',
        'MDVP:Jitter(%)','MDVP:Jitter(Abs)','MDVP:RAP','MDVP:PPQ','Jitter:DDP']
y_rows=['status'] # y_rows 是类别的列名,若患病,值为 1,若不患病,值为 0

# 训练

# 读取训练数据
train_data = pd.read_csv('parkinsons/Data_Parkinsons_TRAIN.csv')
train_x = train_data[x_rows]
train_y = train_data[y_rows]
print("train_x:\n", train_x)
print("train_y:\n", train_y)

# 导入 sklearn Gaussian Naive Bayes,然后进行对训练数据进行拟合
from sklearn.naive_bayes import GaussianNB

gnb = GaussianNB()
gnb.fit(train_x, train_y)

# 对训练数据进行预测
predict_train = gnb.predict(train_x)
print('Prediction on train data:', predict_train)

# 在训练数据上的准确率
from sklearn.metrics import accuracy_score
accuracy_train = accuracy_score(train_y, predict_train)
print('Accuray score on train data:', accuracy_train)

# 测试

# 读取测试数据
test_data = pd.read_csv('parkinsons/Data_Parkinsons_TEST.csv')
test_x = test_data[x_rows]
test_y = test_data[y_rows]

# 对测试数据进行预测
predict_test = gnb.predict(test_x)
print('Prediction on test data:', predict_test)

# 在测试数据上的准确率
accuracy_test = accuracy_score(test_y, predict_test)
print('Accuray score on test data:', accuracy_train)

运行这个 Python 脚本:

$ python naive_bayes_parkinsons.py

train_x:
      MDVP:Fo(Hz)  MDVP:Fhi(Hz) ...  MDVP:RAP  MDVP:PPQ  Jitter:DDP
0        152.125       161.469  ...   0.00191   0.00226     0.00574
1        120.080       139.710  ...   0.00180   0.00220     0.00540
2        122.400       148.650  ...   0.00465   0.00696     0.01394
3        237.323       243.709  ...   0.00173   0.00159     0.00519
..           ...           ...           ...  ...       ...       ...        
155      138.190       203.522  ...   0.00406   0.00398     0.01218

[156 rows x 8 columns]

train_y:
      status
0         1
1         1
2         1
3         0
..      ...
155       1

[156 rows x 1 columns]

Prediction on train data: [1 1 1 0 ... 1]
Accuracy score on train data: 0.6666666666666666

Prediction on test data: [1 1 1 1 ... 1
 1 1]
Accuracy score on test data: 0.6666666666666666

在训练集和测试集上的准确率都是 67%。它的性能还可以进一步优化。你想尝试一下吗?你可以在下面的评论区给出你的方法。

背后原理

朴素贝叶斯分类器从贝叶斯定理发展来的。贝叶斯定理用于计算条件概率,或者说贝叶斯定理用于计算当与一个事件相关联的其他事件发生时,该事件发生的概率。简而言之,它解决了这个问题:如果我们已经知道事件 x 发生在事件 y 之前的概率,那么当事件 x 再次发生时,事件 y 发生的概率是多少? 贝叶斯定理用一个先验的预测值来逐渐逼近一个最终的 后验概率。贝叶斯定理有一个基本假设,就是所有的参数重要性相同(LCTT 译注:即相互独立)。

贝叶斯计算主要包括以下步骤:

  1. 计算总的先验概率:
    P(患病)P(患病) 和 P(不患病)P(不患病)
  2. 计算 8 种指标各自是某个值时的后验概率 (value1,...,value8 分别是 MDVP:Fo(Hz),...,Jitter:DDP 的取值):
    P(value1,\ldots,value8\ |\ 患病)P(value1,…,value8 ∣ 患病)
    P(value1,\ldots,value8\ |\ 不患病)P(value1,…,value8 ∣ 不患病)
  3. 将第 1 步和第 2 步的结果相乘,最终得到患病和不患病的后验概率:
    P(患病\ |\ value1,\ldots,value8) \propto P(患病) \times P(value1,\ldots,value8\ |\ 患病)P(患病 ∣ value1,…,value8)∝P(患病)×P(value1,…,value8 ∣ 患病)
    P(不患病\ |\ value1,\ldots,value8) \propto P(不患病) \times P(value1,\ldots,value8\ |\ 不患病)P(不患病 ∣ value1,…,value8)∝P(不患病)×P(value1,…,value8 ∣ 不患病)

上面第 2 步的计算非常复杂,朴素贝叶斯将它作了简化:

  1. 计算总的先验概率:
    P(患病)P(患病) 和 P(不患病)P(不患病)
  2. 对 8 种指标里的每个指标,计算其取某个值时的后验概率:
    P(value1\ |\ 患病),\ldots,P(value8\ |\ 患病)P(value1 ∣ 患病),…,P(value8 ∣ 患病)
    P(value1\ |\ 不患病),\ldots,P(value8\ |\ 不患病)P(value1 ∣ 不患病),…,P(value8 ∣ 不患病)
  3. 将第 1 步和第 2 步的结果相乘,最终得到患病和不患病的后验概率:
    P(患病\ |\ value1,\ldots,value8) \propto P(患病) \times P(value1\ |\ 患病) \times \ldots \times P(value8\ |\ 患病)P(患病 ∣ value1,…,value8)∝P(患病)×P(value1 ∣ 患病)×…×P(value8 ∣ 患病)
    P(不患病\ |\ value1,\ldots,value8) \propto P(不患病) \times P(value1\ |\ 不患病) \times \ldots \times P(value8\ |\ 不患病)P(不患病 ∣ value1,…,value8)∝P(不患病)×P(value1 ∣ 不患病)×…×P(value8 ∣ 不患病)

这只是一个很初步的解释,还有很多其他因素需要考虑,比如数据类型的差异,稀疏数据,数据可能有缺失值等。

超参数

朴素贝叶斯作为一个简单直接的算法,不需要超参数。然而,有的版本的朴素贝叶斯实现可能提供一些高级特性(比如超参数)。比如,GaussianNB 就有 2 个超参数:

  • priors:先验概率,可以事先指定,这样就不必让算法从数据中计算才能得出。
  • var\_smoothing:考虑数据的分布情况,当数据不满足标准的高斯分布时,这个超参数会发挥作用。

损失函数

为了坚持简单的原则,朴素贝叶斯使用 0-1 损失函数。如果预测结果与期望的输出相匹配,损失值为 0,否则为 1。

优缺点

优点:朴素贝叶斯是最简单、最快速的算法之一。
优点:在数据量较少时,用朴素贝叶斯仍可作出可靠的预测。
缺点:朴素贝叶斯的预测只是估计值,并不准确。它胜在速度而不是准确度。
缺点:朴素贝叶斯有一个基本假设,就是所有特征相互独立,但现实情况并不总是如此。

从本质上说,朴素贝叶斯是贝叶斯定理的推广。它是最简单最快速的机器学习算法之一,用来进行简单和快速的训练和预测。朴素贝叶斯提供了足够好、比较准确的预测。朴素贝叶斯假设预测特征之间是相互独立的。已经有许多朴素贝叶斯的开源的实现,它们的特性甚至超过了贝叶斯算法的实现。


via: https://opensource.com/article/21/1/machine-learning-python

作者:Girish Managoli 选题:lujun9972 译者:tanloong 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

借助终端上的 XML 工具包 XMLStarlet,你就是 XML 之星。

 title=

学习解析 XML 通常被认为是一件复杂的事情,但它不一定是这样。XML 是高度严格结构化的,所以也是相对来说可预测的。也有许多其他工具可以帮助你使这项工作易于管理。

我最喜欢的 XML 实用程序之一是 XMLStarlet,这是一个用于终端的 XML 工具包,借助这个 XML 工具包,你可以验证、解析、编辑、格式化和转换 XML 数据。XMLStarLet 是个相对较小的命令,但浏览 XML 却充满潜力,因此本文演示了如何使用它来查询 XML 数据。

安装

XMLStarLet 默认安装在 CentOS、Fedora,和许多其他现代 Linux 发行版上,所以你可以打开终端,输入 xmlstarlet 来访问它。如果 XMLStarLet 还没有被安装,你的操作系统则会为你安装它。

或者,你可以用包管理器安装 xmlstarlet

$ sudo dnf install xmlstarlet

在 macOS 上,可以使用 MacPortsHomebrew。在 Windows 上,可以使用 Chocolatey

如果都失败了,你可以从 Sourceforge 上的源代码 手动安装它。

用 XMLStarlet 解析 XML

有许多工具可以帮助解析和转换 XML 数据,包括允许你 编写自己的解析器 的软件库,和复杂的命令,如 fopxsltproc。不过有时你不需要处理 XML 数据;你只需要一个方便的方法从 XML 数据中来提取、更新或验证重要数据。对于随手的 XML 交互,我使用 xmlstarlet,这是常见的处理 XML任务的一个典型的“瑞士军刀”式应用。通过运行 --help 命令,你可以看到它提供哪些选项:

$ xmlstarlet --help
Usage: xmlstarlet [<options>] <command> [<cmd-options>]
where <command> is one of:
  ed    (or edit)      - Edit/Update XML document(s)
  sel   (or select)    - Select data or query XML document(s) (XPATH, etc)
  tr    (or transform) - Transform XML document(s) using XSLT
  val   (or validate)  - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)
  fo    (or format)    - Format XML document(s)
  el    (or elements)  - Display element structure of XML document
  c14n  (or canonic)   - XML canonicalization
  ls    (or list)      - List directory as XML
[...]

你可以通过在这些子命令的末尾附加 -help 来获得进一步的帮助:

$ xmlstarlet sel --help
  -Q or --quiet             - do not write anything to standard output.
  -C or --comp              - display generated XSLT
  -R or --root              - print root element &lt;xsl-select&gt;
  -T or --text              - output is text (default is XML)
  -I or --indent            - indent output
[...]

用 sel 命令选择数据

可以使用 xmlstarlet select(简称 sel)命令查看 XML 格式的数据。下面是一个简单的 XML 文档:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
  <os>
   <linux>
    <distribution>
      <name>Fedora</name>
      <release>7</release>
      <codename>Moonshine</codename>
      <spins>
        <name>Live</name>
        <name>Fedora</name>
        <name>Everything</name>
      </spins>
    </distribution>

    <distribution>
      <name>Fedora Core</name>
      <release>6</release>
      <codename>Zod</codename>
      <spins></spins>
    </distribution>
   </linux>
  </os>    
</xml>

在 XML 文件中查找数据时,你的第一个任务是关注要探索的节点。如果知道节点的路径,请使用 -value of 选项指定完整路径。你越早浏览 文档对象模型(DOM)树,就可以看到更多信息:

$ xmlstarlet select --template \
  --value-of /xml/os/linux/distribution \
  --nl myfile.xml
      Fedora
      7
      Moonshine
     
        Live
        Fedora
        Everything     
     
      Fedora Core
      6
      Zod

--nl 代表“新的一行”,它插入大量的空白,以确保在输入结果后,终端在新的一行显示。我已经删除了样本输出中的一些多余空间。

通过进一步深入 DOM 树来凝聚关注点:

$ xmlstarlet select --template \
  --value-of /xml/os/linux/distribution/name \
  --nl myfile.xml
Fedora
Fedora Core

条件选择

用于导航和解析 XML 的最强大工具之一被称为 XPath。它规范了 XML 搜索中使用的语法,并从 XML 库调用函数。XMLStarlet 能够解析 XPath 表达式,因此可以使用 XPath 函数来有条件的进行选择。XPath 具有丰富的函数,由 W3C 提供了详细文档,但我觉得 Mozilla 的 XPath 文档 更简洁。

可以使用方括号作为测试函数,将元素的内容与某个值进行比较。下面是对 <name> 元素的值的测试,它仅返回与特定匹配相关联的版本号。

想象一下,示例 XML 文件包含以 1 开头的所有 Fedora 版本。要查看与旧名称 “Fedora Core” 关联的所有版本号(该项目从版本 7 开始删除了名称中的 “Core”),请执行以下操作:

$ xmlstarlet sel --template \
  --value-of '/xml/os/linux/distribution[name = "Fedora Core"]/release' \
  --nl myfile.xml
6
5
4
3
2
1

通过将路径的 --value-of 更改为 /xml/os/linux/distribution[name=“Fedora Core”]/codename,你便可以查看这些版本的所有代号。

匹配路径和获取目标值

将 XML 标记视为节点的一个好处是,一旦找到节点,就可以将其视为当前的数据的“目录”。它不是一个真正的目录,至少不是文件系统意义上的目录,但它是一个可以查询的数据集合。为了帮助你将目标和“里面”的数据分开,XMLStarlet 把你试图用 --match 选项匹配的内容和用 --value-of 选项匹配的数据值进行了区分。

假设你知道 <spin> 节点包含几个元素。这就是你的目标节点。一旦到了这里,就可以使用 --value-of 指定想要哪个元素的值。要查看所有元素,可以使用点(.)来代表当前位置:

$ xmlstarlet sel --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '.' --nl myfile.xml \
Live
Fedora
Everything

与浏览 DOM 一样,可以使用 XPath 表达式来限制返回数据的范围。在本例中,我使用 last() 函数来检索 spin 节点中的最后一个元素:

$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '*[last()]' --nl myfile.xml
Everything

在本例中,我使用 position() 函数选择 spin 节点中的特定元素:

$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '*[position() = 2]' --nl myfile.xml
Fedora

--match--value 选项可以重叠,因此如何将它们一起使用取决于你自己。对于示例 XML,这两个表达式执行的是相同的操作:

$ xmlstarlet select  --template \
  --match '/xml/os/linux/distribution/spin' \
  --value-of '.' \
  --nl myfile.xml
Live
Fedora
Everything     

$ xmlstarlet select --template \
  --match '/xml/os/linux/distribution' \
  --value-of 'spin' \
  --nl myfile.xml
Live
Fedora
Everything

熟悉 XML

XML 有时看起来过于冗长和笨拙,但为与之交互和构建的工具却总是让我吃惊。如果你想要好好使用 XML,那么 XMLStarlet 可能是一个很好的切入点。下次要打开 XML 文件查看其结构化数据时,请尝试使用 XMLStarlet,看看是否可以查询这些数据。当你对 XML 越熟悉时,它就越能作为一种健壮灵活的数据格式而为你服务。


via: https://opensource.com/article/21/7/parse-xml-linux

作者:Seth Kenlon 选题:lujun9972 译者:zepoch 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出