すこしラズベリーパイで遊んでみた。
以前にダウンロードしたことがあった、Wikipediaのデータを使って
なにかできないかと思い、
巨大なWikipediaデータからタイトルとそのよみがな、概要だけを抽出して、データベース化。
それをラズベリーパイに覚えてもらって、「しりとり」でもやってみようと思う。
Wikipediaのデータはここにあって
http://dumps.wikimedia.org/jawiki/latest/
以下のURLに説明があった。
http://www.mwsoft.jp/programming/munou/wikipedia_data_list.html
入手したのは「jawiki-latest-abstract.xml」というもので、
タイトルや概要が記載れている1.5GB程度のファイル。
xml形式になっており、ちょっと困った。
xml2csv的なものはいろいろありそうだけど、phpの勉強を兼ねて自作。
(その他に、いくつかフィルタしたいこともあったので)
先ほどのファイルはこんな感じ
<title>Wikipedia: 言語</title>
<url>http://ja.wikipedia.org/wiki/%E8%A8%80%E8%AA%9E</url>
<abstract>言語(げんご)とは、コミュニケーションのための記号の体系である。</abstract>
<links> …省略
<url>http://ja.wikipedia.org/wiki/%E8%A8%80%E8%AA%9E</url>
<abstract>言語(げんご)とは、コミュニケーションのための記号の体系である。</abstract>
<links> …省略
これの、<title>のWikipedia:以降〜</title>までを名称として、
<abstract>内を概要とした。
よみがなは、以下のルールで生成した。
1.タイトルがすべてひらがな→タイトルをよみがな
2.タイトルがすべてカタカナ→ひらがなに変換してよみがなとする
3.アブストラクトにタイトル(説明) があれば、説明をひらがなにしてみる
3−1.そのさい、スペースや-・などの区切り文字があったら、そこまでで切り取る
そのほか「〜の一覧」などのまとめページは除外した。
全容がこれ
<>
<?php mb_language('Japanese'); mb_internal_encoding('UTF-8'); mb_regex_encoding("UTF-8"); //タイトル $title_start_string="Wikipedia: "; $title_start_string_len = mb_strlen($title_start_string); $title_end_string=" "; $title_end_string_len = mb_strlen($title_end_string); //アブスト $abst_start_string=""; $abst_start_string_len = mb_strlen($abst_start_string); $abst_end_string=" "; $abst_end_string_len = mb_strlen($abst_end_string); // $mode = 0; $testval_tit = ''; $testval_abs = ''; $testval_kana = ''; $cnt_k = 0; $cnt_r = 0; $cnt_ng = 0; if($argc > 1){ try { $pdo = new PDO('mysql:dbname=test;host=192.168.4.135', 'username', 'password',array(PDO::MYSQL_ATTR_LOCAL_INFILE => true)); } catch (PDOException $e) { exit('データベースに接続できませんでした。' . $e->getMessage()); } $stmt = $pdo->query('SET NAMES utf8'); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } $stmt = $pdo->query('set character_set_database=utf8'); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } echo "読み取り開始・・・\n"; $time_start = microtime(true); $fp = fopen($argv[1], "r"); $temp_file = tempnam(sys_get_temp_dir(), 'Tux'); $fpw = fopen($temp_file, "w"); while ($line = fgets($fp)) { if($mode == 0){ //タイトル探し $testval_tit = searchStr($line,$title_start_string,$title_start_string_len,$title_end_string,$title_end_string_len); if($testval_tit !== ''){ //echo "->".$line; //echo "名称=".$testval_tit."\n"; $cnt_k = $cnt_k + 1; $mode = 1; } }elseif($mode == 1){ //アブスト探し $testval_abs = searchStr($line,$abst_start_string,$abst_start_string_len,$abst_end_string,$abst_end_string_len); if($testval_abs !== ''){ //echo "->".$line; //echo " 概要=".$testval_abs."\n"; $testval_kana = seikei2($testval_abs,$testval_tit); if($testval_kana !== ''){ /*echo "==============================\n"; echo "名称=".$testval_tit."\n"; echo " 概要=".$testval_abs."\n"; echo " よみがな=".$testval_kana."\n"; echo "==============================\n";*/ fwrite($fpw,$pdo->quote($testval_kana).",".$pdo->quote($testval_tit).",".$pdo->quote($testval_abs)."\n"); $cnt_r = $cnt_r + 1; //if($cnt_r > 1000) break; }else{ /*echo "【NG】名称=".$testval_tit."\n"; echo "【NG】よみがな=".$testval_kana."\n"; echo "【NG】概要=".$testval_abs."\n";*/ $cnt_ng = $cnt_ng + 1; } $mode = 0; } } } fclose($fpw); fclose($fp); $timelimit = microtime(true) - $time_start; echo "\n".$timelimit." seconds\n"; echo "総数:".$cnt_k." 有効数:".$cnt_r." 無効数:".$cnt_ng." ".(100*$cnt_r/$cnt_k)."%\n"; echo "DBに書き込み開始・・・"."'".$temp_file."'\n"; $time_start = microtime(true); $stmt = $pdo->query("LOAD DATA LOCAL INFILE ". "'".$temp_file."' REPLACE INTO TABLE `test`.`wiki` ". "FIELDS TERMINATED BY ',' ENCLOSED BY '\'' LINES TERMINATED BY '\n' (`kana`, `name`, `gaiyo`);"); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } $timelimit = microtime(true) - $time_start; echo "\n".$timelimit." seconds\n"; $pdo = null; } function seikei2($abs,$title){ $retval = ""; //〜の一覧ってやつはいらない if(!endsWith($title,"一覧")){ $t_title = mb_convert_kana(seikei($title),"c"); if(preg_match("/^[ぁ-ゞー]+$/u",$t_title)){ //タイトルが全部ひらがなだった $retval = $t_title; //}elseif(preg_match("/^[ァ-ヶー]+$/u",$t_title)){ // //タイトルが全部カタカタだった→ひらがなに変換 // $retval = $t_title; }else{ $testval_k = searchStr($abs,$title."(",mb_strlen($title)+1,")",1); if($testval_k !== ''){ //ひらがなにしてみる $testval_kana = mb_convert_kana(seikei($testval_k),"c"); if(preg_match("/^[ぁ-ゞー・]+$/u",$testval_kana)){ $retval = $testval_kana; } } } } return $retval; } function seikei($str){ //空白や-を削除、区切り文字があれば先頭を返す $retval = ""; $str_s = mb_ereg_replace("[-\s\u00A0\u3000・]","",$str); //$str_s = mb_ereg_replace("・","",$str_s); //$str_s = mb_ereg_replace("-","",$str_s); //$str_s = mb_ereg_replace(" ","",$str_s); //$str_s = mb_ereg_replace("ー",ー",$str_s); $ary = mb_split("[、, (,]",$str_s); if(count($ary) > 0){ $retval = $ary[0]; }else{ $retval = $str_s; } return $retval; } function searchStr($str,$start_str,$start_str_len,$end_str,$end_str_len){ $retval =""; $pos_s = mb_strpos($str, $start_str); $pos_e = mb_strpos($str, $end_str); if(($pos_s === false) || ($pos_e === false)){ //みつからず }else{ //echo mb_strlen($str)."->s:".$pos_s."->e:".$pos_e; //$retval = mb_substr($str,$pos_s+$start_str_len,mb_strlen($str) - $start_str_len - $end_str_len-1); $retval = mb_substr($str, $pos_s+$start_str_len, $pos_e - $pos_s - $start_str_len); } return $retval; } /** * endsWith * http://blog.anoncom.net/2009/02/20/124.html * * @param string $haystack * @param string $needle * @return boolean */ function endsWith($haystack, $needle){ $length = (strlen($haystack) - strlen($needle)); if( $length <0 data-blogger-escaped-false="" data-blogger-escaped-haystack="" data-blogger-escaped-length="" data-blogger-escaped-needle="" data-blogger-escaped-return="" data-blogger-escaped-strpos="">
これを実行すると・・・
php wikicsv.php jawiki-latest-abstract.xml
読み取り開始・・・
29.402565956116 seconds
総数:943216 有効数:408613 無効数:534603 43.321254092382%
DBに書き込み開始・・・'/tmp/TuxUHAuGL'
768.0825881958 seconds
読み取り開始・・・
29.402565956116 seconds
総数:943216 有効数:408613 無効数:534603 43.321254092382%
DBに書き込み開始・・・'/tmp/TuxUHAuGL'
768.0825881958 seconds
PCで実行しているので、やはり生成は29秒と早い。
でも、ラズベリーパイに転送するのは、768秒・・・なんとか改善できないかな。
で、中身はこんな感じ
んでもって、サーバー側のスクリプトは、
<>
<?php mb_language('Japanese'); mb_internal_encoding('UTF-8'); mb_regex_encoding("UTF-8"); $s_talk = htmlspecialchars($_GET['talk'], ENT_QUOTES, "utf-8"); $result = ""; try { $pdo = new PDO('mysql:dbname=test;host=192.168.4.135', 'username', 'password'); } catch (PDOException $e) { talk("データベースに接続できませんでした。"); exit('データベースに接続できませんでした。' . $e->getMessage()); } $stmt = $pdo->query('SET NAMES utf8'); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } $stmt = $pdo->query('set character_set_database=utf8'); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } if(strlen($s_talk) == 0){ talk("WEBサーバーを起動しました。"); }else{ $result = "あなたの言葉は、".$s_talk."です。"; if(preg_match("/^[ぁ-ゞー]+$/u",$s_talk)){ //ひらがなだった $stmt = $pdo->prepare("select * from wiki where wiki.kana like :word and wiki.kana not like '%ん' order by rand() limit 1"); $stmt->bindValue(':word', mb_substr($s_talk,-1).'_%'); $flag = $stmt->execute(); if (!$flag) { $info = $stmt->errorInfo(); exit($info[2]); } while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) { $result=$result." 私の言葉は".$data['name']."(".$data['kana'].")です。 ".$data['gaiyo']; talk("あなたの言葉は、".$s_talk."です。そして、私の言葉は、".$data['kana']."です。"); } }else{ $result=$result." 申し訳ありませんが、すべて「ひらがなで」入力してください。"; talk("あなたの言葉は、".$s_talk."です。申し訳ありませんが、すべて「ひらがなで」入力してください。"); } } $pdo = null; function talk($kotoba){ exec('echo "'.$kotoba.'" | /home/pi/aquestalkpi/AquesTalkPi -v -f1 -f - | aplay > /dev/null &'); } echo <<< EOD簡易しりとり RasPiと「しりとり」で遊ぶ!
これは、Wikipediaのダウンロード可能なデータを利用した簡易的な「しりとり」です。EOD; ?>
そして、ブラウザからアクセス!
ちょっと楽しいかも。
0 件のコメント:
コメントを投稿