computer:perl:species_la-verify
植物拉丁名校验species_la-verify.pl
拉丁名
植物物种采用拉丁文的双名命名法,通常都很长。手工输入难免出错,一般都是错误一两个字母的情形,肉眼很难发现。如果我们有一个事先校验过的名录,只需将输入的拉丁名与名录中的名字做个相似性比较,就很容易发现并纠正此类小错误,从而可以避免后续分析处理时可能导致巨大误差的潜在风险。
这里说的物种拉丁名,指拉丁名通用代码,不包含命名人等部分,通常由属名和种加词构成,如果是变种、亚种等,则包括相应的变种加词、亚种加词等。如:
- Abelia macrotera
- Abelmoschus manihot var. manihot
- Acer caesium subsp. giraldii
- Angelica decursiva form. albiflora
程序功能
程序流程:
- 将拉丁名与名录对照,如果命中,则认为拉丁名是正确的,输出该拉丁名,以及标志“FINE”;
- 如果找不到,则在名录中进行相似性搜索,找出与该拉丁名相似率在90%以上的所有名称,与该拉丁名一起列出,供用户选择,缺省为该拉丁名:
- 如果用户仍旧选择该拉丁名,则输出名称和标志“NEW”;
- 如果用户选择了名录中的名称,则输出名称和标志“MOD”。
- 如果相似搜索失败,则直接输出名称和标志“NEW”。
这里对不同的结果设置了一些标志,供后续处理。比如标志为“NEW“的名称,如果确认无误,则可以将其添加到名录里,这样名录会不断增长,可用性和准确性也随之提高。
String::Similarity模块
相似性比较用到String::Similarity模块,需要事先安装,详细信息可访问CPAN。
如果系统是CentOS,并且启用了RPMforge源,则可以直接YUM安装:
yum install perl-String-Similarity
如果从源代码安装,方法如下:
gunzip String-Similarity-1.04.tar.gz tar xvf String-Similarity-1.04.tar cd String-Similarity-1.04/ perl Makefile.PL make make test make install
代码简述
使用String::Similarity模块:
use String::Similarity;
参数分别为名录文件和要校验的名称列表文件:
my $conf_file = shift; my $la_file = shift;
读入名录,放到列表变量里:
my @conf; open(IN, $conf_file); chomp(@conf = <IN>); close IN;
读入要校验的名称列表,同时放到列表变量和哈希变量里,这样的相同的名字都对应同一个哈希键(key),避免后续的重复校验:
my @all_list; my %la_names; open(IN, $la_file); while (<IN>) { chomp; push @all_list, $_; $la_names{$_} = ""; } close IN;
对每个哈希键(拉丁名称)依次进行处理。如果键为空,则设定标志“NONE”:
foreach my $value (keys %la_names) { if ($value eq "") { $la_names{$value} = "NONE\t" . $value; next; }
如果键存在于名录中,则设定标志“FINE”:
my @temp_list = grep { $_ eq $value } @conf; if (@temp_list) { $la_names{$value} = "FINE\t" . $value; next; }
进行相似性搜索:
@temp_list = grep { similarity($_, $value, 0.9) >= 0.9 } @conf;
如果搜不到,则直接设定标志“NEW”:
if (!@temp_list) { $la_names{$value} = "NEW\t" . $value; next; }
列出所有结果供用户选择:
my $choose; print STDERR "[$value] Similar Records:\n"; print STDERR "0): $value\n"; my $i = 1; foreach (@temp_list) { print STDERR "$i): $_\n"; $i++; } while (1) { print STDERR "Please choose(Ctrl+C to Abort)[0]: "; chomp($choose = <STDIN>); last if ($choose >= 0 && $choose <= @temp_list); }
根据选择结果设定相应标志:
if ($choose) { $la_names{$value} = "MOD\t" . $temp_list[$choose - 1]; } else { $la_names{$value} = "NEW\t" . $value; }
处理完所有键后,根据哈希中的设置输出所有名称的校验结果:
foreach (@all_list) { print STDOUT $la_names{$_} . "\r\n"; } exit 0;
完毕。
computer/perl/species_la-verify.txt · 最后更改: 2014/11/01 02:02 由 127.0.0.1