Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://ynomura.dip.jp/index.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <rss version="2.0">
  3.   <channel>
  4.      <title>Weblog on mebius.tokaichiba.jp</title>
  5.      <link>http://ynomura.dip.jp/</link>
  6.      <description>かつてJR横浜線 十日市場駅近くのMebius (CPU:Pentium 150MHz)より発信していたウェブログです。</description>
  7.      <language>ja</language>
  8.      <copyright>Copyright 2017</copyright>
  9.      <lastBuildDate>Thu, 10 Aug 2017 21:06:12 +0900</lastBuildDate>
  10.      <generator>http://www.sixapart.com/movabletype/</generator>
  11.      <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  12.  
  13.            <item>
  14.         <title>野球のポジション当てゲームをプログラムで解いてみた</title>
  15.         <description><![CDATA[<p>一昨日、<a href="http://heart-quake.com/article.php?p=527">野球のポジション当てゲーム</a>というのを知った。</p>
  16.  
  17. <p><a href="http://heart-quake.com/article.php?p=527">http://heart-quake.com/article.php?p=527</a>より:
  18. <blockquote>
  19. 1.藤山選手はサードと同じアパートに住んでいるということだ。<br />
  20. 2.センターはライトより背は高いが、足はライトの方が早い。<br />
  21. 3.鈴木選手の妹さんはセカンドと婚約中だそうで、どうも挙式は来春だそうだ。<br />
  22. 4.キャッチャーの長男とサードの次女は同じ小学校の同級生だそうだ。<br />
  23. 5.ショートとサードそれに桜井選手の3人はよく揃って競馬に行くそうだ。<br />
  24. 6.ピッチャーはとても麻雀が強く、今月も梅田選手と菊池選手から5000円ずつまきあげたそうだ。<br />
  25. 7.外野選手のうち一人はどうも木下選手か松村選手らしい。<br />
  26. 8.小川選手はどうも奥さんとうまくいっていないようだ。近々離婚するのではないかとの噂がとんでいる。<br />
  27. 9.選手達はよく揃ってゴルフに行くが、梅田・藤山・桜井の3選手はどうしてもキャッチャーとセカンドには勝てないようだ。<br />
  28. 10.ピッチャーの奥さんはサードの妹さんだそうだ。<br />
  29. 11.松村選手はキャッチャーと、又、桜井選手はピッチャーととても仲が良いようである。<br />
  30. 12.選手たちのうちで、独身なのは、鈴木・梅田・山田の3選手、それにセンターとライトの5人である。<br />
  31. 13.山田選手は桜井選手より背が高く、木下選手は桜井選手より背が低い。しかし、この3人はいずれもファーストより低い。<br />
  32. <!--
  33. 14.選手たちのうちで酒を飲まないのは、梅田選手と松村選手。それにショートの3人だけだそうだ。
  34. 15.バッテリーと内野の全員は菊池・藤山・松村の3選手を除くとみんな小川選手より背が低い。
  35. 16.鈴木選手は外野手の3人と一緒に麻雀をよくするそうだ。
  36. -->
  37. <br />
  38. ここからは、問題文を一部改変しております。<br />
  39. 製品をご購入いただくと正式な問題文が閲覧可能です。<br />
  40. <br />
  41. 14.選手たちのうちで酒を飲まないのは、XXX選手とXXX選手。それにショートの3人だけだそうだ。<br />
  42. 15.バッテリーと内野の全員はXXX・XXX・XXXの3選手を除くとみんな外野の小川選手より背が低い。<br />
  43. 16.鈴木選手は外野手のX人と一緒に麻雀をよくするそうだ。<br />
  44. </blockquote>
  45. こういう論理パズルで、色々制約のあるグループワークで解くもので、何らかの研修とかで使われるものらしい。</p>
  46. <p>これが、色々制約のあるグループワークだから難しいが、一人でやったら簡単に解けるということだったので、上記XXXの部分を入手して、早速その日の夜にやってみたら、1時間くらいかけても解けなかった。</p>
  47. <p>次の日の夜も、前日と同様、「藤山 not 5, 8 &gt; 9, 鈴木 not 4, 4 single, ...」と紙に書き出すと、読み易い文字で書き直した為か、20分くらいで何らか解が出たのだが、解は複数あるような感じで、出した解は別途入手した答えと違った。</p>
  48. <p>本当に解は1つしかないのだろうか?と気になって、今日、次のような簡単なプログラムを書いて探させてみたら、確かに解は1つしか無かった。</p>
  49. <blockquote><pre>
  50. #!/opt/local/bin/python3
  51. from itertools import permutations
  52. names = ('藤山', '鈴木', '桜井', '梅田', '菊池', '木下', '松村', '小川', '山田')
  53.  
  54. def taller(name1, name2):
  55.    dict1 = {'山田':3, '桜井':2, '木下':1} #13
  56.    if name1 in dict1 and name2 in dict1:
  57.        if dict1[name1] > dict1[name2]: return True
  58.    if name1 in ['XXX', 'XXX', 'XXX'] and name2 == '小川': return True #15
  59.    return False
  60.  
  61. def single(name):
  62.    return name in ['鈴木', '梅田', '山田'] #12
  63.  
  64. def married(name):
  65.    return name in ['小川'] #8
  66.  
  67. def judge(position):
  68.    name_by_pos = {v:k for k,v in position.items()}
  69.  
  70.    if position['藤山'] == 5: return False #1
  71.    if taller(name_by_pos[9], name_by_pos[8]): return False #2
  72.    if position['鈴木'] == 4 or married(name_by_pos[4]): return False #3
  73.    if single(name_by_pos[2]) or single(name_by_pos[5]): return False #4
  74.    if position['桜井'] == 5 or position['桜井'] == 6: return False #5
  75.    if position['梅田'] == 1 or position['菊池'] == 1: return False #6
  76.    if (position['木下'] >= 7 and position['松村'] >= 7) \
  77.       or (position['木下'] <= 6 and position['松村'] <= 6): return False #7
  78.    #8
  79.    if position['梅田'] in (2,4) or position['藤山'] in (2,4) \
  80.       or position['桜井'] in (2,4): return False #9
  81.    if single(name_by_pos[1]): return False #10
  82.    if position['松村'] == 2 or position['桜井'] == 1: return False #11
  83.    if position['鈴木'] >= 8 or position['梅田'] >= 8 or position['山田'] >= 8 \
  84.       or married(name_by_pos[8]) or married(name_by_pos[9]): return False #12
  85.    if position['山田'] == 3 or position['桜井'] == 3 \
  86.       or position['木下'] == 3: return False #13
  87.    if position['XXX'] == 6 or position['XXX'] == 6: return False #14
  88.    if position['XXX'] >= 7 or position['XXX'] >= 7 or position['XXX'] >= 7 \
  89.       or position['小川'] <= 6: return False #15
  90.    if XXXXXXXXXXXXXXXXXXXXX: return False #16
  91.    return True
  92.  
  93. for p in permutations(range(9)):
  94.    position = {names[i]: p[i]+1 for i in range(9)}
  95.    if judge(position) == True:
  96.        print(position)
  97. </pre></blockquote>
  98. (上記問題文で伏字にされている部分がわかる部分は伏字にしている)
  99.  
  100. <p>
  101. プログラムのデバッグ中に、次のような表を作ってこれを埋めていく形で解き直したら、10分もかからずに解けた。問題を半分くらい覚えてしまったから早く解けたということもあるが、最初からこうやれば良かったと思った。
  102. <table border="1">
  103. <tr><th>    <th>1<th>2<th>3<th>4<th>5<th>6<th>7<th>8<th>9</tr>
  104. <tr><th>藤山<td> <td>0<td> <td>0<td>0<td> <td> <td> <td> </tr>
  105. <tr><th>鈴木<td>0<td>0<td> <td>0<td>0<td> <td> <td> <td> </tr>
  106. <tr><th>桜井<td>0<td>0<td> <td>0<td>0<td>0<td> <td> <td> </tr>
  107. <tr><th>梅田<td>0<td>0<td> <td>0<td>0<td> <td> <td> <td> </tr>
  108. <tr><th>菊池<td>0<td> <td> <td> <td> <td> <td> <td> <td> </tr>
  109. <tr><th>木下<td> <td> <td>0<td> <td> <td> <td>7<td>7<td>7</tr>
  110. <tr><th>松村<td> <td>0<td> <td> <td> <td> <td>7<td>7<td>7</tr>
  111. <tr><th>小川<td> <td> <td> <td>0<td> <td> <td> <td>0<td>0</tr>
  112. <tr><th>山田<td>0<td>0<td>0<td> <td>0<td> <td> <td> <td> </tr>
  113. </table>
  114. (1.〜13.まで読んでマークした状態、0は偽、7は7.参照の意)
  115. </p>
  116.  
  117. ]]></description>
  118.         <link>http://ynomura.dip.jp/archives/2017/08/post_61.html</link>
  119.         <guid>http://ynomura.dip.jp/archives/2017/08/post_61.html</guid>
  120.                  <category domain="http://www.sixapart.com/ns/types#category">数学</category>
  121.        
  122.        
  123.         <pubDate>Thu, 10 Aug 2017 21:06:12 +0900</pubDate>
  124.      </item>
  125.            <item>
  126.         <title>4五歩早仕掛けの玉頭銀対策を考える</title>
  127.         <description><![CDATA[筆者はこの所、4五歩早仕掛けを多用している。長らく将棋の勉強を怠っており、対四間飛車の急戦はこれしか思い出せないのである。しかも、四間飛車に対して急戦の構えを見せると△4三銀と上がる人が多いので、実現しやすく、便利である。
  128. <img src="/archives/images/45quick01.png"> 図1:4五歩早仕掛け
  129.  
  130. 今月、久々に将棋を指す機会があり、久々の4五歩早仕掛けがクリーンヒットして安心し、その次の対局でもまた4五歩早仕掛けをしたら、4三の銀を5四〜6五〜7六と斜めにスルスルと動かされ、対処できずボロボロに負けてしまった。
  131. <img src="/archives/images/45quick02.png"> 図2:6九金型の4五歩早仕掛けに対する玉頭銀
  132.  
  133. 筆者は昔からこの△5四銀が苦手なのであるが、寡聞にして定跡書で見たことが無かった為、この手は無い手で、必ず咎められる手だと思っていた。それで、△5四銀とされれば▲5五歩から殺しにかかるのだが、成功することは5回に1回もない。(しかも、銀を殺せても良くなるとは限らない。)
  134.  
  135. 玉頭銀を殺すイメージ図
  136. <img src="/archives/images/45quick03.png"> 図3:歩を入手して▲7七歩とできれば銀が死ぬ
  137.  
  138. <img src="/archives/images/45quick04.png"> 図4
  139.  
  140. <img src="/archives/images/45quick05.png"> 図5:次に▲6六歩で銀が死ぬ
  141.  
  142. <img src="/archives/images/45quick06.png"> 図6:このままなら次に▲7七歩で銀が死ぬ
  143.  
  144. 今回も銀を殺せず、悪形だけが残り、総崩れしてしまった。
  145. あまりにもひどかったので、一度きちんと調べておくことにした。
  146.  
  147. <hr />
  148. 【結論】<ul>
  149. <li>この△5四銀〜△6五銀〜△7六銀と動く戦法には「玉頭銀」という名前が付いているらしい。
  150. <li>玉頭銀は6九金型の4五歩早仕掛けに対して特に有効とされているらしい。
  151. <li>4五歩早仕掛けの1手前の▲4六歩は△5四歩を待ってからにするべきらしい。
  152. <li>従って、▲6八金直△5四歩の交換を入れてからにするべきらしい。
  153. </ul>
  154. <hr />
  155.  
  156. しかし、▲6八金直の次に△5四歩とされるとは限らない。
  157. ▲6八金直の直後に△5四銀と玉頭銀で来られれば▲5五歩△6五銀▲7五歩〜▲2六飛の筋があるし、▲3五歩△同歩▲4六銀が速いので、玉頭銀の牽制になっているとは思うが、後手には△1二香や△6四歩など、色々な手がある。△6四歩〜△5四銀〜△6三銀引と堅められることも多い。それに対して、▲6八金直は有効な待ちなのだろうか?
  158.  
  159. 筆者は人生で▲6八金直にいい思い出が無い。△8四桂〜△7六桂の両取りを狙われるし、下段が空くし、5七銀の引き場所が無くなるし、▲5九香の頑張りがあまり利かなくなる。
  160.  
  161. ▲6八金直が得な手でなく、次に△5四歩や△5四銀が期待できないなら、やっぱり▲6八金直と待つのではなく、さっさと▲4六歩と突きたい。それでもし△5四銀を食らっても、正確に指されれば少し悪くなる、という程度に済ませる方法は無いだろうか、と思って、懲りずに6九金型で玉頭銀を食らった場合の対策を探してみた。
  162.  
  163.  
  164. △5四銀の後は(1)▲3七桂、(2)▲3八飛、(3)▲5五歩の3通りが多いようである。
  165.  
  166. (1)▲3七桂の後は、△6五銀▲4五歩△7六銀▲2四歩△同歩▲4四歩
  167. <img src="/archives/images/45quick07.png"> 図7
  168. △同角▲同角△同飛▲7七歩△8七銀成
  169. <img src="/archives/images/45quick08.png"> 図8
  170. ▲同玉△8四飛▲8六銀△6四角▲9七角△9五歩▲同歩△9六歩▲同玉△8六角▲同角△8五銀
  171. <img src="/archives/images/45quick09.png"> 図9
  172. と玉頭銀の恐ろしさを一方的に見せつけられるのが、代表的な進行である。
  173.  
  174. ▲4四歩△4四同角には▲7七歩が正解だと思われる。▲4四歩に△3五歩でも▲7七歩と打つことになるらしい。(1)の▲3七桂は、銀を取れないのに形悪く▲7七歩を打つことになることが多く、いまいちである。
  175.  
  176. ただ、▲3七桂△6五銀▲4五歩△7六銀の後、▲4四歩でなく▲4四角とする手があるらしい。
  177. △同角▲同歩△同飛なら▲6六角として、△8四飛と回るのを防げる。
  178. <img src="/archives/images/45quick10.png"> 図10
  179.  
  180.  
  181. (2)▲3八飛は、△3二飛なら▲5五歩△6五銀▲3五歩△同歩▲同飛△7六銀▲2四歩△同歩▲5四歩(図6)のように銀を狙えそうだが、図6からでも簡単には銀が取れない。△4五歩でも助かりそうだし、△6四歩▲6六歩△6五歩▲8六歩△6六歩▲同銀△6四歩とやっても後手がなんとかなりそうである。
  182.  
  183. ▲3八飛には△4五歩とする人が多いと思う。その後、▲3三角成△同桂▲8八角△4三金▲2八飛に△6四角(山崎六段)
  184. <img src="/archives/images/45quick11.png"> 図11
  185. という手があり、これは先手こらえるのが大変そうである。△6四角に▲2四歩と攻め合って先手良しとする本もあるが、筆者には先手良しと理解できなかった。
  186.  
  187. ▲3八飛には何と△4三銀と戻る手もあり、▲3五歩△同歩▲同飛△3二飛▲4五歩△同歩▲4四歩△2二角▲4五飛
  188. <img src="/archives/images/45quick12.png"> 図12
  189. と自然に進めても、△3四銀(谷川-藤井)でうまくいかない。
  190.  
  191.  
  192. やはり筆者としては、△5四銀には勝ち負けを度外視してでも(3)▲5五歩としたい。
  193. ▲5五歩の後は△6五銀▲3五歩△同歩▲3八飛
  194. <img src="/archives/images/45quick13.png"> 図13
  195. とする。
  196. そこで△4三金だと、▲3五飛△3四歩▲3六飛△7六銀▲4五歩△6五銀▲7五歩△4五歩▲8六飛(図5)のように銀挟みが成功する筋がある。
  197.  
  198. 図13から△4五歩だと、▲3五飛△4六歩▲4五歩△3四歩▲同飛△4五飛▲3七桂△4四飛▲同飛△同角▲4一飛
  199. <img src="/archives/images/45quick14.png"> 図14
  200. が一例で、ここで△3五角なら後手良しらしいが、アマ同士なら先手もやれそうではないだろうか。
  201.  
  202. 図13から△4五歩▲3五飛△4六歩▲4五歩に△7六銀とした実戦例(森下-櫛田)もあり、▲4六銀△9五歩▲同歩△9八歩▲同香△9七歩▲同香△9六歩▲同香△8五銀
  203. <img src="/archives/images/45quick15.png"> 図15
  204. と端から大暴れされたが、▲3二歩の垂らしから、と金を作って先手が勝っている。
  205.  
  206. 図13から△7六銀だと、正確に指されると後手良しらしいが、▲3五飛△6五銀▲6六歩△7六銀▲5四歩△同歩▲9七角
  207. <img src="/archives/images/45quick16.png"> 図16
  208. という指し方もあるかも知れない。△3二飛なら▲2四歩△同歩▲2二歩である。
  209.  
  210.  
  211. 1筋の突き合いが入っていると、6九金型でも玉頭銀に対して別の対策があるかも知れない。
  212.  
  213. 1つには、△5四銀に対して、▲5五歩△6五銀▲3五歩△同歩▲3八飛△7六銀▲3五飛△6五銀に▲1五歩(升田-大山)という定跡がある。
  214. <img src="/archives/images/45quick17.png"> 図17
  215. 以下△同歩▲3四歩△2二角▲2四歩△4三飛▲5四歩△同銀▲3三歩成△同飛▲同飛成△同角▲2三歩成△5一角▲2八飛
  216. <img src="/archives/images/45quick18.png"> 図18
  217. で先手優勢である。
  218.  
  219. もう1つは、△5四銀に対して、▲5五歩△6五銀▲3五歩△同歩▲3八飛△4五歩▲3五飛△4六歩の後、▲3七桂△7六銀▲4五桂が成立する。
  220. <img src="/archives/images/45quick19.png"> 図19
  221. 1筋の突き合いが入っていないと、ここで△1五角があり、▲5四歩△同歩▲1一角成としても△3四歩で後手良しになるが、図19だと△3四歩か△2二角しかなく、△3四歩なら▲3三桂成、△2二角なら▲2四歩でいずれも崩壊ではないだろうか。
  222.  
  223. 問題はどこで1筋の突き合いを入れるかだが、▲5七銀左と上がる前に入れている実戦例が、上記の升田-大山戦を含め複数あるので、そのタイミングが良いと思う。ただ、後手が玉頭銀で来ない場合にどういう影響があるかは未確認である。
  224.  
  225. ■参考文献
  226. 最強将棋21 四間飛車破り【急戦編】渡辺 明(著)]]></description>
  227.         <link>http://ynomura.dip.jp/archives/2017/07/post_60.html</link>
  228.         <guid>http://ynomura.dip.jp/archives/2017/07/post_60.html</guid>
  229.                  <category domain="http://www.sixapart.com/ns/types#category">将棋</category>
  230.        
  231.        
  232.         <pubDate>Sat, 22 Jul 2017 22:26:33 +0900</pubDate>
  233.      </item>
  234.            <item>
  235.         <title>scikit-learnのナイーブベイズ分類器を使ってみる</title>
  236.         <description><![CDATA[<p><a href="/archives/2017/05/weka.html">前回</a>のFamily Out Problemの確率モデル(下図)を題材に、ナイーブベイズ分類器を使ってみる。</p>
  237.  
  238. <p><img src="/archives/images/FamilyOutProblem.svg" width=400 height=300 /><br />
  239. Family Out Problem</p>
  240.  
  241. <p>この問題において、family-out以外の変数の真偽値が与えられた時にfamily-out=TRUEかどうかを判定するよう、ナイーブベイズ分類器を学習させてみる。</p>
  242.  
  243. <blockquote><pre>
  244. import numpy as np
  245. import matplotlib.pyplot as plt
  246. from sklearn.naive_bayes import BernoulliNB
  247. from sklearn.metrics import precision_recall_fscore_support
  248. from sklearn.metrics import roc_curve, auc
  249.  
  250. def generate_sample():
  251.    "Sample data generator of the Family Out problem"
  252.    fo = np.random.binomial(1, 0.15)
  253.    bp = np.random.binomial(1, 0.01)
  254.    lo = np.random.binomial(1, (0.05, 0.6)[fo])
  255.    do = np.random.binomial(1, ((0.3, 0.97), (0.9, 0.99))[fo][bp])
  256.    hb = np.random.binomial(1, (0.01, 0.7)[do])
  257.    return [fo, bp, lo, do, hb]
  258.  
  259. # Generate training data and test data
  260. train_data = np.array([generate_sample() for _ in range(1000)])
  261. test_data = np.array([generate_sample() for _ in range(100)])
  262.  
  263. X_train = train_data[:, 1:5] # other than fo
  264. y_train = train_data[:, 0] # only fo
  265. X_test = test_data[:, 1:5] # other than fo
  266. y_test = test_data[:, 0] # only fo
  267.  
  268. # Train a Naive Bayes classifier
  269. clf = BernoulliNB()
  270. clf.fit(X_train, y_train)
  271.  
  272. # Evaluate with training data
  273. y_pred = clf.predict(X_train)
  274. metrics = precision_recall_fscore_support(y_train, y_pred)
  275. print('Evaluation with training data')
  276. print('Class FamilyOut=False: Precision={:.3f}, Recall={:.3f}, F-measure={:.3f}'.format(metrics[0][0], metrics[1][0], metrics[2][0]))
  277. print('Class FamilyOut=True : Precision={:.3f}, Recall={:.3f}, F-measure={:.3f}'.format(metrics[0][1], metrics[1][1], metrics[2][1]))
  278.  
  279. # Evaluate with test data
  280. y_pred = clf.predict(X_test)
  281. metrics = precision_recall_fscore_support(y_test, y_pred)
  282. print('Evaluation with test data')
  283. print('Class FamilyOut=False: Precision={:.3f}, Recall={:.3f}, F-measure={:.3f}'.format(metrics[0][0], metrics[1][0], metrics[2][0]))
  284. print('Class FamilyOut=True : Precision={:.3f}, Recall={:.3f}, F-measure={:.3f}'.format(metrics[0][1], metrics[1][1], metrics[2][1]))
  285.  
  286. # Draw ROC curve
  287. y_train_post = clf.predict_proba(X_train)[:, 0]
  288. y_test_post = clf.predict_proba(X_test)[:, 0]
  289.  
  290. fpr, tpr, thresholds = roc_curve(y_train, y_train_post, pos_label=0)
  291. roc_auc = auc(fpr, tpr)
  292. plt.plot(fpr, tpr, 'k-', lw=2, label='ROC for training data (area = {:.2f})'.format(roc_auc))
  293.  
  294. fpr, tpr, thresholds = roc_curve(y_test, y_test_post, pos_label=0)
  295. roc_auc = auc(fpr, tpr)
  296. plt.plot(fpr, tpr, 'k--', lw=2, label='ROC for test data (area = {:.2f})'.format(roc_auc))
  297.  
  298. plt.xlabel('False Positive Rate')
  299. plt.ylabel('True Positive Rate')
  300. plt.title('ROC curve of BernoulliNB')
  301. plt.legend(loc="lower right")
  302.  
  303. plt.show()
  304. </pre></blockquote>
  305.  
  306. <p>問題のモデルに従って学習用データとテストデータをランダムに生成し、sklearn.naive_bayes.BernoulliNBの分類器を学習させ、テストデータを分類させ、family-out=FALSEとfamily-out=TRUEのそれぞれについてPrecision, Recall, F値を計算している。<br />
  307. 加えて、予測したfamily-out=FALSE/TRUEの確率から、ROC曲線とAUCを出力している。
  308. </p>
  309.  
  310. <p>出力例<br />
  311. <blockquote><pre>
  312. Evaluation with training data
  313. Class FamilyOut=False: Precision=0.936, Recall=0.983, F-measure=0.959
  314. Class FamilyOut=True : Precision=0.847, Recall=0.589, F-measure=0.695
  315. Evaluation with test data
  316. Class FamilyOut=False: Precision=0.923, Recall=0.988, F-measure=0.955
  317. Class FamilyOut=True : Precision=0.889, Recall=0.533, F-measure=0.667
  318. </pre></blockquote>
  319.  
  320. ROC曲線<br />
  321. <img src="/archives/images/naive_bayes01.png" alt="ROC curve" width=320 height=240 /><br />
  322. その時のtraining_dataとtest_data(.arff形式)<br />
  323. <a href="/archives/misc/family_out_train.arff">family_out_train.arff</a><br />
  324. <a href="archives/misc/family_out_test.arff">family_out_test.arff</a><br />
  325. </p>
  326.  
  327. <p>ナイーブベイズ分類器には、同じクラスのデータでは全ての特徴が独立に出現する、つまりbp,lo,do,hbに依存関係が無く、これらがTRUEになる確率はfoの値だけで決まるという仮定があるが、この問題ではbp,do,hbに依存関係があるので、ベイジアンネットワークの方がうまく学習できると考えられる。<br />
  328. なのでベイジアンネットワークで分類した場合の性能と比較したいが、scikit-learn(0.18)にベイジアンネットワークが無いので、代わりにWeka 3.8.1のBayesNetを用いて学習用データで学習させ、テストデータを分類した結果と比較してみる。</p>
  329.  
  330. <p>Wekaの操作手順<br />
  331. <ol>
  332. <li>Weka ExplorerのPreprocessタブでOpen file...ボタンを押し、<a href="/archives/misc/family_out_train.arff">family_out_train.arff</a>を開く</li>
  333. <li>ClassifyタブでClassifierとしてBayesNetを選択する</li>
  334. <li>"BayesNet -D ..."とあるフィールドをクリックしてパラメーター設定画面を開き、searchAlgorithmのフィールドをクリックして、initAsNaiveBayes=False, maxNrOfParents=2に変更</li>
  335. <li>Test optionsのSupplied test setのボタンを押し、<a href="archives/misc/family_out_test.arff">family_out_test.arff</a>を開き、Classとしてfamily-outを選択</li><li>クラスをfamily-outを選択し、Startボタンを押す</li>
  336. </ol>
  337.  
  338. 上記と同じデータを使った出力例<br />
  339. <blockquote><pre>
  340. === Run information ===
  341.  
  342. Scheme:       weka.classifiers.bayes.BayesNet -D -Q weka.classifiers.bayes.net.search.local.K2 -- -P 2 -N -S BAYES -E weka.classifiers.bayes.net.estimate.SimpleEstimator -- -A 0.5
  343.  
  344. === Detailed Accuracy By Class ===
  345.  
  346.                 TP Rate  FP Rate  Precision  Recall   F-Measure  MCC      ROC Area  PRC Area  Class
  347.                 0.988    0.467    0.923      0.988    0.955      0.651    0.889     0.967     0
  348.                 0.533    0.012    0.889      0.533    0.667      0.651    0.889     0.648     1
  349. Weighted Avg.    0.920    0.398    0.918      0.920    0.911      0.651    0.889     0.919    
  350.  
  351. === Confusion Matrix ===
  352.  
  353.  a  b   <-- classified as
  354. 84  1 |  a = 0
  355.  7  8 |  b = 1
  356. </pre></blockquote>
  357. </p>
  358.  
  359. <p>BernoulliNBのテストデータに対する出力と、Precision, Recall, F-measureが完全に一致している。</p>
  360.  
  361. <p>WekaのBayesNetのデフォルト設定では正しいネットワークが学習されなかったが、上記手順の3.のように設定を変えると、大体次のように正しいネットワークになった。<br />
  362. <img src="/archives/images/bayesnet04.png" alt="" /></p>
  363.  
  364. <p>BernoulliNBの性能には試行毎にばらつきがあったが、1000回の平均を取ってみたのが次の値であり、上記の結果は特別に良い例ではない。
  365. <blockquote><pre>
  366. Average with training data
  367. Class FamilyOut=False: Precision=0.925, Recall=0.982, F-measure=0.952
  368. Class FamilyOut=True : Precision=0.844, Recall=0.545, F-measure=0.661
  369. Average with test data
  370. Class FamilyOut=False: Precision=0.925, Recall=0.982, F-measure=0.952
  371. Class FamilyOut=True : Precision=0.842, Recall=0.544, F-measure=0.651
  372. Average of AUC with training data=0.894
  373. Average of AUC with test data=0.895
  374. </pre></blockquote>
  375. また、計10回、同じデータでWekaのBayesNetの性能と比較した所、Precision, Recall, F-measureについては、8回は一致していた。<br />
  376. ROC曲線のAUCはWekaのBayesNetの方が高いことが多かったが、BernoulliNBでも大体0.85-0.90の範囲であり、十分に高かった。<br />
  377. 従って、この確率モデルに対して、ナイーブベイズ分類器は予測性能が十分に高いと言える。</p>
  378.  
  379. <p>なお、ここまでの結果では、学習データに対する各種性能値とテストデータに対する値にほぼ差が無いが、これは学習データのサンプル数が1000と十分に多く、偏りが無いからである。これを100にすると、次のように、テストデータに対する成績が少し下がるが、それでも、学習データだけに対して大幅に成績が良い「過学習(overfitting)」の状態と言える程ではない。<br />
  380. <br />
  381. 学習データ数が100の1000試行の平均<br />
  382. <blockquote><pre>
  383. Average with training data
  384. Class FamilyOut=False: Precision=0.931, Recall=0.963, F-measure=0.945
  385. Class FamilyOut=True : Precision=0.793, Recall=0.582, F-measure=0.650
  386. Average with test data
  387. Class FamilyOut=False: Precision=0.926, Recall=0.955, F-measure=0.938
  388. Class FamilyOut=True : Precision=0.767, Recall=0.564, F-measure=0.620
  389. Average of AUC with training data=0.899
  390. Average of AUC with test data=0.890
  391. </pre></blockquote>
  392. </p>
  393. ]]></description>
  394.         <link>http://ynomura.dip.jp/archives/2017/06/scikitlearn.html</link>
  395.         <guid>http://ynomura.dip.jp/archives/2017/06/scikitlearn.html</guid>
  396.                  <category domain="http://www.sixapart.com/ns/types#category">数学</category>
  397.        
  398.        
  399.         <pubDate>Mon, 19 Jun 2017 22:35:46 +0900</pubDate>
  400.      </item>
  401.            <item>
  402.         <title>Wekaでベイジアンネットワークの事後確率を計算</title>
  403.         <description><![CDATA[<p>ベイジアンネットワークの復習をしていて、<a href="http://www.orsj.or.jp/archive2/or58-04/or58_4_191.pdf">確率的グラフィカルモデル‐ベイジアンネットワークとその周辺‐</a>(オペレーションズ・リサーチ 2013年4月号)という記事を見つけた。その中に、Family Out Problemという有名な例題(下図)の紹介があり、p.194に、
  404. <blockquote>
  405. 表1~3で与えられたCPTの値と式(11)を利用して丹念に計算することにより
  406. P(X<sub>1</sub>=1|X<sub>3</sub>=1,X<sub>5</sub>=1)=0.7577···という結論を得る.
  407. </blockquote>
  408. と書かれていたので、これを自力で計算できたらベイジアンネットワークを理解できたことにしよう、と思って、丹念に計算してみたら、その値にならなかった。</p>
  409.  
  410. <p><img src="/archives/images/FamilyOutProblem.svg" width=400 height=300 /><br />
  411. Family Out Problem</p>
  412. <p>ここでは、<br />
  413. X<sub>1</sub>: Family Out<br />
  414. X<sub>2</sub>: Bowel Problem<br />
  415. X<sub>3</sub>: Light On<br />
  416. X<sub>4</sub>: Dog Out<br />
  417. X<sub>5</sub>: Hear Bark<br />
  418. (それぞれ2値の確率変数)であり、それぞれの条件付き確率は次の通りである。<br />
  419. P(X<sub>1</sub>=1) = 0.15<br />
  420. P(X<sub>2</sub>=1) = 0.01<br />
  421. P(X<sub>3</sub>=1 | X<sub>1</sub>=0) = 0.05<br />
  422. P(X<sub>3</sub>=1 | X<sub>1</sub>=1) = 0.6<br />
  423. P(X<sub>4</sub>=1 | X<sub>1</sub>=0, X<sub>2</sub>=0) = 0.3<br />
  424. P(X<sub>4</sub>=1 | X<sub>1</sub>=0, X<sub>2</sub>=1) = 0.97<br />
  425. P(X<sub>4</sub>=1 | X<sub>1</sub>=1, X<sub>2</sub>=0) = 0.9<br />
  426. P(X<sub>4</sub>=1 | X<sub>1</sub>=1, X<sub>2</sub>=1) = 0.99<br />
  427. P(X<sub>5</sub>=1 | X<sub>4</sub>=0) = 0.01<br />
  428. P(X<sub>5</sub>=1 | X<sub>4</sub>=1) = 0.7
  429. </p>
  430. <p><img src="/archives/images/bayesnet01.png" alt="P(X_1=1 | X_3=1, X_5=1) = \frac{\sum_{X_2}\sum_{X_4} P(X_1=1, X_2, X_3=1, X_4, X_5=1)}{\sum_{X_1}\sum_{X_2}\sum_{X_4} P(X_1, X_2, X_3=1, X_4, X_5=1)}" width=462 height=38 /><br />
  431. なので、Pythonで
  432. <blockquote><pre>
  433. P00101 = 0.85 * 0.99 * 0.05 * 0.7 * 0.01
  434. P00111 = 0.85 * 0.99 * 0.05 * 0.3 * 0.7
  435. P01101 = 0.85 * 0.01 * 0.05 * 0.03 * 0.01
  436. P01111 = 0.85 * 0.01 * 0.05 * 0.97 * 0.7
  437. P10101 = 0.15 * 0.99 * 0.6 * 0.1 * 0.01
  438. P10111 = 0.15 * 0.99 * 0.6 * 0.9 * 0.7
  439. P11101 = 0.15 * 0.01 * 0.6 * 0.01 * 0.01
  440. P11111 = 0.15 * 0.01 * 0.6 * 0.99 * 0.7
  441.  
  442. P35 = P00101 + P00111 + P01101 + P01111 + P10101 + P10111 + P11101 + P11111
  443. P135 = P10101 + P10111 + P11101 + P11111
  444. P1_35 = P135 / P35
  445. print(P1_35)
  446. </pre></blockquote>
  447. とすると、0.8578...という数値になった。どこか読み間違えたかと思って、
  448. <blockquote><pre>
  449. def prob(x1, x2, x3, x4, x5):
  450.    p = 1.0
  451.    p *= (0.85, 0.15)[x1]
  452.    p *= (0.99, 0.01)[x2]
  453.    p *= ((0.95, 0.05), (0.4, 0.6))[x1][x3]
  454.    p *= (((0.7, 0.3), (0.03, 0.97)), ((0.1, 0.9), (0.01, 0.99)))[x1][x2][x4]
  455.    p *= ((0.99, 0.01), (0.3, 0.7))[x4][x5]
  456.    return p
  457.  
  458. P135 = sum([prob(1, x2, 1, x4, 1)
  459.             for x2 in range(2)
  460.             for x4 in range(2)])
  461. P35 =  sum([prob(x1, x2, 1, x4, 1)
  462.             for x1 in range(2)
  463.             for x2 in range(2)
  464.             for x4 in range(2)])
  465. P1_35 = P135 / P35
  466. print(P1_35)
  467. </pre></blockquote>
  468. と書いてみたが、やはり0.8578...だった。
  469. </p>
  470. <p>上記の記事内の条件付き確率表に誤記があり、0.7577...というのは元の確率表で計算された値か、とも思ったが、どの文書のFamily Out Problemを見ても確率は同じだった。</p>
  471. <p>正解は何なのか、何らかのツールで確認しようと思って、Pythonのベイジアンネットワーク関連のツールを探したが、適当なものがなかなか見つからなかった。
  472. </p>
  473. <p><a href="http://scikit-learn.org/stable/">scikit-learn</a>には"Naive Bayes"のAPIはあるがベイジアンネットワークは見つからない。<br />
  474. <a href="https://pymc-devs.github.io/pymc/">PyMC</a>や<a href="http://bayespy.org/">BayesPy</a>は、きっとうまく使えばこの計算ができるのだろうが、ネットワークを定義して、CPT(conditional probability table、条件付き確率表)とevidence(観測値)を与えて事後確率を計算する直接的なサンプルコードが見つからなかったので、諦めた。<br />
  475. <a href="https://github.com/achille/pbnt">PBNT</a>にはそういうサンプルコードがあったので、使ってみたが、P(X<sub>1</sub>=1|X<sub>3</sub>=1,X<sub>5</sub>=1)=0.2018...という全然違う値が出力された。P(X<sub>5</sub>=1)=0.2831と、これは正しい値が出たので、ネットワークとCPTは合ってそうであり、事後確率を計算するにはengine.marginal()でなく別のメソッドを使わないといけないのかとも思ったが、よくわからなかった。
  476. </p>
  477. <p>Pythonを諦めてツールを探すと、<a href="http://www.cs.waikato.ac.nz/ml/weka/">Weka</a>でできることがわかった。Wekaは機械学習の勉強をするなら必修らしく、過去にインストールしていたので、やってみた。<br />
  478. Wekaを起動して、Tools->Bayes net editorを開くと、GUIがバグだらけ(Version 3.8.1, WindowsとMacとで確認)で使いにくいが、ノードを追加して右クリックしながらネットワークを作成し、Tools->Layoutでノードの配置を修正し、CPTを設定し、さらに保存したXMLを書き換えて色々修正し、Tools->Show Marginsを選ぶと、次のように結合確率が表示される。<br />
  479. <img src="/archives/images/bayesnet02.png" /><br />
  480. さらに、右クリック->Set evidenceで LightOn=True, HearBark=True と設定すると、次のように、各ノードの事後確率が表示される。<br />
  481. <img src="/archives/images/bayesnet03.png" />
  482. </p>
  483. <p>これによると、FamilyOut=Trueの事後確率はやはり0.8578...である。筆者は何か問題を読み間違えているのだろうか?</p>]]></description>
  484.         <link>http://ynomura.dip.jp/archives/2017/05/weka.html</link>
  485.         <guid>http://ynomura.dip.jp/archives/2017/05/weka.html</guid>
  486.                  <category domain="http://www.sixapart.com/ns/types#category">数学</category>
  487.        
  488.        
  489.         <pubDate>Mon, 29 May 2017 18:31:10 +0900</pubDate>
  490.      </item>
  491.            <item>
  492.         <title>角交換振り飛車に大ポカ一発で沈む</title>
  493.         <description><![CDATA[昨日は毎年参加している地域の将棋大会だった。
  494. 今年は2回戦敗退だったが、予選は1勝1敗で抽選で勝ち抜け(3人のブロックで3人とも1勝1敗だった)、抽選で決勝1回戦はシードだったので、<a href="/archives/2016/06/post_56.html">昨年の1回戦敗退</a>より悪い内容だった。通常3勝かかる所、たった1勝で2回戦まで進出するとは、何とくじ運の良かったことか。
  495.  
  496. 筆者はここ1年くらい将棋の勉強をしておらず、全て忘れてしまっており、先月からたまにネット将棋を指していたが以前のレートでは全く勝てず、今年は予選突破できないと思った。
  497. 昔から記憶力が無い方であるが、たった1年休んだくらいで全て忘れてしまい、レートが200も下がるのでは、筆者は将棋に向いてないのだろうとつくづく思う。
  498.  
  499. 2回戦の相手は昨年優勝のI藤さんだった。筆者が絶好調でもまず勝てない相手であるが、先手の筆者に次の局面のような感触の良い手が出た。
  500. <img src="/archives/images/20170521-1.png">
  501. 通常は4二の銀が4四に居るので、3四の歩を取っても響かないが、この形だと歩を取った後に3筋の歩を伸ばせる。3四の歩を受けるには△1二角と打つしかないが、形が悪いだろう。
  502. 筆者は通常、角交換振り飛車には▲6六歩のようにして角交換を拒否するのだが、1回戦で筆者が<a href="/archives/2011/07/3_2.html">100回やっても勝てそうにないY田さん</a>がI藤さんに対して▲6六歩と角交換を拒否して負けたのを見て、直前に何か別の展開を<a href="/archives/2013/08/post_47.html">ガラケーの自作アプリ</a>に仕込んだ棋譜の中から1つ探して、その通りに指してみたものである。そういうことをすると通常は相手の研究にはまるので、ろくなことにならないのだが、今回は功を奏した。
  503. 対して、後手のIさんは△3二飛と指した。
  504. <img src="/archives/images/20170521-2.png">
  505. これを見た瞬間、チャンスだと思った。2三の地点が空いている。
  506. その誘惑に駆られた上、一手前に長考したこともあり、じっくり考えようとは思わなかった。
  507. ▲3四角に△4五桂と両取りに跳ねられても▲同角で両方受かる、と、それ以上考えずに、10秒も使わずに▲3四角と指したら、△2五桂とされて、一発で撃沈してしまった。
  508. <img src="/archives/images/20170521-3.png">
  509. あと5秒考えていればこの手に気付いただろう。有段者が何の意味もなく、△3二飛のような隙を作る手を指すはずがない、と、何故一瞬でも思わなかったのか。
  510. △2五桂の後、▲同歩、△3四飛、▲2四歩とすれば、後手は歩切れで、と金ができて大差にはならなさそうだが、この局面では丁度△1五角があって、受かってしまう。
  511.  
  512. △3二飛の局面は激指14のPro+3でも評価値が+280であり、少しリードしていたのは間違いない。その後、▲3四角ではなく、▲2九飛 △5四歩 ▲4八金と桂馬に紐を付け、△1二角 ▲6六歩 △6四歩 ▲1六歩のように進めれば、まあまあ指しやすそうである。
  513. <img src="/archives/images/20170521-4.png">
  514. ここまでの手順は激指14のPro+以上の手を続けたものであり、評価値は+228である。
  515.  
  516. まあ、相手が相手なだけに、こう進んでもまず勝てなかっただろうが…]]></description>
  517.         <link>http://ynomura.dip.jp/archives/2017/05/post_59.html</link>
  518.         <guid>http://ynomura.dip.jp/archives/2017/05/post_59.html</guid>
  519.                  <category domain="http://www.sixapart.com/ns/types#category">将棋</category>
  520.        
  521.        
  522.         <pubDate>Sun, 21 May 2017 22:44:13 +0900</pubDate>
  523.      </item>
  524.            <item>
  525.         <title>MacPortsでmaximaをインストールするとエラーになるのを回避</title>
  526.         <description><![CDATA[<p>現在、MacPortsを使って
  527. <blockquote>
  528. sudo port install maxima
  529. </blockquote>
  530. すると、下のようなエラーになって失敗してしまう。(macOS Sierra 10.12.4で確認)
  531. <blockquote><pre>
  532. ../../doc/info//errormessages.texi:296: `Warning messages' has no Up field (perhaps incorrect sectioning?).
  533. ../../doc/info//errormessages.texi:162: Prev field of node `Operators of arguments must all be the same' not pointed to.
  534. ../../doc/info//errormessages.texi:152: This node (Only symbols can be bound) has the bad Next.
  535. ../../doc/info//errormessages.texi:152: Next field of node `Only symbols can be bound' not pointed to (perhaps incorrect sectioning?).
  536. ../../doc/info//errormessages.texi:204: This node (out of memory) has the bad Prev.
  537. ../../doc/info//errormessages.texi:8: `Error messages' has no Up field (perhaps incorrect sectioning?).
  538. makeinfo: Removing output file `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_math_maxima/maxima/work/maxima-5.39.0/doc/info/maxima.info' due to errors; use --force to preserve.
  539. make[3]: *** [maxima.info] Error 1
  540. </pre></blockquote>
  541. </p>
  542. <p>原因は、makeinfoのバージョンが古いからのようだ。<br />
  543. <a href="http://maxima-discuss.narkive.com/KeLR9qhb/can-t-install-5-39">http://maxima-discuss.narkive.com/KeLR9qhb/can-t-install-5-39</a><br />
  544. に、makeinfoのバージョンが4.xだとこうなることが書かれている。
  545. 実際、macOS Sierraで<code>
  546. makeinfo --version
  547. </code>すると、(GNU texinfo) 4.8と表示される。
  548. </p>
  549. <p>そこで、
  550. <blockquote>
  551. sudo port install texinfo
  552. </blockquote>
  553. (GNU texinfo 6.3のmakeinfoがインストールされる)してから再度
  554. <blockquote>
  555. sudo port install maxima
  556. </blockquote>
  557. すると、上記のエラーは出なくなった。Activationの段階で
  558. <blockquote><pre>
  559. --->  Installing maxima @5.39.0_3+xmaxima
  560. --->  Activating maxima @5.39.0_3+xmaxima
  561. Error: Failed to activate maxima: Image error: /opt/local/bin/maxima already exists and does not belong to a registered port.  Unable to activate port maxima. Use 'port -f activate maxima' to force the activation.
  562. </pre></blockquote>
  563. というエラーになるが、メッセージの通り、
  564. <blockquote>
  565. sudo port -f activate maxima
  566. </blockquote>
  567. とすると、一応wxMaximaと併用しても問題なく動いた。
  568. </p>]]></description>
  569.         <link>http://ynomura.dip.jp/archives/2017/05/macportsmaxima.html</link>
  570.         <guid>http://ynomura.dip.jp/archives/2017/05/macportsmaxima.html</guid>
  571.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  572.        
  573.        
  574.         <pubDate>Sun, 21 May 2017 21:22:43 +0900</pubDate>
  575.      </item>
  576.            <item>
  577.         <title>JediにAutoCompleよりCompanyModeを優先させる</title>
  578.         <description><![CDATA[2ヶ月前に<a href="/archives/2017/03/carbon_emacspyt.html">Carbon EmacsのPython環境を整備した</a>ばかりなのだが、MacのOSを10.7.5から10.12.4にバージョンアップすると、Carbon Emacsがまともに動かなくなってしまった。起動はするのだが、すぐに固まってしまう。しかも、その後distnotedというプロセスが全てのCPUを奪い続けて、Macが激重になる。
  579. この現象は<a href="http://irreal.org/blog/?p=2533">OS X 10.9+Emacs 24.3で起こる</a>らしく、Carbon Emacs(Emacs 22)でも起こったという情報は見つけられなかったが、おそらく同じ問題である。どちらかと言うとOSのバグなのだが、現時点ではEmacsを24.4以降にバージョンアップする以外に解決方法が見当たらない。
  580.  
  581. その為、長年お世話になったCarbon Emacsを手放し、Emacsの最新版である25.2を使うことにした。
  582.  
  583. EmacsWikiの<a href="https://www.emacswiki.org/emacs/PythonProgrammingInEmacs">Python Programming In Emacs</a>のページにはPythonの開発環境を便利にする方法が色々書かれているが、筆者は高機能なPythonの開発環境を使いたい時はSpyderを使っており、EmacsのPython環境はPython.elでPython3が使えて、もう少し便利な補完が効けば十分なので、Jediだけを追加インストールすることにした。
  584.  
  585. Emacs 25.2にbuilt-inのPython.elはPython3に対応しているのだが、MacPortsでpython35をインストールして、M-x customize-group -> pythonして"Python Shell Interpreter"をpython3にすると、<a href="https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22897">Warningが出まくり</a>、妙に不安定だった。M-x list-packagesしてpython packageを0.25.2にバージョンアップすると少し改善したが、完全には直らなかった。
  586. さらに、Jediをインストールすると、これまた不安定で、時々補完候補が出る前にEmacsが固まった。(C-gで抜けることはできる)
  587.  
  588. Emacs 24の最新版である24.5.1ではこの問題は起こらなかったので、当面、EmacsでPythonのコードを書く時は24.5.1を使うことにした。
  589.  
  590. Jediのインストールは、
  591. <blockquote><code>(require 'package)
  592. (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  593. (package-initialize)</code></blockquote>としてpackage.elにMELPAのリポジトリを登録し、M-x list-packagesしてjediをインストールし、<a href="http://tkf.github.io/emacs-jedi/latest/">Jedi.elのドキュメント</a>に従ってセットアップした。
  594.  
  595. なお、Emacs25でjediをインストールすると、Emacs24で"Symbol's function is void: cl-struct-define"というエラーになった。これはjediに限らず、よくあることだそうで、Emacsの24と25を併用する場合、package.elで何かをインストールするならEmacs24でする方が良さそうだ。
  596.  
  597. さて、JediはAutoCompleteとCompanyModeの両方に対応しているが、package.elで"jedi"をインストールするとAutoCompleteが使われる。"company-jedi"をインストールするとCompanyModeが使われるのだが、"jedi"と"company-jedi"の両方をインストールすると、AutoCompleteが優先される。特にAutoCompleteに不満は無く、和製なので贔屓したいが、色々読んでいると、世界的には、日本でも現在は、CompanyModeの方が人気があるようなので、何が良いのかを知るために、これからしばらくはCompanyModeを積極的に使うべく、両方をインストールしてCompanyModeをデフォルトにすることに決めた。
  598.  
  599. しかし、.emacsや.emacs.d/init.elでCompanyModeを優先する適当な方法がわからなかった。Python modeにしてM-x auto-complete-modeとすればAutoCompleteのON/OFFが切り替わり、OFFだとCompanyModeが使われるのだが、Emacs Lispで(auto-complete-mode)としてもON/OFFが切り替わらず、auto-complete-mode関数にはOFFにする引数も無いのである。auto-complete-mode関数のソースコードを見ると、"(if auto-complete-mode ..."とあるので、<blockquote>(setq auto-complete-mode nil)
  600. (auto-complete-mode)</blockquote>とすれば良さそうに思ったが、これでもOFFにならない。
  601. 但し、(setq auto-complete-mode nil)すると、即座にAutoCompleteがOFFになる。このことを使って、試行錯誤の末、.emacs等に
  602. <blockquote>(add-hook 'python-mode-hook 'jedi:setup)</blockquote>よりも前のどこかに
  603. <blockquote>(add-hook 'python-mode-hook
  604.  (lambda () (setq auto-complete-mode nil)))</blockquote>と書けば、Python mode開始時にAutoCompleteがOFFになり、CompanyModeが使われることがわかった。
  605. ]]></description>
  606.         <link>http://ynomura.dip.jp/archives/2017/05/jediautocomplet.html</link>
  607.         <guid>http://ynomura.dip.jp/archives/2017/05/jediautocomplet.html</guid>
  608.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  609.        
  610.        
  611.         <pubDate>Sat, 06 May 2017 23:32:13 +0900</pubDate>
  612.      </item>
  613.            <item>
  614.         <title>ROC曲線を理解する</title>
  615.         <description><![CDATA[<p>2値の予測(判別、識別、…)に用いる特徴量の良し悪しを評価する1つの方法として、ROC曲線というものがある。<br />
  616. 実際は正で予測も正であるデータの数をTP(True Positive)、<br />
  617. 実際は負で予測も負であるデータの数をTN(True Negative)、<br />
  618. 実際は負で予測は正であるデータの数をFP(False Positive)、<br />
  619. 実際は正で予測は負であるデータの数をFN(False Negative)、<br />
  620. と呼ぶ時、<br />
  621. TPR(True Positive Ratio)=TP/(TP+FN)を縦軸、<br />
  622. FPR(False Positive Ratio)=FP/(FP+TN)を横軸、<br />
  623. としたグラフである。
  624. </p>
  625. <p>ROC曲線の例<br />
  626. <a href="/archives/images/ROC1.png">
  627. <img src="/archives/images/ROC1.png" width="320" height="240" alt="ROC curve sample" />
  628. </a>
  629. </p>
  630.  
  631. <p>ROC曲線は、必ず(0,0)から始まって(1,1)で終わる。<br />
  632. 特徴量が全く予測の役に立たない、ランダムな値であれば、TPR=FPRの線になる。<br />
  633. ROC曲線より下の面積、AUR(Area Under ROC curve)(または単にAUC(Area Under the Curve))が大きいほど、特徴量の値の全域に渡って良い特徴量だとされる。
  634. 理想的な特徴量だと、ROC曲線はFPR=0とTPR=1の線になる。
  635. </p>
  636.  
  637. <p>ROC曲線は機械学習で識別器の評価によく用いられるらしいので、とりあえず覚えておこうと思ったのだが、筆者はこれの理解にえらく苦労したので、調べたことや考えたことをメモする。<br />
  638. <a href="/archives/2009/09/16.html">統計学の検定</a>と同様、こういう確率と論理を組み合わせたものは、人によって向き不向きがあるのだと思いたい。</p>
  639.  
  640. <p>TP,TN,FP,FNの関係を再度整理すると、次のようになる。
  641. <table border="1">
  642. <tr><th rowspan="2" colspan="2"><th colspan="2">予測</tr>
  643. <tr><th bgcolor="maroon">+<th bgcolor="navy">−</tr>
  644. <tr><th rowspan="2">実<br />際<th>+<td align="center" bgcolor="maroon">TP<td align="center" bgcolor="navy">FN (Type II error)</tr>
  645. <tr><th>−<td align="center" bgcolor="maroon">FP (Type I error)<td align="center" bgcolor="navy">TN</tr>
  646. </table>
  647. PやNは予測がPositiveかNegativeかであり、TやFはそれが正解かどうかである。<br />
  648. FPは誤検出のことであり、統計学の検定でも使われる「第一種の過誤」(検定では帰無仮説を棄却できないのに棄却する条件に誤ってヒットしてしまうこと)である。<br />
  649. FNは検出不能であり、「第二種の過誤」(検定では帰無仮説が誤りなのに棄却する条件にヒットしないこと)である。
  650. </p>
  651.  
  652. 予測の精度に関する尺度としては、Accuracy, Presicision, Recall, F値があり、それぞれ次のように定義される。
  653. <dl>
  654. <dt>Accuracy = (TP+TN) / (TP+TN+FP+FN)</dt><dd>予測の正解率。</dd>
  655. <dt>Precision = TP / (TP+FP)</dt><dd>Positiveと予測される中の正解率。</dd>
  656. <dt>Recall = TP / (TP+FN)</dt><dd>実際にPositiveの内、Positiveと予測される割合。検出力、Sensitivity。</dd>
  657. <dt>F値(F-measure, F1 score) = ((Precision<sup>-1</sup> + Recall<sup>-1</sup>)/2)<sup>-1</sup></dt><dd>PrecisionとRecallの調和平均。統計学のF分布に従うF値とは関係ない。<br />
  658. PrecisionとRecallはトレードオフの関係にあるので、それらをバランス良く合成した尺度。</dd>
  659. </dl>
  660.  
  661. <p>予測の精度はAccuracyで評価するのが簡単だが、実際の正のデータ数と負のデータ数に偏りがあると、データ数が少ない方の正解率が低くても、データ数が多い方の正解率が高ければAccuracyが高くなってしまうので、Accuracyだけでは適切に評価できない。<br />
  662. そのような場合にPrecisionやRecallが用いられるが、これらは一般に特徴量の閾値によってトレードオフの関係があり、セットで評価しないといけないので、単純比較には向かない。そこで用いられるスカラー値が、F値や、ROC曲線のAUCである。<br />
  663. Precision-Recall曲線のAUCも使われることがあるが、Presicionは実際の正のデータの割合に依存するので、正のデータの割合が同じでないと比較には使えない。実際の正のデータの割合が極端に小さい場合など、Precisionが大きな意味を持つ場合にはPrecision-Recall曲線が用いられる。
  664. </p>
  665.  
  666. <p>
  667. ROC曲線は、TPR=TP/(TP+FN)とFPR=FP/(FP+TN)のグラフである。TPRを陽性率、FPRを偽陽性率と呼ぶこともある。TPRはRecallと同じである。FPRはfall-out(副産物)と呼ばれることもある。
  668. </p>
  669. <p>
  670. 次の図の3つのROC曲線が、正のデータと負のデータがどのように分布する特徴量に対応するかを考えてみる。<br />
  671. <a href="/archives/images/ROC2.png">
  672. <img src="/archives/images/ROC2.png" width="240" height="240" alt="ROC curve sample 2" />
  673. </a><br />
  674. </p>
  675. <p>
  676. 例えば、次のような分布になる特徴量だと、青いROC曲線になる。<br />
  677. <a href="/archives/images/ROC3.png">
  678. <img src="/archives/images/ROC3.png" width="320" height="240" alt="distribution of totally independent feature" />
  679. </a><br />
  680. 横軸は特徴量、縦軸は赤い部分が正のデータの分布、青い部分が負のデータの分布を表している。このグラフでは、正のデータも負のデータも一様分布している。閾値tより右ならPositive、左ならNegativeと予測する時、tを右端から左に動かすと、TPRもFPRも0から1に向かって増大するが、常にTPR=FPRである。正のデータと負のデータの割合はグラフの形状には関係しない。
  681. </p>
  682. <p>
  683. 次のような、正のデータと負のデータが完全に分かれる理想的な特徴量だと、緑のROC曲線になる。<br />
  684. <a href="/archives/images/ROC4.png">
  685. <img src="/archives/images/ROC4.png" width="320" height="240" alt="distribution of ideal feature" />
  686. </a><br />
  687. tを右端から左に動かすと、FPR=0のままTPRが0から1に変化し、青のゾーンに入ると、FPRが0から1に変化する。
  688. </p>
  689. <p>
  690. 次のような分布だと、赤いROC曲線になる。<br />
  691. <a href="/archives/images/ROC5.png">
  692. <img src="/archives/images/ROC5.png" width="320" height="240" alt="distribution of which makes ROC curve perfect arc" />
  693. </a><br />
  694. tを右端から左へ動かすと、FPRよりもTPRの方が早く上昇する。なるべく正のデータと負のデータの分布が分離している良い特徴量ほどFPRが上昇する前にTPRが上昇するので、AUCが大きくなることがわかる。<br />
  695. </p>
  696.  
  697. <p>AUCはどれくらいだと良いか、という基準は一般的なものも色々あるようだが、大体、最低0.7は無いと有効ではないとされるようである。
  698. </p>
  699. <p>なお、特徴量の最良の閾値(cut-off)はROC曲線の(0,1)に最も近い点とする、という方法を複数の箇所で目にしたが、明確な理論的根拠がある訳ではなく、必ずしもそれに限定されないようである。そもそも、(0,1)に最も近いというのがユークリッド距離で良いのかどうかがわからない。
  700. </p>]]></description>
  701.         <link>http://ynomura.dip.jp/archives/2017/04/roc.html</link>
  702.         <guid>http://ynomura.dip.jp/archives/2017/04/roc.html</guid>
  703.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  704.        
  705.        
  706.         <pubDate>Sun, 09 Apr 2017 20:30:28 +0900</pubDate>
  707.      </item>
  708.            <item>
  709.         <title>pandasでmergeせずにgroupbyで間接参照したい</title>
  710.         <description><![CDATA[<p>この前、pandasを使っていて、次のような感じの、関連する2つのテーブル、access_logとchoice_logがある時に、結合したテーブルを作らずにchoice毎のtimestampの最小値を求めたかったのだが、どう書けば良いのかわからなかった。
  711. </p>
  712. <blockquote><pre>
  713. import pandas as pd
  714. import numpy as np
  715. access_log = pd.DataFrame({'session': [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
  716.                           'timestamp': [314, 159, 265, 358, 979, 323, 846, 264, 338, 327]})
  717. choice_log = pd.DataFrame({'session': [100, 100, 101, 102, 102, 103, 104, 104, 105, 106, 106, 107, 108, 108, 109],
  718.                           'choice':  ['A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E', 'A', 'B', 'C', 'D', 'E']})
  719. >>> access_log
  720.   session  timestamp
  721. 0      100        314
  722. 1      101        159
  723. 2      102        265
  724. 3      103        358
  725. 4      104        979
  726. 5      105        323
  727. 6      106        846
  728. 7      107        264
  729. 8      108        338
  730. 9      109        327
  731. >>> choice_log
  732.   choice  session
  733. 0       A      100
  734. 1       B      100
  735. 2       C      101
  736. 3       D      102
  737. 4       E      102
  738. 5       A      103
  739. 6       B      104
  740. 7       C      104
  741. 8       D      105
  742. 9       E      106
  743. 10      A      106
  744. 11      B      107
  745. 12      C      108
  746. 13      D      108
  747. 14      E      109
  748. >>>
  749. </pre></blockquote>
  750. <p>結合テーブルを作るなら、次のように書ける。
  751. </p>
  752. <blockquote><pre>
  753. merged = choice_log.merge(access_log, on='session', how='left')
  754. result = merged.groupby('choice')['timestamp'].min()
  755. >>> result
  756. choice
  757. A    314
  758. B    264
  759. C    159
  760. D    265
  761. E    265
  762. Name: timestamp, dtype: int64
  763. >>>
  764. </pre></blockquote>
  765.  
  766. <p>実際にあったテーブルは巨大で、他にも列がたくさんあり、単純に結合テーブルを作るとRAMが足りなくなってメモリスワップが多発したので、結合テーブルを作らずにこれと同じことがしたかったのだが、その書き方がわからなかった。<br />
  767. 結局access_log.set_index('session').to_dict()のようにして一時的なdictを作って、スワップを多発させながら処理してしまった。<br />
  768. それが心残りだったので、改めてpandasのドキュメントを拾い読みしながら方法を探してみた。
  769. </p>
  770. <ol>
  771. <li>単純に、別のテーブルを参照する関数をSeries.mapに渡す
  772. <blockquote><pre>
  773. def session_to_timestamp(session_series):
  774.    return session_series.map(lambda x: access_log[access_log.session==x]['timestamp'].iat[0])
  775.  
  776. result = choice_log.groupby('choice').agg(lambda x: session_to_timestamp(x).min())
  777. </pre></blockquote>
  778. <p>Seriesの先頭の要素を取り出す方法には、.iat[0]の他に.iloc[0]や.values[0]などがあり、筆者が試した所values[0]の方が速かったりしたが、pandasのドキュメントに書かれているのはilocとiatなので、ここでは添字が整数なら高速なiatを用いた。</p>
  779. </li>
  780. <li>リスト内包表現(list comprehension)で別のテーブルを参照する
  781. <blockquote><pre>
  782. def session_to_timestamp(session_series):
  783.    return [access_log[access_log.session==x]['timestamp'].iat[0] for x in session_series]
  784.  
  785. result = choice_log.groupby('choice').agg(lambda x: min(session_to_timestamp(x)))
  786. </pre></blockquote>
  787. <p>リストにはminメソッドが無いので、session_to_timestamp(x).min()とはできない。</p>
  788. </li>
  789. <li>isinを使ったBoolean Indexingで別の表のサブセットを得る
  790. <blockquote><pre>
  791. def session_to_timestamp(session_series):
  792.    return access_log[access_log.session.isin(session_series.values)]['timestamp']
  793.  
  794. result = choice_log.groupby('choice').agg(lambda x: session_to_timestamp(x).min())
  795. </pre></blockquote>
  796. </li>
  797. <li>別の表からSeriesを作ってSeries.mapに渡す
  798. <blockquote><pre>
  799. def session_to_timestamp(session_series):
  800.    return session_series.map(access_log.set_index('session').timestamp)
  801.  
  802. result = choice_log.groupby('choice').agg(lambda x: session_to_timestamp(x).min())
  803. </pre></blockquote>
  804. <p>一見シンプルで美しそうだが、set_index()はコピーを返すので、timestampの一時的なdictを作るのと変わらない。しかも、グループ数だけ新たなテーブルを作るので、無駄である。</p>
  805. </li>
  806. </ol>
  807.  
  808. <p>これらの処理時間を色々測ってみたが、2つのテーブルのサイズやグループの数によって変わり、どう比較すれば良いかわからなかったので、省略する。<br />
  809. 大まかな傾向としては、1.と2.の処理時間はchoice_logのサイズに依存し、3.と4.の処理時間はsession_logのサイズに依存するようだった。4.はset_indexした中間テーブルを事前に作っておくと高速化するが、それでも、大抵の場合3.が一番速かった。<br />
  810. いずれの方法も最速になる場合があるようなので、場合毎に色々試してみるしかなさそうである。</p>
  811. <p>肝心のメモリ使用量は、適当な測り方がわからなかった。<br />
  812. そもそも、スワップしながらの処理時間が問題だったので、単純にメモリ使用量では測れないと思う。
  813. </p>
  814.  
  815. <p>他にも、以下のような方向で書き方を考えてみたが、うまくできなかった。
  816. </p>
  817. <ul>
  818. <li>groupbyでaggregateでなくtransformしてmin()<br />
  819. transformする時に別のテーブルを参照することを考えたが、transformするとgroup解除されてしまうので、使えなかった。transformする時にmin()するのなら、min()した値を増殖させるだけ無駄なので、確実にaggregateの方が効率が良い。
  820. </li>
  821. <li>pandas.DataFrame.lookupを使う<br />
  822. 引数としてindexしか受けられないので、使えなかった。
  823. </li>
  824. <li>pandas.DataFrame.joinを使う<br />
  825. pandas.DataFrame.mergeを使うのと変わらなかった。
  826. </li>
  827. </ul>
  828.  
  829. <p>そもそも、lambda式を使わずに書く方法は無いのだろうか。<br />
  830. teratailとかStack Overflowとかで聞いた方が早いか。
  831. </p>]]></description>
  832.         <link>http://ynomura.dip.jp/archives/2017/03/pandasmergegrou.html</link>
  833.         <guid>http://ynomura.dip.jp/archives/2017/03/pandasmergegrou.html</guid>
  834.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  835.        
  836.        
  837.         <pubDate>Fri, 31 Mar 2017 20:00:01 +0900</pubDate>
  838.      </item>
  839.            <item>
  840.         <title>pandas.read_csv+numpy.bincountでエラー</title>
  841.         <description><![CDATA[<p>ちょっと前に、はやりのAIのプログラミングでよく使われるPythonとNumPyとPandasを使い始めたのだが、PandasでCSVファイルを読み込んで、各ラベルの出現回数を得る為にNumPyのbincountメソッドを使うと、次のようなエラーが出て、困った。
  842. <blockquote>
  843. TypeError: Cannot cast array data from dtype('int64') to dtype('int32') according to the rule 'safe'
  844. </blockquote>
  845. その時使った環境は、Windows 7(32bit版)+Python 3.5.2(Anaconda 4.1.1 (32-bit))である。Mac OS Xでは出なかった。
  846. </p>
  847. <p>これは、32bitのPythonを使っていると起こることらしい。例えば、32bit Pythonで次のプログラムを実行すると、同じエラーが出る。
  848. <blockquote><pre>
  849. import numpy as np
  850. import pandas as pd
  851. import io
  852.  
  853. data = np.random.randint(10, size=30)
  854. buf = io.StringIO("\n".join(str(x) for x in data))
  855. df = pd.read_csv(buf, header=None)
  856. x = df[0].values
  857. print(x)
  858. print(np.bincount(x)) #Error on 32bit Python
  859. </pre></blockquote>
  860. これは、Pandasが32bit Pythonでもint64を使うのが原因のようである。
  861. </p>
  862.  
  863. <p>このエラーを回避するには、bincountに渡すデータの型をint32にすれば良い。
  864. <blockquote><pre>print(np.bincount(x.astype('int32'))) #also OK on 32bit Python</pre></blockquote>
  865. 出力例
  866. <blockquote>
  867. [1 0 6 7 1 7 7 6 9 5 6 2 8 0 7 6 7 8 9 7 8 9 8 0 2 1 2 6 0 3]<br />
  868. [4 3 3 1 0 1 5 6 4 3]
  869. </blockquote>
  870. </p>
  871.  
  872. <p>または、np.unique(return_counts=True)を使う方法があり、こちらの方が、大抵の場合はnp.bincountを使うよりも好ましいとされるようである。
  873. <blockquote><pre>
  874. print(np.unique(x, return_counts=True))
  875. </pre></blockquote>
  876. 出力例
  877. <blockquote>
  878. (array([0, 1, 2, 3, 5, 6, 7, 8, 9]), array([4, 3, 3, 1, 1, 5, 6, 4, 3]))
  879. </blockquote>
  880. 確かに、np.unique(return_counts=True)の方が、データに負の値があっても使えるし、大きな値が混ざってても配列が巨大にならないので、安全そうである。
  881. </p>
  882.  
  883. <p>なお、今動作しているPythonが32bitか64bitかを判定する方法は、いくつかあるようである。
  884. <u>例1</u>
  885. <blockquote><pre>
  886. import platform
  887. platform.architecture()
  888. </pre></blockquote>
  889.  
  890. 出力(上がMacOSX、下がWin32)
  891. <blockquote>
  892. ('64bit', '')<br />
  893. ('32bit', 'WindowsPE')
  894. </blockquote>
  895.  
  896. <u>例2</u>
  897. <blockquote><pre>
  898. import sys
  899. "%x" % sys.maxsize
  900. </pre></blockquote>
  901. 出力(上がMacOSX、下がWin32)
  902. <blockquote>
  903. '7fffffffffffffff'<br />
  904. '7fffffff'
  905. </blockquote>
  906.  
  907. <u>例3</u>(platform.architecture()の実装にも使われている方法)
  908. <blockquote><pre>
  909. import struct
  910. struct.calcsize("P") * 8
  911. </pre></blockquote>
  912. 出力(上がMacOSX、下がWin32)
  913. <blockquote>
  914. 64<br />
  915. 32
  916. </blockquote>
  917. </p>
  918. ]]></description>
  919.         <link>http://ynomura.dip.jp/archives/2017/03/pandasread_csvn.html</link>
  920.         <guid>http://ynomura.dip.jp/archives/2017/03/pandasread_csvn.html</guid>
  921.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  922.        
  923.        
  924.         <pubDate>Sun, 05 Mar 2017 20:47:33 +0900</pubDate>
  925.      </item>
  926.            <item>
  927.         <title>Carbon EmacsにPython 3環境導入</title>
  928.         <description><![CDATA[<p>筆者はMacで未だにEmacs 22ベースのCarbon Emacsを多用している。Emacs 24ベースのCocoa Emacsもインストールはしているのだが、色々な環境をCarbon Emacsに作ってしまっているので、移行するのが億劫なのである。</p>
  929.  
  930. <p>最近、Python 3を使い始めたのだが、Carbon Emacsのpython.elはPython 2にしか対応していないので、何とかPython 3に対応させる方法は無いかと探した結果、<br />
  931. <a href="http://www.loveshack.ukfsn.org/emacs/">http://www.loveshack.ukfsn.org/emacs/</a><br />
  932. から<br />
  933. python.el<br />
  934. emacs.py<br />
  935. sym-comp.el<br />
  936. の3つをダウンロードして、Emacs.app/内に置けば良いことがわかった。(python.elとemacs.pyは既にあるものを置換、sym-comp.elはpython.elと同じディレクトリに追加)<br />
  937. そして、Emacsを立ち上げて、M-x customize-groupとし、<br />
  938. "Python Default Version" = 3<br />
  939. "Python Python Command" = python3<br />
  940. にすれば完成である。</p>
  941.  
  942. <p>これで、C-c TABとM-TABを駆使すればシンボルの補完ができて、まあまあコーディングが楽になるのだが、やっぱり補完機能は便利にしたいので、<br />
  943. <a href="http://cortyuming.hateblo.jp/entry/20111224/p1">Pythonの補完をEmacsでシンプルに最小労力で手早く使えるようにする - 牌語備忘録 -pygo</a><br />
  944. を参考にして、<a href="https://www.emacswiki.org/emacs/AutoComplete">auto-complete.el</a> + <a href="http://chrispoole.com/downloads/ac-python.el">ac-python.el</a>をインストールした。<br />
  945. auto-complete.elは、Emacs 22で動作実績のある、auto-complete-1.3.1.tar.bz2をどこかから入手した。</p>
  946.  
  947. <p>そして、.emacsに次の4行を書けば完成である。
  948. <blockquote><pre>(require 'auto-complete)
  949. (require 'auto-complete-config)
  950. (ac-config-default)
  951. (require 'ac-python)</pre></blockquote></p>
  952.  
  953. <p>これで、python-modeにして、<code>import math</code>と書いてC-c TABして、<code>math.</code>と打つと、math.sqrtやらmath.piやらが補完候補として自動的に現れるようになった。</p>]]></description>
  954.         <link>http://ynomura.dip.jp/archives/2017/03/carbon_emacspyt.html</link>
  955.         <guid>http://ynomura.dip.jp/archives/2017/03/carbon_emacspyt.html</guid>
  956.                  <category domain="http://www.sixapart.com/ns/types#category">PC一般</category>
  957.        
  958.        
  959.         <pubDate>Wed, 01 Mar 2017 23:37:59 +0900</pubDate>
  960.      </item>
  961.            <item>
  962.         <title>対石田流の定跡で悩む</title>
  963.         <description><![CDATA[筆者は石田流が苦手である。後手になって、初手から▲7六歩△3四歩▲7五歩とされると、これは大変なことになったな、と思ってしまう。同じぐらいの実力(アマ三段程度)同士だと、石田流にされると3局に2局は負けてると思う。
  964. 先週は将棋大会があり、石田流対策としては、▲7六歩△3四歩▲7五歩には△4二玉、下図の局面から仕掛けるなら△9二飛▲8五桂△8二飛▲8六歩△8四飛、の2つだけを覚えて臨んだら、予選の1局目から▲7六歩△3四歩▲7五歩とされ、次の図の局面を迎えてしまった。
  965. <img src="/archives/images/20161123-1.png">
  966. このような局面から△9二飛▲8五桂△8二飛▲8六歩△8四飛と飛車を端に振ってすぐ戻して浮くのは、過去に何かの本で読んだもので、多分定跡だと思う。もし△9二飛▲8五桂△8二飛の次に▲8六飛とされたらどうすればいいんだろう、と不安に思っていたが、他に何も思い付かなかったので、定跡と信じて△9二飛、▲8五桂、△8二飛と手早く指した。
  967. <img src="/archives/images/20161123-2.png">
  968. すると、ノータイムで実際に▲8六飛とされてしまい、長考に沈んでしまった。
  969. 後で調べると、ここまでは2004年のNHK杯の三浦−行方戦と全く同じ進行であり、その対局ではやはり▲8六歩と指されていた。他にも部分的に同じ形から△9二飛▲8五桂△8二飛としたプロの棋譜を4つぐらい見つけたが、次の手は全て▲8六歩△8四飛だったし、激指14で分析しても▲8六飛は評価が低いので、良くない手なのだと思うが、これの咎め方がよくわからない。
  970. <img src="/archives/images/20161123-3.png">
  971. 次に何をやっても▲7三桂成がある。それには△8六飛(次図)とする一手だが、▲同角でも△7三桂の後に先攻されてすぐ桂損を回復されるし、▲6三成桂と踏み込まれる手も気になる。
  972. <img src="/archives/images/20161123-4.png">
  973. 筆者の実戦は、▲8六飛の後、△7四歩▲7三桂成△8六飛▲同角△7三桂▲7四歩△同銀▲7一飛(次図)と先着され、△6二金と受けたら▲9一飛成から大暴れされ、なす術無く、十数手後には激指の先手の評価値が+1000という必敗の形勢になってしまった。
  974. <img src="/archives/images/20161123-5.png">
  975. 激指によると、△6二金が悪手で、ここまで来たら桂取りが銀取りにならないように△6三銀と戻るのが良いらしいが、そこまで後手を引いて駒損を回復されて龍まで作られてしまうのでは、何をやってるのかわからないと思う。
  976. ただ、△7四歩では△6五歩の方が良さそうである。▲7三桂成と歩を取られるのなら逃げておこうと思って△7四歩と避けたのだが、△7三桂と取り返した後に▲7四歩と取る手が桂取りの先手になるし、△7四歩が無くても△7三桂には▲7四歩と突き出す所なので、意味が無かった。▲8六飛の後、△6五歩▲7三桂成△8六飛▲同角△7三桂▲7四歩△同銀▲7一飛△5五角というのが激指の推奨手順である。
  977. <img src="/archives/images/20161123-6.png">
  978. 激指はこれで-400(後手少しリード)くらいの評価を示しているが、筆者にはこれで後手が指せる理由がわからない。次に△3六桂とやっても▲3九玉と引かれるので攻め方がわからないし、やはり▲9一飛成から暴れられて、筆者の実力ではその勢いを止められないように思う。
  979. ただ、もし△5五角に▲5六歩とされれば、△3六桂で一気に後手勝勢になりそうである。△3六桂に▲3九玉だと△6六角が王手で危険なので▲1七玉しか無いが、△1五歩とすれば受けが難しいと思う。
  980. <img src="/archives/images/20161123-7.png">
  981. ▲5五歩なら△1六歩▲2六玉△2八桂成である。
  982. こうなることを期待して、▲8六飛には△6五歩とするべきなのだろうか。]]></description>
  983.         <link>http://ynomura.dip.jp/archives/2016/11/post_58.html</link>
  984.         <guid>http://ynomura.dip.jp/archives/2016/11/post_58.html</guid>
  985.                  <category domain="http://www.sixapart.com/ns/types#category">将棋</category>
  986.        
  987.        
  988.         <pubDate>Sun, 27 Nov 2016 20:28:50 +0900</pubDate>
  989.      </item>
  990.            <item>
  991.         <title>980</title>
  992.         <description><![CDATA[惜しい。
  993. <a href="/archives/images/TOEICIPresult20161023.jpg"><img src="/archives/images/TOEICIPresult20161023.jpg" width="408" height="172"></a>]]></description>
  994.         <link>http://ynomura.dip.jp/archives/2016/11/980.html</link>
  995.         <guid>http://ynomura.dip.jp/archives/2016/11/980.html</guid>
  996.                  <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
  997.        
  998.        
  999.         <pubDate>Tue, 08 Nov 2016 23:55:53 +0900</pubDate>
  1000.      </item>
  1001.            <item>
  1002.         <title>psvn.el+Subversion 1.7がネストされたワーキングコピーでエラーになる件</title>
  1003.         <description><![CDATA[<p>筆者は<a href="http://www.xsteve.at/prg/emacs/psvn.el">psvn.el</a>を6年くらい愛用している。仕事でSubversionを使ってるのだが、Subversionのクライアントソフトとして、周囲がTortoiseSVNを使う中、一人で頑にpsvn.elを使っている。マウス操作やトラックパッド操作が必要なく、全てがキーボード操作で完結するのが、個人的に気持ち良いのである。
  1004. </p>
  1005. <p>最近、仕事で使うSubversionのバージョンが1.6から1.8に変わり、それまで使っていた、2009年のバージョンのpsvn.elが動かなくなった。Subversion 1.7でワーキングコピーの形式が大幅に変わったからである。
  1006. </p>
  1007. <p>そこで、Subversion 1.7にも対応している、最新のpsvn.el(2015-07-20版)をダウンロードして使い始めた所、ワーキングコピーのルートディレクトリにチェックアウトしたワーキングコピーでM-x svn-statusすると、<blockquote>Wrong type argument: stringp, nil</blockquote>というエラーが出て使えなかった。つまり、<pre>
  1008. svn co (URL1) aaa
  1009. cd aaa
  1010. svn co (URL2) bbb
  1011. </pre>
  1012. とした時のディレクトリbbbの下でM-x svn-statusができなかった。<br />
  1013. svn coの代わりに、svn propsetでsvn:externalsを指定してbbbを取得しても同じエラーになった。<br />
  1014. ディレクトリaaaの下でsvn switchして別のワーキングコピーを取得した場合は同じ問題が起こらないのだが、あいにくURL1とURL2とでSubversionのリポジトリが異なる為に、svn switchでbbbを取得することができないのである。
  1015. </p>
  1016. <p>これが筆者としては非常に困ったので、自力で修正してみた。<br />
  1017. 変更箇所をdiff形式で示す。</p>
  1018. <p>修正案1
  1019. <blockquote><pre>
  1020. <span class="diffold">--- psvn.el.org 2015-07-20, 21:42:00</span>
  1021. <span class="diffnew">+++ psvn.el 2016-09-30</span>
  1022. <span class="grayout">@@ -6063,6 +6063,7 @@
  1023.         ;; it doesn't, e.g we reached / already.
  1024.         (setq parent (expand-file-name (concat wc-root "..")))
  1025.         (or (and (< (length parent) (length wc-root))
  1026. <span class="diffnew">+                 (not (file-exists-p (concat wc-root (svn-wc-adm-dir-name))))  ;; stop if .svn or equivalent exists</span>
  1027.                  (svn-status-base-dir-1 (expand-file-name (concat wc-root ".."))))
  1028.             wc-root)))))</span>
  1029. </pre></blockquote>
  1030.  
  1031. svn-status-base-dir-1関数の中で、ワーキングコピーのルートディレクトリを探すのに、できるだけ上位のディレクトリを探すようで、上に辿る途中にエラーになるので、.svnを発見したらそれ以上遡らないようにするものである。</p>
  1032.  
  1033. <p>修正案2
  1034. <blockquote><pre>
  1035. <span class="diffold">--- psvn.el.org 2015-07-20, 21:42:00</span>
  1036. <span class="diffnew">+++ psvn.el 2016-10-10</span>
  1037. <span class="grayout">@@ -3084,7 +3084,7 @@
  1038.     (let ((svn-process-buffer-name "*svn-info-output*"))
  1039.       (when (get-buffer svn-process-buffer-name)
  1040.         (kill-buffer svn-process-buffer-name))
  1041. <span class="diffold">-      (svn-run nil t 'parse-info "info" ".")</span>
  1042. <span class="diffnew">+      (svn-run nil t 'parse-info "info" default-directory)</span>
  1043.       (svn-status-parse-info-result)))
  1044.   (unless (eq arg t)
  1045.     (svn-status-update-buffer)))</span>
  1046. </pre></blockquote>
  1047.  
  1048. 原因がよくわからないが、途中にワーキングコピーのルートディレクトリがあると、そこから1つ上に遡った時に、カレントディレクトリがdefault-directoryでなく、もう1つ上のディレクトリにずれてしまうようで、カレントディレクトリがワーキングコピー中でないと <code>svn info .</code> がエラーになる(*)ので、 <code>svn info</code> する時に常にdefault-directoryを使うように変えるものである。
  1049. </p>
  1050.  
  1051. <p>どちらも適切な修正かどうかはわからないが、とりあえず筆者の環境(Linux + Subversion 1.8 + Emacs 2.4)では標記の問題は解決した。
  1052. </p>]]></description>
  1053.         <link>http://ynomura.dip.jp/archives/2016/10/psvnelsubversio.html</link>
  1054.         <guid>http://ynomura.dip.jp/archives/2016/10/psvnelsubversio.html</guid>
  1055.                  <category domain="http://www.sixapart.com/ns/types#category">UNIX</category>
  1056.        
  1057.        
  1058.         <pubDate>Mon, 10 Oct 2016 14:11:57 +0900</pubDate>
  1059.      </item>
  1060.            <item>
  1061.         <title>被写界深度の計算式を導いてみた</title>
  1062.         <description><![CDATA[被写界深度というのは、レンズを通して見た映像の、ピントが合っているように見える、奥行き方向の範囲のことである。
  1063. 昨年、フォトマスター検定という試験を受ける為に勉強した中で、被写界深度を求める式が何故このようになるのかがわからず、気になっていた。
  1064. 先月、フォトマスター検定について講義する機会があったので、そのネタとして、被写界深度の式を導いてみた。
  1065.  
  1066. <img src="/archives/images/DoF1.svg" border="1" width="651" height="250">
  1067. 図1
  1068.  
  1069. まず、被写界深度が何故存在するかというと、ピントが合っていない距離の点は点でなく丸になって映る(ボケる)が、その丸(錯乱円)が十分に小さいと、ほとんどボケてるように見えないからである。
  1070. その十分に小さい錯乱円の直径=許容ボケをδとすると、フィルム(デジカメだとセンサー)上のδに対応して、光軸上のフィルム/センサーの前後に、その範囲に焦点を結ぶとピントが合って見える範囲=焦点深度が存在する。
  1071. <img src="/archives/images/DoF2.svg" border="1" width="333" height="237">
  1072. 図2
  1073.  
  1074. この焦点深度の幅を2εとすると、F値(絞り値)=レンズ焦点距離(f)÷レンズ口径(Φ)を使って、f >> εなのでε/δ = F、すなわちε = Fδと近似できる。
  1075. この焦点深度に対応する、被写体側の範囲が、被写界深度である。
  1076.  
  1077. ここで、「ガウスの結像公式」(以下、単に「結像公式」)というのを用いる。結像公式とは、凸レンズからa離れた位置から発せられる光が、凸レンズを通って反対側のb離れた位置に焦点を結ぶ時、aとbの関係を、レンズ焦点距離fを用いて、
  1078. <img src="/archives/images/DoF01.png" alt="\frac{1}{f}=\frac{1}{a}+\frac{1}{b}, Gaussian form of the lens equation">
  1079. と表すものである。ちなみに、レンズの焦点距離とは、無限遠から来る光が焦点を結ぶ位置のことである。(上式でa=∞とするとb=fとなる)
  1080.  
  1081. この結像公式を用いて、焦点深度と被写界深度の関係を式にする。
  1082. 図1のように、sをレンズから合焦位置までの距離、s<sub>n</sub>を被写界の近点、s<sub>f</sub>を被写界の遠点、tをレンズからフィルム/センサーまでの距離とすると、
  1083. <img src="/archives/images/DoF02.png">
  1084. となる。これらの連立方程式を、tを消去して、s<sub>n</sub>とs<sub>f</sub>について解く。
  1085. (1)よりt=sf/(s-f)が得られるので、これを(2),(3)に代入すると、
  1086. <img src="/archives/images/DoF03.png" alt="s_n=\frac{(t+\epsilon)f}{(t+\epsilon)-f}=\frac{(\frac{sf}{s-f}+\epsilon)f}{(\frac{sf}{s-f}+\epsilon)-f}=\frac{(sf+\epsilon(s-f))f}{f^2+\epsilon(s-f)}">
  1087. <img src="/archives/images/DoF04.png" alt="s_f=\frac{(t-\epsilon)f}{(t-\epsilon)-f}=\frac{(\frac{sf}{s-f}-\epsilon)f}{(\frac{sf}{s-f}-\epsilon)-f}=\frac{(sf-\epsilon(s-f))f}{f^2-\epsilon(s-f)}">
  1088. が得られる。
  1089. ここで、s,f>>εなので、s&plusmn;ε&asymp;s, f&plusmn;ε&asymp;f, sf&plusmn;ε<sup>2</sup>&asymp;sfと近似できることを用いて、簡略化する。
  1090. <img src="/archives/images/DoF05.png" alt="s_n=\frac{(sf+\epsilon(s-f))f}{f^2+\epsilon(s-f)}=\frac{((s-\epsilon)(f+\epsilon)+\epsilon^2))f}{f(f-\epsilon)+\epsilon s}\approx\frac{sf^2}{f^2+\epsilon s}">
  1091. <img src="/archives/images/DoF06.png" alt="s_f=\frac{(sf-\epsilon(s-f))f}{f^2-\epsilon(s-f)}=\frac{((s+\epsilon)(f-\epsilon)+\epsilon^2))f}{f(f+\epsilon)-\epsilon s}\approx\frac{sf^2}{f^2-\epsilon s}">
  1092.  
  1093. これにε=Fδを代入すれば、被写界深度の近点と遠点を求める式になるのだが、フォトマスター検定の参考書では過焦点距離を用いた式になっているので、もう少し変形を進める。
  1094. 過焦点距離とは、被写界深度の遠点が無限遠に届く、最短の撮影距離である。焦点深度と結像公式を用いて被写界深度の近点、遠点と同じ要領で、過焦点距離Hについても式を立てると、
  1095. <img src="/archives/images/DoF07.png">
  1096. となる。下の式からt=f+εが得られ、それを用いて上の式をHについて解くと、
  1097. <img src="/archives/images/DoF08.png" alt="H=\frac{tf}{t-f}=\frac{(f+\epsilon)f}{\epsilon}\approx\frac{f^2}{\epsilon}=\frac{f^2}{F\delta}">
  1098. すなわち<strong>過焦点距離=レンズ焦点距離<sup>2</sup>÷(絞り値×許容ボケ)</strong>と求まる。これを用いてs<sub>n</sub>, s<sub>f</sub>をさらに整理する。
  1099. <img src="/archives/images/DoF09.png" alt="s_n\approx\frac{sf^2}{f^2+\epsilon s}=\frac{sf^2}{f^2+\frac{f^2}{H}s}=\frac{Hs}{H+s}">
  1100. <img src="/archives/images/DoF10.png" alt="s_f\approx\frac{sf^2}{f^2-\epsilon s}=\frac{sf^2}{f^2-\frac{f^2}{H}s}=\frac{Hs}{H-s}">
  1101.  
  1102. 従って、
  1103. 被写界近点=(過焦点距離×合焦距離)÷(過焦点距離+合焦距離)
  1104. 被写界遠点=(過焦点距離×合焦距離)÷(過焦点距離−合焦距離)
  1105. である。
  1106.  
  1107. なお、過焦点距離の計算には許容ボケが必要になるが、許容ボケは通常、フィルムやセンサーの対角線長÷1300、が用いられる。
  1108. 35mmフィルムなら、√(36<sup>2</sup>+24<sup>2</sup>)/1300≒0.03328 (≒1/30) mm、
  1109. フォーサーズ/マイクロフォーサーズなら√(17.3<sup>2</sup>+13<sup>2</sup>)/1300≒0.01665 (≒1/60) mm、である。
  1110. ]]></description>
  1111.         <link>http://ynomura.dip.jp/archives/2016/07/post_57.html</link>
  1112.         <guid>http://ynomura.dip.jp/archives/2016/07/post_57.html</guid>
  1113.                  <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
  1114.        
  1115.        
  1116.         <pubDate>Tue, 05 Jul 2016 19:57:23 +0900</pubDate>
  1117.      </item>
  1118.      
  1119.   </channel>
  1120. </rss>
  1121.  

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//ynomura.dip.jp/index.xml

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda