なんとなく

なんとなく書きます

機械学習勉強その1

良いと言われているオックスフォードの通信学習をやってみた。 その第1週の内容

単語

出てきた単語をまとめる

日本語 英語
教師あり学習 supervised learning
教師なし学習 unsupervised learning
分類 classification
回帰分析 regression analysis
仮説 hypothesis
最急降下法 gradient descent

教師あり学習

ラベル付きデータの扱い
分類と回帰の問題を扱う

分類の例は指定した中にあるラベル分け
・通常メールと迷惑メールを学習させてた迷惑メールフィルターなど

回帰の例は売上予測など

教師なし学習

ラベルなしデータの扱い
出力が決まっていないもの

自動のラベル分け等ができる。
・ニュース記事の自動分類

最急降下法

回帰の問題を解く1つの手段

WPFのTreeViewの要素を数え上げる。

WPFのTreeViewの要素を数え上げるのをぱっと見調べても見つからなかったので書く
まあ正確にはTreeViewにバインドしたインスタンスの数をしっかり数え上げたんだけども

結構悩んだけど再帰に気づけばあっさり片付いた。

まずはバインドしている数え上げの対象クラスの概要。
中に自分のリストを持つのが特徴。
自分の下がなければnullにしている。

public class TItem
{
~略
public List<TItem> Items { get; set; }
}

実際の関数部分
refを使っているから隠す感じで2つの関数に分けた。
Itemsがnullになるまで再帰で潜るだけ。

public int FileCount()
{
    int count = 0;
    this.FileCountCore(this, ref count);
    return count;
}

private void FileCountCore(TItem item , ref int count)
{
    if (item.Items != null)
    {
        foreach (var i in item.Items)
        {
            this.FileCountCore(i, ref count);
        }
    }
    count++;
}

再帰だと簡単だった。

LINQのSkipとTakeについて

Skipはその名を通り指定の数だけ飛ばす。

Takeは指定の数だけ出力する。

2つを組み合わせると

範囲の指定ができる。

↓のように書くと

 Enumerable.Range(1, 100).Skip(10).Take(20)

で11~30を返す。

 

SkipWhileとTakeWhileはそれぞれ

Func<int,bool>とFunc<int,int,bool>のデリゲートを持つ。

Func<int,int,bool>は良くあるインデックス付きのやつのパターン

↑の11~30を返すのものを書く場合は

Func<int,bool>のときは

Enumerable.Range(1100).SkipWhile(i => i < 11).TakeWhile(i => i < 31)

 

Func<int,int,bool>のときは

Enumerable.Range(1100).SkipWhile((v,i) => i < 10).TakeWhile((v,i) => i < 20)

 

 のように書く。

 

LINQのAggregateについて

使い方が初見ではいまいち不明なAggregateの使い方について

雑なイメージはreduce関数

[1,2,3,4]を1234とかに変換するときに使える。

 

こんな感じで

Enumerable.Range(1, 4).Aggregate(0, (a, b) => 10* a + b)

 

今回の例だと

 Convert.ToInt32(string.Join("", Enumerable.Range(1, 4)))

の方が二桁の数値にも対応できて楽

 

Aggregateで全部に対応するにはbの桁次第でaにかける数を変える必要がある。

1桁⇒10

2桁⇒100

といった感じにするためにPowとLog10を組み合わせる必要がある。

↓な感じに

Enumerable.Range(5, 4).Aggregate(0, (a, b) => Convert.ToInt32(Math.Pow(10, (int)(Math.Log10(b))+1) * a + b))

System::Stringからtchar*とかへの変更

char*とw_char*で別々にやらないといけないみたい。

System::Stringは最後のNULLがないけど
tchar*系はNULLの必要があるので長さの変更の必要あり。


参考URLを貼る。
http://msdn.microsoft.com/ja-jp/library/ms235631.aspx

http://msdn.microsoft.com/ja-jp/library/d1ae6tz5.aspx

PDFの相互参照表(xref)

xref
x y

でxのオブジェクトを連番でy個示すとのこと。

xxxxxxxxxx yyyyy f [EOL]

xxxxxxxxxx:10桁のファイル先頭からのバイトオフセット
yyyyy:生成番号
f:使用中かを示すワード「n」(使用中)or「f」(フリー)
改行記号を入れて20バイトとのこと
fのあとは、[スペース]+[ ]もしくは[ ]+[ ]とのこと。
本当なのだろうか。。。

PDFのストリームについて

ストリームのオブジェクトの構造は大体こう

x y obj<>stream[改行]
[data][改行]
endstream
endobj

ストリームのデータサイズは、[data]の長さで[改行]は含まないとのこと。
[改行]は「CR+LF」or「LF」とのこと。

※CR:0x0d LF:0x0a

改行コードによりstream~endstream間の大きさが異なるので
読み飛ばすときには注意が必要。
しかも、改行コードはファイル内でも統一されてるとは限らないっぽい。
めんどくさい。

Lengthの値を後ろで参照させる場合有(/Length xx yy R)
この場合は大抵ストリームの後ろにあるので読み飛ばせずに
ストリームを読み続けるしかないのか?
また調べよう。
先に入れて欲しいなー。


フィルターとかについては、またいつか。