コーパス言語学実践

コーパス言語学実践
2006年度2学期
第9回
本日の内容
• これまでと同様の作業
– プログラムで処理するケースの紹介
2
perlのプログラム(1)
• 述べ語数で各品詞の語数を計算する
wc_nobe.pl
perl wc_nobe.pl < gingatetsudono_yoru08.txt
3
perlのプログラム(2)
• 異なり語数で各品詞の語数を計算する
wc_kotonari.pl
perl wc_kotonari.pl < gingatetsudono_yoru08.txt
4
プログラムを理解するヒント(1)
• split関数
• 連想配列
• foreach という構文
5
split関数補足(1)
• split関数と配列の関係
split関数は第1引数で指定した区切り子(文
字列)で,第2引数で指定した文字列の中身
を区切り,その結果を配列に代入する
@a = split(/☆/, $line);
6
split関数の補足(2)
• 例:
@a = split(/☆/, $line);
$line=”サラダ☆380☆レタス,ツナ,ブロッコリー,
ドレッシング,たまねぎ☆260”;
だとすると
7
split関数の補足(3)
• 例:
• @a = split(/☆/, ”サラダ☆380☆レタス,ツナ,ブ
ロッコリー,ドレッシング,たまねぎ☆260”);
こんな感じで,
区切り子は「☆」ということになります.
8
split関数の補足(4)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
split関数では,指定された文字列の中に
区切り文字があるかどうか先頭から探します.
9
split関数の補足(5)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
ありました!
10
split関数の補足(6)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
ここまでの値を
配列に入れます
0
@a
サラダ
11
split関数の補足(7)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
探索を続けます
0
@a
サラダ
12
split関数の補足(8)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
見つかりました!
0
@a
サラダ
13
split関数の補足(9)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
ここまでを
代入します
0
@a
サラダ
1
380
14
split関数の補足(10)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
続けます.
0
@a
サラダ
1
380
15
split関数の補足(11)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
見つかりました.
0
@a
サラダ
1
380
16
split関数の補足(12)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
@a
ここまでを
代入します.
0 サラダ
1
380
2
レタス,ツナ,ブロッコ
リー,ドレッシング,
たまねぎ
17
split関数の補足(13)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
@a
続けます.
0 サラダ
1
380
2
レタス,ツナ,ブロッコ
リー,ドレッシング,
たまねぎ
18
split関数の補足(14)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
@a
文字列の最後まで
きました.
0 サラダ
1
380
2
レタス,ツナ,ブロッコ
リー,ドレッシング,
たまねぎ
19
split関数の補足(15)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
@a
ここまでを
代入します.
0 サラダ
1
380
2
レタス,ツナ,ブロッコ
リー,ドレッシング,
たまねぎ
3
260
20
split関数の補足(16)
• split関数では
@a = split(/☆/, $line);
サラダ☆380☆レタス,ツナ,ブロッコリー,ドレッシング,
たまねぎ☆260
@a
0 サラダ
これでsplit関数の
作業が完了です
1
380
2
レタス,ツナ,ブロッコ
リー,ドレッシング,
たまねぎ
3
260
21
split関数の補足(17)
while(<>) {
chomp;
@a = split(/\t/, $_);
print(“$a[0] - $a[1] - $a[2] - $a[3]\n”);
}
exit;
splittest.pl として保存
perl splittest.pl < gingatetsudono_yoru08.txt
22
連想配列(1)
• perlには,連想配列と呼ばれる配列がある.
• 特徴:添え字に文字列が使える
– 連想配列には%に続けて名前をつける.
例:%array という連想配列
3000
2000
1500
1000
要素
(中身)
上松
松
竹
梅
添え字
$array{“上松”}=3000; $array{“竹”}=1500
(インデックス)
$array{“松”}=2000;
$array{“梅”}=1000
;
23
;
連想配列(2)
• 連想配列の使い方(参照)
– 各要素を個別に参照
print “上松の中身は” . $a{“上松”} . “\n”;
print “松の中身は” . $a{“松”} . “\n”;
添え字 中身
print “竹の中身は” . $a{“竹”} . “\n”;
print “梅の中身は” . $a{“梅”} . “\n”; 上松 3000
松 2000
%a
竹
1500
梅
1000
24
連想配列(3)
• 練習 renso01.plをダウンロードして実行
y:\corpus> perl renso01.pl
連想配列 a に値を代入.
値の出力がされているはず.
を確かめる.
25
連想配列(4)
• wc_nobe.plの中の,
@a = split(/\t/, $_);
$count{$a[3]}++; ←ここが連想配列
– split関数で タブで区切った,すると$a[?]に値が入る
– $a[3]には,品詞が入っている.
– 品詞を 添え字 にして $count{品詞} という連想配列
「++」は1つ数字を足すという意味
26
foreachという構文(1)
• 繰り返し構文として foreach というのがある
– wc_nobe.pl では
foreach $key (sort keys %count) {
printf ("%s\t%d\n", $key, $count{$key});
}
連想配列%countの添え字を$keyに入れる
添え字はソートして順番に取り出す
27
foreachという構文(2)
– wc_kotonari.pl では
foreach $key (keys %count0) {
@b = split(/ /, $key);
$count{$b[0]}++;
}
というのもある.ソートしないで取り出す.
28
foreachという構文(3)
while($_=<>) {
chomp($_);
@a = split(/\t/, $_);
$soeji=$a[3] . " " . $a[0] . " " . $a[1] . " " . $a[2];
$count0{$soeji}++;
}
foreach $key (keys %count0) {
@b = split(/ /, $key);
$count{$b[0]}++;
}
foreach $key (sort keys %count) {
printf ("%s\t%d\n", $key, $count{$key});
}
exit;
29