Upload
nishio
View
41.917
Download
0
Embed Size (px)
Citation preview
「ルール」とは
将来的にいろいろな抽象化がされるが今のところは「TrueかFalseを返すコード」と思っていい。
3
if (これはルール) { … }
def foo(x):
… return True
return False# これもルール
*.py[cod]
*$py.class
*.so
env/
.eggs/
正規表現の羅列もルール
ルールはたくさんある
すでに皆さんの書いているコードの中にもルールはたくさんあるはず
「複雑な判断」が必要なケースではたくさんの細かいルールをまとめて大きな複雑な判断を行っているはず
「まとめる」とは何か?
4
まとめかたの例(単純なもの)
「ルール1、ルール2、…ルールnのうちどれかがTrueの時にTrueを返す」
=全部をorでつなぐ
「ルール1、ルール2、…ルールnのすべてがTrueの時にTrueを返す」
=全部andでつなぐ
5
あいまいさの表現
「ルールx1, x2, x3…は時々誤爆するから単体ではあんまり信用出来ないけど、3個以上Trueになってる時はTrueを返したい」
= Σ(xi) > 2.5
これを論理式で書こうとするとめんどくさい。シンプルに表現できる表現方法を使うことで思考を節約する。
9
例1一部信用出来ないルール
「ルールx1, x2, …は十分信用できるのでどれか一つがTrueならTrueを返していいけどルールx5, x6, …はn個以上Trueじゃないと信用出来ない」
これのシンプルな例としてx1 or (x2 and x3)を考える。x1は単体で信用できるが、x2とx3信頼出来ないので両方Trueの時だけにしたい。
11
例2例外があるルール
「ルールx1, x2…のどれかがTrueならTrueを返すただし例外としてルールx5がTrueの時を除く」
これのシンプルな形として(x1 or x2) and (not x3)
を考える。x3がTrueの場合を例外として、x1かx2
がTrueならTrueを返す。
14
例3もっと複雑なルール
Q:任意の論理式が重み付き和の方法で表現できる?
→YesともNoとも言える、ちょっと補足が必要。
例として
x1 xor x2 = (x1 or x2) and not (x1 and x2)を考えてみよう。
18
ルールを追加する
たとえば新しくx3というルールを追加する
x3 = x1 and x2
そうすると
x1 xor x2 = (x1 or x2) and not (x1 and x2)
= (x1 or x2) and (not x3)
これは例2と同じになる。
20
ここまでの流れ
複雑な判断が必要なケースでは細かいルールを「まとめ」て使っている。
その細かいルールのまとめかたにはandとorで論理的にまとめる方法の他に、重み付き和の方法がある。
後者のほうがあいまいな判断に使いやすい。
22
重みをどうやって決めるのか?
1. とりあえず全部1にする(今「全部and」や「全部or」なら良くはなっても悪くはならない)
2. 手で適当に指定する(このルールは誤爆多いから信用出来ないとか書いた人がわかっているケース)
3. 重みを機械的に決める
=機械学習
23
元祖人工ニューロン
1943年、McCullochとPittsが神経細胞の振る舞いにヒントを得て論理計算が可能なモデルを提案*
それは「入力に重みを付けて足しあわせ、閾値を超えたら1の出力を出す」というものだった。
つまりここまで「重み付き和の方法」と呼んできたものは実は「McCulloch&Pitts型人工ニューロン」(MCP)だった。
29
* ‘A logical calculus of the ideas immanent in nervous activity’
補足
細かいことを言えば機械学習の各手法はもっと複雑に枝分かれや合流をしているのだけど今回は「大きく分けて積み重ねていく系とそうでないのがあって、話題のDeepLearningは積み重ねる系だけど、今回は枯れた技術であるロジスティック回帰を使う」ぐらいの理解でOK
(細かいことの例:人工ニューロンを元に1958年にパーセプトロンが発表されるが、その当時のパーセプトロンは3層のものでも入力層と中間層の間はランダム結線で元祖と同じように線形非分離な問題が解けなかった。1969年にそれを指摘されて研究が下火になるが、1974年~1986年に誤差逆伝搬法のニューラルネットへの応用が発表され、多層のパーセプトロンがまともに学習できるようになった。一方、ロジスティック回帰は人工ニューロンとは無関係に1958年に発表されたが、後に2層の単純パーセプトロンと等価であることが示された)
31
実際の流れ
「XXXするとよさそうなものがあったらYYY」というユーザストーリーを実現する方法を考える
1. 「XXXするとよさそうなものがあったら」に注目した
2.「XXXするとよさそう」を「判断」するコードが必要と考えた
33
以降伏字が多くなりますがご容赦を
実際の流れ
3. とりあえず適当にXXXっぽいキーワードで検索して眺めた
4. XXXっぽい発言がたくさんあるスレッドを発見したのでファイルに書き出した
5. それを眺めながら適当にルールを書いた
34
正解データを読んでLRを学習40
file_yes = codecs.open(‘XXX.txt', 'r', 'utf-8')
file_no = codecs.open('not_XXX.txt', 'r', 'utf-8')
xs = []
ys = []
for line in file_yes:
line = preprocess(line)
xs.append(make_feature_vector(line))
ys.append(1)
for line in file_no:
line = preprocess(line)
xs.append(make_feature_vector(line))
ys.append(0)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(xs, ys)
特徴ベクトルの作り方41
from rules import rules
def make_feature_vector(s):
fv = []
for f in rules:
rs = f(s)
if rs:
fv.append(1)
else:
fv.append(0)
return fv
能動学習
10. 正解を教えてないデータについて、ロジスティック回帰で予測をさせて、確率が0.5に近い順に表示させてみた(つまり現状の教師データではTかFか判断がつかないものを表示)
11. 0.5に近い順に1行ずつ表示して、僕が対話的にy/nを入力し、教師データに追加するようにした
12. 眺めながら、場合によってはルールのほうを追加した
42
対話的に学習データを追加44
unknown = codecs.open(‘SOMETHING.txt', 'r', 'utf-8')
buf = []
for line in unknown:
s = preprocess(line)
v = make_feature_vector(s)
score = model.predict_proba(v)[0][1]
buf.append((abs(0.5 - score), score, s, line))
buf.sort()
for _dum, score, s, line in buf:
print u"{:.2f}".format(score),
print line.strip()
yn = raw_input('y/n?>')
if yn == 'y':
codecs.open(‘XXX.txt', 'a', 'utf-8').write(line)
elif yn == 'n':
codecs.open('not_XXX.txt', 'a', 'utf-8').write(line)
else:
print 'passed'