【问题标题】:Perl script to convert a collection of text into vector representation将文本集合转换为矢量表示的 Perl 脚本
【发布时间】:2013-05-23 04:20:09
【问题描述】:

输入文件为UTF8编码,每一行结构如下:

    C\tTEXT\n

其中 C 是一类文档(几个字符),\t 是一个制表符,TEXT 是一个字符序列,\n 是一个换行符。

从每个 TEXT 中删除 HTML 标记和类似的标记、实体、非字母字符,并将每个文本转换为单词序列,其中顺序并不重要。

然后从每个 TEXT 中创建向量,其中向量的各个元素(属性)对应于文本集合中的单词,向量中的值将取决于单词在 TEXT 中的出现。这些值可以有两种:

A - number of occurrences of words (1 or 0) 
B - number of occurrences    of words (0 or more)

最后一个值向量是文档的类。

如有必要,可以从所有文本中删除一起具有低频率的单词(例如,一个)。

字符数少的单词也可以删除。

Example input file:
CLASS    One Class One
CLASS    One Two
2CLASS   two three
CLAS12   three

示例输出文件:

这些是脚本的参数(最小字长=1,最少出现的字=1,A)

输出:

      one two three
CLASS  2   0    0 
CLASS  1   1    0
2CLASS 0   1    1
CLAS12 0   0    1

我当前的代码:

请帮帮我。

#!/usr/bin/perl

use strict;
use encoding 'UTF-8';
use Data::Dumper;

my %vector = ();
my @vectors = ();
my ($string,$word);

open SOURCE, "<:encoding(UTF-8)", "source.txt" or die "File does not exist $!\n";

my($class,$hodnota);
while (my $line = <SOURCE>) {
  if($line=~ /^(\w+)\t(.+)\n/){  
    $string =$2; $class = $1;
    $string=~ s/[^a-zA-Z ]//g; 

      for $word ( split " +", $string )
      {
        $vector{$word}++;
      }

      $vector{"class"} = $class;
      push(@vectors, %vector)
   }

}          
    close S;

print Dumper( \@vectors );

【问题讨论】:

    标签: perl


    【解决方案1】:

    我建议如下:

    chomp($line);
    if ($line =~ /^(\w+)\t(.+)/){
        my $vector = {};
        my ($class, $string) = ($1, $2);
        for my $word (split /[^a-zA-Z]/, $string) {
            next if length($word) < $some_treshold; # $word is too short
            my $word_lc = lc($word);
            $vector{$word_lc}++;
            $all_words{$word_lc} = 1; # this has to be initialized before main loop, as $all_words = {};
        }
        $vector{"class"} = $class; # hopefully, no words will be "class"
        push(@vectors, %vector)
    }
    

    完成后,keys %$all_words 可以找到所有使用过的单词。希望我正确理解了您的需求。

    【讨论】:

      【解决方案2】:
      use strict; 
      use warnings;
      use Data::Dumper;
      
      open my $in_data, shift(@ARGV);
      my @array_of_hashes_of_hashes=(); 
      #used array of hashes_of_hashes because you treated two instances of CLASS differently
      #if they could be treated the same, a simple hash of hashes would work fine.
      
      while (<$in_data>)
      {  
          if ($_ =~ /^(\w+)\t(.+)\n/)
          {   
              my %temp_hash=();
              my @values=split(/ /,$2);
      
              foreach (@values)
              {
                  $temp_hash{lc($_)}+=1; #so that one and One map to the same key
              }
      
              push @array_of_hashes_of_hashes, {$1 => \%temp_hash};
          }
      }
      
      print Dumper \@array_of_hashes_of_hashes; #just to show you what it looks like
      

      我注意到您没有从CLASS One Class One 打印Class 的值,所以如果您想在打印所有内容时过滤掉它。

      【讨论】:

        猜你喜欢
        • 2019-01-01
        • 1970-01-01
        • 2013-06-07
        • 2019-06-23
        • 2013-12-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多