gnu octave
数据科学是跨越编程语言的知识领域。 一些以解决该领域的问题而闻名,而其他则鲜为人知。 本文将帮助您熟悉使用某些流行语言进行数据科学的过程。
选择Python和GNU Octave进行数据科学
每隔一段时间,我就会尝试学习一种新的编程语言。 为什么? 它主要是无聊与旧的方式以及对新方式的好奇心的结合。 当我开始编程时,我所知道的唯一的语言是C。在那些年里,生活是艰难而危险的,因为我不得不手动分配内存,管理指针并记住释放内存。
然后一位朋友建议我尝试使用Python,生活变得轻松多了。 程序变慢了很多,但我不必因编写分析软件而受苦。 但是,我很快意识到,每种语言都比其他语言更适合某些应用程序。 后来我学习了其他一些语言,每种语言都带来了一些新的启示。 发现新的编程样式使我可以向其他语言回传一些解决方案,并且一切都变得更加有趣。
所有程序都应在命令行上运行,而不是通过图形用户界面 (GUI)运行。 完整的示例可在polyglot_fit信息库中找到 。
编程任务
您将在本系列中编写的程序:
- 从CSV文件读取数据
- 用直线内插数据(即f(x)= m⋅x + q )
- 将结果绘制到图像文件
这是许多数据科学家遇到的普遍情况。 示例数据是Anscombe四重奏的第一组,如下表所示。 这是一组人工构造的数据,当拟合直线时可以提供相同的结果,但是它们的曲线非常不同。 数据文件是一个文本文件,其中的制表符用作列分隔符,几行作为标题。 该任务将仅使用第一组(即前两列)。
一世 | II | 三级 | IV | ||||
---|---|---|---|---|---|---|---|
x | ÿ | X | ÿ | X | ÿ | X | ÿ |
10.0 | 8.04 | 10.0 | 9.14 | 10.0 | 7.46 | 8.0 | 6.58 |
8.0 | 6.95 | 8.0 | 8.14 | 8.0 | 6.77 | 8.0 | 5.76 |
13.0 | 7.58 | 13.0 | 8.74 | 13.0 | 12.74 | 8.0 | 7.71 |
9.0 | 8.81 | 9.0 | 8.77 | 9.0 | 7.11 | 8.0 | 8.84 |
11.0 | 8.33 | 11.0 | 9.26 | 11.0 | 7.81 | 8.0 | 8.47 |
14.0 | 9.96 | 14.0 | 8.10 | 14.0 | 8.84 | 8.0 | 7.04 |
6.0 | 7.24 | 6.0 | 6.13 | 6.0 | 6.08 | 8.0 | 5.25 |
4.0 | 4.26 | 4.0 | 3.10 | 4.0 | 5.39 | 19.0 | 12.50 |
12.0 | 10.84 | 12.0 | 9.13 | 12.0 | 8.15 | 8.0 | 5.56 |
7.0 | 4.82 | 7.0 | 7.26 | 7.0 | 6.42 | 8.0 | 7.91 |
5.0 | 5.68 | 5.0 | 4.74 | 5.0 | 5.73 | 8.0 | 6.89 |
Python方式
Python是一种通用编程语言,是当今使用最广泛的语言之一(从TIOBE索引 , RedMonk编程语言排名 , 编程语言索引的流行度 ,GitHub的八进制状态和其他来源的发现中可以证明 ) 。 它是一种解释语言 ; 因此,源代码由执行指令的程序读取和评估。 它具有一个全面的标准库 ,使用起来通常非常令人愉悦(我没有对最后一条语句进行引用;这只是我的拙见)。
安装
要使用Python开发,您需要解释器和一些库。 最低要求是:
- NumPy ,方便进行数组和矩阵操作
- SciPy的用于科学计算
- Matplotlib用于绘图
在Fedora中安装它们很容易:
sudo dnf install python3 python3-numpy python3-scipy python3-matplotlib
注释码
在Python中, 注释是通过在行首添加#来实现的,其余行将被解释器丢弃:
# This is a comment ignored by the interpreter.
fitting_python.py示例使用注释在源代码中插入许可信息,第一行是特殊注释 ,使注释可以在命令行上执行:
#! /usr/bin/env python3
该行通知命令行解释器该脚本需要由程序python3执行。
所需的库
可以使用Python将库和模块作为具有库的所有功能和成员的对象(如示例中的第一行)导入。 有一个方便的选项,可以使用as规范使用自定义标签重命名它们:
import numpy
as np
from scipy import stats
import matplotlib.pyplot
as plt
您可能还决定仅导入一个子模块(如第二和第三行所示)。 语法具有两个(或多或少)等效的选项: import module.submodule和from module import submodule 。
定义变量
首次给变量赋值时声明了Python的变量:
input_file_name
=
"anscombe.csv"
delimiter
=
" \t "
skip_header
=
3
column_x
=
0
column_y
=
1
变量类型由分配给变量的值推断。 除非它们在模块中声明并且只能读取,否则没有常量值的变量。 习惯上,不应修改的变量应以大写形式命名。
打印输出
通过命令行运行程序意味着输出仅打印在终端上。 Python具有print()函数,默认情况下,该函数打印其参数并在输出的末尾添加换行符:
print ( "#### Anscombe's first set with Python ####" )
可以将print()函数与Python中字符串类的格式化功能结合在一起。 字符串具有format方法,可用于将某些格式化的文本添加到字符串本身。 例如,可以添加格式化的浮点数,例如:
print ( "Slope: {:f}" . format ( slope ) )
读取数据
使用NumPy和函数genfromtxt()可以很容易地读取CSV文件,该函数会生成一个NumPy数组 :
data = np. genfromtxt ( input_file_name , delimiter = delimiter , skip_header = skip_header )
在Python中,函数可以具有可变数量的参数,您可以通过指定所需的参数来传递子集。 数组是非常强大的类似矩阵的对象,可以很容易地切成更小的数组:
x
= data
[ :
, column_x
]
y
= data
[ :
, column_y
]
冒号选择整个范围,它们也可以用于选择一个子范围。 例如,要选择数组的前两行,应使用:
first_two_rows = data [ 0 : 1 , : ]
拟合数据
SciPy提供了方便的数据拟合功能,例如linregress()函数。 此函数提供了一些与拟合相关的重要值,例如两个数据集的斜率,截距和相关系数:
slope
, intercept
, r_value
, p_value
, std_err
= stats.
linregress
( x
, y
)
print
(
"Slope: {:f}" .
format
( slope
)
)
print
(
"Intercept: {:f}" .
format
( intercept
)
)
print
(
"Correlation coefficient: {:f}" .
format
( r_value
)
)
由于linregress()提供了几条信息,因此可以将结果同时保存到多个变量中。
绘图
Matplotlib库仅绘制数据点; 因此,您应该定义要绘制的点。 x和y数组已经定义,因此您可以直接绘制它们,但是您还需要代表直线的数据点。
fit_x = np. linspace ( x. min ( ) - 1 , x. max ( ) + 1 , 100 )
linspace()函数可以方便地在两个值之间生成一组相等间隔的值。 利用强大的NumPy数组可以很容易地计算出纵坐标,这些数组可以在公式中使用,就好像它们是普通的数字变量一样:
fit_y = slope * fit_x + intercept
该公式逐个元素应用于数组; 因此,结果在初始数组中具有相同数量的条目。
要创建绘图,首先,定义一个将包含所有图形的图形对象 :
fig_width
=
7
#inch
fig_height
= fig_width /
16 *
9
#inch
fig_dpi
=
100
fig
= plt.
figure
( figsize
=
( fig_width
, fig_height
)
, dpi
= fig_dpi
)
在一个图形上可以绘制几个图。 在Matplotlib中,这些图称为轴 。 本示例定义了一个单轴对象来绘制数据点:
ax
= fig.
add_subplot
(
111
)
ax.
plot
( fit_x
, fit_y
, label
=
"Fit"
, linestyle
=
'-'
)
ax.
plot
( x
, y
, label
=
"Data"
, marker
=
'.'
, linestyle
=
''
)
ax.
legend
(
)
ax.
set_xlim
(
min
( x
) -
1
,
max
( x
) +
1
)
ax.
set_ylim
(
min
( y
) -
1
,
max
( y
) +
1
)
ax.
set_xlabel
(
'x'
)
ax.
set_ylabel
(
'y'
)
使用以下命令将图形保存到PNG图像文件中:
fig. savefig ( 'fit_python.png' )
如果要显示(而不是保存)绘图,请调用:
plt. show ( )
本示例引用了绘图部分中使用的所有对象:它定义了对象fig和对象ax 。 这种技术性不是必需的,因为plt对象可以直接用于绘制数据集。 Matplotlib教程显示了一个界面,例如:
plt. plot ( fit_x , fit_y )
坦白地说,我不喜欢这种方法,因为它隐藏了各种对象之间发生的非平凡的交互。 不幸的是,有时官方示例有些混乱,因为它们倾向于使用不同的方法。 在这个简单的示例中,不必引用图形对象,但是在更复杂的对象中(例如,在GUI中嵌入图时),它就变得很重要。
结果
命令行上的输出为:
#### Anscombe's first set with Python ####
Slope:
0.500091
Intercept:
3.000091
Correlation coefficient:
0.816421
这是Matplotlib生成的图像。
![用Python获得的数据集的图和拟合 Plot and fit of the dataset obtained with Python](https://i-blog.csdnimg.cn/blog_migrate/1c0160d5901701797cc2f60993ad3c23.png)
GNU Octave方式
GNU Octave语言主要用于数值计算。 它提供用于处理向量和矩阵的简单语法,并具有一些强大的绘图功能。 它是像Python这样的解释型语言。 由于Octave的语法大部分与MATLAB 兼容 ,因此通常被描述为MATLAB的免费替代品。 在最流行的编程语言中,Octave并未列出,但在MATLAB中却是这样。 MATLAB早于NumPy,我感到它是受前者启发的。 在浏览示例时,您会看到类比。
安装
fitting_octave.m示例仅需要基本的Octave软件包,因此在Fedora中的安装相当简单:
sudo dnf install octave
注释码
在Octave中,可以在代码中添加带有百分号( % )的注释,如果不需要MATLAB兼容性,也可以使用# 。 使用#选项可以让您编写与Python示例相同的特殊注释行,以直接在命令行上执行脚本。
必要的图书馆
此示例中使用的所有内容都包含在基本软件包中,因此您无需加载任何新库。 如果需要库,则语法为pkg load module 。 此命令将模块的功能添加到可用功能列表中。 在这方面,Python具有更大的灵活性。
定义变量
变量的定义语法与Python几乎相同:
input_file_name
=
"anscombe.csv"
;
delimiter
=
" \t "
;
skip_header
=
3
;
column_x
=
1
;
column_y
=
2
;
请注意,该行的末尾有分号; 这不是必需的,但是它抑制了行结果的输出。 如果没有分号,解释器将打印表达式的结果:
octave:
1
> input_file_name
=
"anscombe.csv"
input_file_name
= anscombe.
csv
octave:
2
> sqrt
(
2
)
ans
=
1.4142
打印输出
强大的函数printf()用于在终端上打印。 与Python不同, printf()函数不会在打印字符串的末尾自动添加换行符,因此您必须添加它。 第一个参数是一个字符串,可以包含要传递给函数的其他参数的格式信息,例如:
printf ( "Slope: %f \n " , slope ) ;
在Python中,格式化内置于字符串本身,但在Octave中,它特定于printf()函数。
读取数据
dlmread()函数可以读取类似于CSV文件的文本文件:
data = dlmread ( input_file_name , delimiter , skip_header , 0 ) ;
结果是一个矩阵对象,它是Octave中的基本数据类型之一。 可以使用类似于Python的语法对矩阵进行切片:
x
= data
( :
, column_x
)
;
y
= data
( :
, column_y
)
;
根本区别在于索引从1开始而不是0。 因此,在示例中, x列是第一列。
拟合数据
要将数据拟合为直线,可以使用polyfit()函数。 它使用多项式来拟合输入数据,因此您只需要使用一阶多项式:
p
= polyfit
( x
, y
,
1
)
;
slope
= p
(
1
)
;
intercept
= p
(
2
)
;
结果是一个具有多项式系数的矩阵; 因此,它选择前两个索引。 要确定相关系数,请使用corr()函数:
r_value = corr ( x , y ) ;
最后,使用printf()函数打印结果:
printf
(
"Slope: %f \n "
, slope
)
;
printf
(
"Intercept: %f \n "
, intercept
)
;
printf
(
"Correlation coefficient: %f \n "
, r_value
)
;
绘图
像Matplotlib示例一样,您首先需要创建一个表示拟合线的数据集:
fit_x
= linspace
(
min
( x
) -
1
,
max
( x
) +
1
,
100
)
;
fit_y
= slope * fit_x + intercept
;
与NumPy的类比在这里也很明显,因为它使用的linspace()函数的行为就像Python的等效版本。
同样,与Matplotlib一样,首先创建一个图形对象,然后创建一个轴对象以保存绘图:
fig_width
=
7
; %inch
fig_height
= fig_width /
16 *
9
; %inch
fig_dpi
=
100
;
fig
= figure
(
"units"
,
"inches"
,
"position"
,
[
1
,
1
, fig_width
, fig_height
]
)
;
ax
= axes
(
"parent"
, fig
)
;
set
( ax
,
"fontsize"
,
14
)
;
set
( ax
,
"linewidth"
,
2
)
;
要设置轴对象的属性,请使用set()函数。 但是,该接口非常令人困惑,因为该函数希望使用逗号分隔的属性和值对列表。 这些对只是代表属性名称的字符串和代表该属性值的第二个对象的连续。 还有其他功能可以设置各种属性:
xlim
( ax
,
[
min
( x
) -
1
,
max
( x
) +
1
]
)
;
ylim
( ax
,
[
min
( y
) -
1
,
max
( y
) +
1
]
)
;
xlabel
( ax
,
'x'
)
;
ylabel
( ax
,
'y'
)
;
绘图是通过plot()函数实现的。 默认行为是每次调用都会重置轴,因此您需要使用功能hold() 。
hold
( ax
,
"on"
)
;
plot
( ax
, fit_x
, fit_y
,
"marker"
,
"none"
,
"linestyle"
,
"-"
,
"linewidth"
,
2
)
;
plot
( ax
, x
, y
,
"marker"
,
"."
,
"markersize"
,
20
,
"linestyle"
,
"none"
)
;
hold
( ax
,
"off"
)
;
此外,还可以在plot()函数中添加属性和值对。 图例必须单独创建,并且标签应手动声明:
lg
= legend
( ax
,
"Fit"
,
"Data"
)
;
set
( lg
,
"location"
,
"northwest"
)
;
最后,将输出保存到PNG图像:
image_size
= sprintf
(
"-S%f,%f"
, fig_width * fig_dpi
, fig_height * fig_dpi
)
;
image_resolution
= sprintf
(
"-r%f,%f"
, fig_dpi
)
;
print
( fig
,
'fit_octave.png'
,
'-dpng'
,
image_size
,
image_resolution
)
;
在这种情况下,令人困惑的是,这些选项作为带有属性名称和值的单个字符串传递。 由于在Octave中字符串不具有Python的格式化功能,因此必须使用sprintf()函数。 它的行为与printf()函数类似,但是不会打印其结果,而是以字符串形式返回。
在此示例中,就像在Python中一样,引用了图形对象以保持它们的交互作用明显。 如果Python在这方面的文档有些混乱,那么Octave的文档会更糟。 我发现的大多数示例都不关心引用对象。 取而代之的是,它们依赖于以下事实:绘图命令作用于当前活动图形。 全局根图形对象跟踪现有图形和轴。
结果
命令行上的结果输出为:
#### Anscombe's first set with Octave ####
Slope:
0.500091
Intercept:
3.000091
Correlation coefficient:
0.816421
这显示了使用Octave生成的结果图像。
![用Octave获得的数据集的图和拟合 Plot and fit of the dataset obtained with Octave](https://i-blog.csdnimg.cn/blog_migrate/a1b39b797ac05bc4aa2fd73e740690b1.png)
接下来
Python和GNU Octave可以绘制相同的信息,尽管它们到达那里的方式不同。 如果您想探索其他语言来完成类似的任务,强烈建议您查看Rosetta Code 。 看到如何解决多种语言中的相同问题,这是一个奇妙的资源。
您喜欢用哪种语言绘制数据? 在评论区分享你的观点。
翻译自: https://opensource.com/article/20/2/python-gnu-octave-data-science
gnu octave