Kill one bird with two stones.

情報推薦、情報抽出を研究している大学院生の基本的にやったことのメモとか

C++の配列の要素数

現在C++の勉強中
他の言語からの移行はだいたい標準入出力,変数の宣言,配列,その言語特有のこと
を覚えればいいから、学習コストは低くなる。

さて、以下の配列
int a[]={1,2,3,4,5}
に対して配列の要素数を求めることを考える。
ちなみに要素数は5
他の言語とかたとえばPHPの場合
$a=array(1,2,3,4,5);
var_dump(count($a));

5って出るけど
C++だと

int a_sizeof=sizeof(a);//20
int a_k=sizeo(a[0]);//4
int size=a_sizeof/a_k;//5
とワンステップ踏む必要がある。
配列の要素数のカウントとかよく使うんだから標準の関数に含めればいいと思うんだけどな。

SEのプレゼン術

SEのプレゼン術 (技評SE新書)

SEのプレゼン術 (技評SE新書)


時間があるし、本を何冊か読もうと思う。
ひとまず1冊目

200p程度と読みやすい。1-2時間程度かな。

自分もプレゼンで上がりやすいけど
・自己心理のコントロール

  • 自己暗示、積極的思考、開き直り

をすればいいんじゃないのかってあって今度のプレゼンの機会では心がけようと思う。

スライドに関しては

  • あまり文章量多くするな
  • 配色気をつけろ。色多くするな

プレゼンに関しては

  • 早口
  • オーバーリアクション

に気をつけろと。
まあ、一般的に言われていることだしな。

2.1章まで読んでみた

共立出版から出てる情報推薦システム入門理論と実践を読み進めてく

情報推薦システム入門 -理論と実践-

情報推薦システム入門 -理論と実践-

1章
推薦システムについて

そもそも推薦ってのは、ある本を推薦するって場合と膨大な情報の中から興味のある情報を推薦する(情報過多問題)を解決するためだよねって話。

・協調型推薦
ユーザーAとBが類似しててAが本Aを買ったならBに本Aを推薦するのは合理的だよね。って方法
膨大な本の集合の中から有望な本をフィルタリングして、ユーザーが暗黙的に協調してるから
collaborative filtering;CF 協調フィルタリングとも

・内容ベース
アイテムの説明とか、重要度から推薦する。

・知識ベース
推薦する物の技術的特徴を使用。
例えばPCは頻繁に、買い換えないから、ユーザーの個人情報とかから推測できずベストセラーのアイテムを推薦するしかない。
顧客の要望に応えて推薦する


2章
協調型推薦
2.1ユーザーベース
ユーザーが過去に似た嗜好を持っているならその思考は将来においても似ている
ユーザの好みは長い間一貫してる
との家庭のもと、ユーザーがつけた評価値を用いて予測する。

ピアソンの相関係数がよく用いられるみたい。式は略
2.2式の数字は
アリスの平均が4,ユーザー1の平均が2.25で数式通りに当てはめればOK

ユーザー2との類似度が0.70かどうかを確認する。
ユーザー2の平均は3.5なので

(5-4)*(4-3.5)+(3-4)*(3-3.5)+(4-4)*(4-3.5)+(4-4)*(3-3.5)/(\sqrt{(5-4)^2+(3-4)^2+0^2+0^2}*\sqrt{(4-3.5)^2+(3-3.5)^2+(4-3,5)^2+(3-3.5)^2})=0.7

で、アリスのアイテム5の評価値の予測を2.3式を使う。
2.4式は若干見づらいが、

アリスの平均値→4
アリスとユーザー1,2それぞれの類似度を足し合わせたもの(分母にあたる) (0.85+0.7)
分母にあたるため計算上は 1/(0.85+0.7)
アリスとユーザー1の類似度にユーザー1のアイテム5の評価値からユーザー1の平均値を引いたものを掛け合わせたもの→(0.85*(3-2,4))
アリスとユーザー2の類似度にユーザー2のアイテム5の評価値からユーザー2の平均値を引いたもの掛け合わせたもの→(0.70*(5-3.8))
なお、ここでの平均値はアリスとの類似度を求めるに使用したアイテム4までの平均ではなく、アイテム5までの平均なので注意

で計算をすると確かに4.87になる。」

WikipediaのアブストラクトデータをDBに突っ込む

DBはMySQLを使う。
データのダウンロードは、
Index of /jawiki/latest/
jawiki-latest-abstract.xml

右クリックメニューから保存

でダウンロードしておく。左クリックからだと設定にもよるけど、とてつもなく大きいxmlファイルを開きに行っちゃうので注意。(というより開けないとおもうけど)

で、このabstractをmysqlでインポートできるようにしたいわけだけど、
jawiki-latest-pages-articles.xml.bz2
だとxml2sqlを使えば簡単にできるらしいんだけど、無理そうだったので自作のパーサーを書く。
JavaでXMLを操作の4種類方法とサンプルソース | DigiTechLog Dot Com
のSAXパーサーと
ファイルの入出力 ( Javaサンプル集 )
の追加書き込みの記事を参考に作った。

バグとかありそうだけど、一応パーサーとしての役割を果たしているし、
ひとまず良しとしておく。
ソースは

import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;

public class XMLTestApp1 extends DefaultHandler {
	public static void main(String[] argv) {
		try {
			SAXParserFactory spfactory = SAXParserFactory.newInstance();
			SAXParser parser = spfactory.newSAXParser();
			parser.parse(new File("jawiki-latest-abstract.xml"),
					new XMLTestApp1());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int key = 0;
	public String titlename = "";
	String anchor = "";
	String abst = "";
	String[] Starray = new String[2];
	int akey = 0;
	boolean flag = false;

	public void startElement(String uri, String localName, String qName,
			Attributes attributes) {
		if (qName.equals("title")) {
			key = 1;
			abst = "";
		} else if (qName.equals("abstract")) {
			key = 2;
			akey = 0;
		} else if (qName.equals("anchor")) {
			key = 3;
		} else {
			key = 0;
			akey = 0;
			String[] Starray = new String[2];
		}
	}

	public void characters(char[] ch, int offset, int length) {
		if (key == 1) {
			titlename = new String(ch, offset, length);
			if (titlename.length() > 10) {
				titlename = titlename.substring(10);
				Starray[0] = titlename;
				akey = 1;
				flag = false;
			}

		} else if (key == 2) {
			akey = 0;
			abst = abst + new String(ch, offset, length);
			int abstcount = abst.length();
		} else if (key == 3) {
			Starray[1] = abst;
			akey = 2;
			anchor = new String(ch, offset, length);
			String outputFileName = "link.txt";
			File outputFile = new File(outputFileName);
			try {
				// 出力ストリームの生成(追記モード)
				FileOutputStream fos = new FileOutputStream(outputFile, true);
				OutputStreamWriter osw = new OutputStreamWriter(fos);
				PrintWriter pw = new PrintWriter(osw);
				pw.println(Starray[0] + "," + anchor);
				pw.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (akey == 2 && flag == false) {
			flag = true;
			String outputFileName = "abst.txt";
			File outputFile = new File(outputFileName);
			try {
				FileOutputStream fos = new FileOutputStream(outputFile, true);
				OutputStreamWriter osw = new OutputStreamWriter(fos);
				PrintWriter pw = new PrintWriter(osw);
				pw.println(Starray[0] + "," + Starray[1]);
				pw.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			akey = 3;
		}
	}

	private static boolean checkBeforeWritefile(File file) {
		if (file.exists()) {
			if (file.isFile() && file.canWrite()) {
				return true;
			}
		}
		return false;
	}
}

読み込ませたいxmlをプログラム上で指定して、書き出したいファイル二つをプログラムを置いたところに作成しておく。
自分はabst.txt とlink.txt

abst.txtは
title,abstract の形式で出力され、linkは title,linkで出力される。
あらかじめデーターベースを作成しておいて
次にmysqlimportで
$ mysqlimport -i -u root -p --fields-terminated-by="," データベース名 ファイル名
Password:***

でインポートしてデータを見てみればたぶんOK

ただ、,区切りで判断してるから&のアブストラクトがいまいちちゃんと処理できていない。+とかで区切り文字にしておけばいいんだろうけど。

あとアブストラクトのデータをちょっと見るとわかるけどいまいち使えない。
中途半端にアブストラクトが切り出されているものも多いし。
やっぱり文章使いたいなら jawiki-latest-pages-articles.xml.bz2を使っておくべき

Wikipediaのデータをデータベースに入れる。

Wikipediaのダウンロードできるデータファイル一覧 | mwSoft

ここで紹介されているWikipediaのデータをデータベースに入れる方法。

だいたいひとつ入れるのに1日かかるので帰る前とか時間があるときにやる方がいい。

MySQL/Ubuntuを使用する。

あとApache,MySQL,PHP,PHPMyadminもインストール済みの環境と考える。

page.sqlとcategorylinks.sqlをインポートした時の方法

BigDump: Staggered MySQL Dump Importer

から、bigdump.zipをダウンロードし、Apacheでアクセスできるフォルダにいれておく。

bigdump.phpを適当に開いて

// Database configuration

$db_server = 'localhost';
$db_name = '';
$db_username = '';
$db_password = '';

を自分の環境に合わせて設定。

また、インポートしたいpage.sql,categorylinks.sqlを同じフォルダ内に入れておく。

照合順序がbinaryになってるため、大文字小文字を厳密に考慮すべきアプリケーションの場合は、Web上でbigdump.phpを開いて
Start Importをクリックして開始。問題なければ、そのまま進む。

もし、大文字、小文字どちらでも検索できるようにしたい場合は、

適当なエディタで開いてvarbinaryをvarcharに

CREATE TABLE文の最後の照合順序を示すところのbinaryをutf8に変更して上書きして、bigdump.php上から開始すればOK

page.sqlの場合
を参考にしてUNIQUE INDEXを消して登録すればOK.

あとはPHPMyadmin上からINDEXを設定するなりする。

つまづきやすい点としては
・照合順序がbinaryになっている点。ここをutf8に変更すれば一応日本語で大文字小文字考慮しないで扱えるはず
sqlを開く。Windows上ではほぼ間違いなくメモリの都合で開けないため、サーバー上の端末から開くことを推奨

ラインセレクタを作ってみた.


現状はこんな感じ

ミキサーは
http://www.area-powers.jp/product/usb_product/product/kyo-on/u1soundt5.html
を使ってる


基本的に
・TVのヘッドホン端子から直接ヘッドホンで聞く
・TVのヘッドホン端子をミキサーのLINE IN入力にいれる.
USBでPCにつないで,PCの音声と,ミキサーのマイク,TVの音声をミキシングしてミキサーのFRONT OUT PUTからヘッドホンにつなげる

ただ,この場合機能変える場合抜き差ししないとならない.

ということで,ラインセレクタを作った.
回路図は

見たいな感じ
実際は4回路入りのトグルスイッチ一個で実装

ステレオジャックが80円×4
スイッチが630円で1000円以内で作れた.

アンプ機能つけても良かったけどめんどくさくなるし,
電源入れたり消したりしないといけなくなるからまあいいと思う