差分
このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン | ||
dmb:2011:q4 [2012/01/29 21:55] – created watalu | dmb:2011:q4 [不明な日付] (現在) – 外部編集 (不明な日付) 127.0.0.1 | ||
---|---|---|---|
行 1: | 行 1: | ||
- | === データの説明 === | + | === 元のデータの説明 === |
- | == TIC 2000 == | + | == TIC2000 |
- | < | + | [[http:// |
- | tic.leaan <- read.table(" | + | |
- | tic.eval <- read.table(" | + | * CoIL 2000 Challengeで用いられた保険会社の顧客に関するデータ。86個の変数は、契約状況(V44-V85)と社会人口統計学的な変数(V1-V43)を含んでいる。この調査は |
- | tic.test <- read.table("http:// | + | * このデータはオランダのデータマイニング会社Sentinent Machine Researchから提供され、現実のビジネスの問題に基づいている。学習用データ(ticdata2000.txt)は5000レコードでcaravan insurance policyの契約の有無(V86)を含んでおり、検証用データ(ticeval2000.txt)は4000レコードで契約の有無(V86)は含んでいない。検証用データの正解は、CoIL 2000 Challengeの開催時には公開されていなかったが、現在はテストデータ(tictest2000.txt)として公開されている。 |
- | tic.eval$V86 <- tic.test | + | * V1-V43のうち、コード化が指定されていない変数はすべて、郵便番号の一桁目のエリアを指している。たとえばV30が9ならばその顧客は郵便番号が9で始まるエリアに家を借りていることを、V31が5ならば郵便番号が5のエリアに持ち家があることを意味する。職業、社会層などもすべて、該当するエリアの箇所が郵便番号の一桁目で埋まっている。 |
- | rm(tic.test) | + | |
- | tic.learn$V1 <- as.factor(tic.learn$V1) | + | |
- | tic.lean$V5 <- as.factor(tic.learn$V5) | + | |
- | </ | + | |
== 変数 == | == 変数 == | ||
+ | |||
+ | [[http:// | ||
+ | |||
|変数|分類|メモ| | |変数|分類|メモ| | ||
|V1|顧客分類2|L0でコード化されている、数字の大きさに意味なし| | |V1|顧客分類2|L0でコード化されている、数字の大きさに意味なし| | ||
行 20: | 行 19: | ||
|V5|顧客分類1|L2でコード化されている、数字の大きさに意味なし| | |V5|顧客分類1|L2でコード化されている、数字の大きさに意味なし| | ||
|V6-V9|宗教|L3でコード化されている、V6+V7+V8+V9は9から12の間。それぞれの宗教を信じる割合?| | |V6-V9|宗教|L3でコード化されている、V6+V7+V8+V9は9から12の間。それぞれの宗教を信じる割合?| | ||
- | |V10-V13|結婚|L3でコード化されている?割合?| | + | |V10-V13|結婚|場所を表す変数, |
- | |V14-V15|世帯の大きさ|L3でコード化されている?V14+V15は10以下。割合?| | + | |V14-V15|世帯の大きさ|L3でコード化されている、なぜかV14+V15は10以下。割合?| |
- | |V16-V18|教育水準|L3でコード化されている?V16+V17+V18はほぼ10、それぞれの年数?割合?| | + | |V16-V18|教育水準|L3でコード化されている、なぜかV16+V17+V18はほぼ10、それぞれの年数?割合?| |
- | |V19-V24|職業|L3でコード化されている?V19+V20+V21+V22+V23+V24は9から13の間| | + | |V19-V24|職業|L3でコード化されている、なぜかV19+V20+V21+V22+V23+V24は9から13の間| |
- | |V25-V29|社会層|L3でコード化されている?V25+V26+V27+V28+V29は9から12の間| | + | |V25-V29|社会層|L3でコード化されている、なぜかV25+V26+V27+V28+V29は9から12の間| |
- | |V30-V31|住居|L3でコード化されている?V30+V31は9か10| | + | |V30-V31|住居|L3でコード化されている、なぜかV30+V31は9か10| |
- | |V32-V34|自動車|L3でコード化されている?V32+V33+V34は9から11の間| | + | |V32-V34|自動車|L3でコード化されている、なぜかV32+V33+V34は9から11の間| |
- | |V35-V36|健康保険|L3でコード化されている?V35+V36は9か10| | + | |V35-V36|健康保険|L3でコード化されている、なぜかV35+V36は9か10| |
- | |V37-V41|収入|L3でコード化されている?V37+V38+V39+V40+V41は9から13の間| | + | |V37-V41|収入|L3でコード化されている、なぜかV37+V38+V39+V40+V41は9から13の間| |
- | |V42|平均収入|L3でコード化されている?| | + | |V42|平均収入|L3でコード化されている| |
- | |V43|購買力|L3でコード化されている?1から8の間。| | + | |V43|購買力|L3でコード化されている、1から8の間。| |
|V44-V64|各種保険支払い額|L4でコード化| | |V44-V64|各種保険支払い額|L4でコード化| | ||
|V65-V85|各種保険契約件数|件数| | |V65-V85|各種保険契約件数|件数| | ||
メモの確認用のコード。 | メモの確認用のコード。 | ||
- | < | + | |
< | < | ||
table((tic.learn$V16+tic.learn$V17+tic.learn$V18)) | table((tic.learn$V16+tic.learn$V17+tic.learn$V18)) | ||
行 46: | 行 45: | ||
</ | </ | ||
- | </ | ||
== 各変数のコーディング == | == 各変数のコーディング == | ||
行 142: | 行 140: | ||
|8|f 10.000 - 19.999| | |8|f 10.000 - 19.999| | ||
|9|f 20.000 - ?| | |9|f 20.000 - ?| | ||
+ | |||
+ | == 参考 == | ||
+ | |||
+ | kernlabパッケージに、加工済みのデータが入っていて、それを使うこともできる。 | ||
+ | |||
+ | < | ||
+ | install.packages(c(" | ||
+ | tic.learn <- ticdata[1: | ||
+ | tic.eval <- ticdata[5823: | ||
+ | </ | ||
+ | |||
+ | === 今回の課題 === | ||
+ | == 概要 == | ||
+ | |||
+ | * もっと大きな変数の組み合わせで、同じ事を試みよ。その際に生じる幾つかの困難を乗り越えよ。 | ||
+ | * CoIL 2000では、訪問する800人を選べ、という課題になっていたが、この課題では訪問する人数も各自で決めて良い。 | ||
+ | |||
+ | == 準備 == | ||
+ | |||
+ | < | ||
+ | install.packages(c(" | ||
+ | </ | ||
+ | |||
+ | これでエラーが出る場合には、[[https:// | ||
+ | |||
+ | < | ||
+ | library(mvpart) | ||
+ | library(gam) | ||
+ | library(MASS) | ||
+ | library(kernlab) | ||
+ | </ | ||
+ | |||
+ | 以上の4つのライブラリを、この課題では使う可能性がある。 | ||
+ | |||
+ | == データの読み込み == | ||
+ | |||
+ | < | ||
+ | tic.leaan <- read.table(" | ||
+ | tic.eval <- read.table(" | ||
+ | tic.test <- read.table(" | ||
+ | tic.eval <- cbind(tic.eval, | ||
+ | colnames(tic.eval)[86] <- " | ||
+ | rm(tic.test) | ||
+ | </ | ||
+ | |||
+ | == 少し加工する == | ||
+ | |||
+ | 以下の6行は、実行しない方がいい場合もある。 | ||
+ | |||
+ | < | ||
+ | tic.learn$V1 <- as.factor(tic.learn$V1) | ||
+ | tic.learn$V5 <- as.factor(tic.learn$V5) | ||
+ | tic.learn$V86 <- as.factor(tic.learn$V86) | ||
+ | tic.eval$V1 <- as.factor(tic.eval$V1) | ||
+ | tic.eval$V5 <- as.factor(tic.eval$V5) | ||
+ | tic.eval$V86 <- as.factor(tic.eval$V86) | ||
+ | </ | ||
+ | |||
+ | あとはそのまま。 | ||
+ | |||
+ | == 考えたルールに基づく対象限定 == | ||
+ | |||
+ | 各変数に閾値を設けてルールを生成したとする。 | ||
+ | たとえば、「V47が5.5以上かつV44が1未満」または「V47が5.5以上かつV1が{1, | ||
+ | 次のように記す。 | ||
+ | |||
+ | < | ||
+ | (tic.eval$V47> | ||
+ | </ | ||
+ | |||
+ | 「& | ||
+ | |||
+ | このルールを検証用データに適用するには、 | ||
+ | |||
+ | < | ||
+ | tic.eval.visit <- (tic.eval$V47> | ||
+ | </ | ||
+ | |||
+ | と、訪問するか否かを二値(TRUE, | ||
+ | このモデルに予測に基づいた訪問の成果を検証するには、訪問対象のリストtic.visitと検証用データの正解V86のクロス集計を行えばよい。 | ||
+ | |||
+ | < | ||
+ | table(tic.eval.visit) | ||
+ | |||
+ | FALSE TRUE | ||
+ | | ||
+ | |||
+ | table(tic.eval.visit, | ||
+ | |||
+ | tic.eval.visit | ||
+ | FALSE 2878 151 | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ここでは、訪問対象に884+87=971人を選定し、そのうちの87人が実際に契約してくれる人だったことになる。 | ||
+ | 契約率は87/ | ||
+ | < | ||
+ | (884+151)/ | ||
+ | </ | ||
+ | で25.9%となる。 | ||
+ | |||
+ | == モデルに基づく対象限定 == | ||
+ | |||
+ | 学習したモデルに基づいて、訪問対象を狭めるには、predict()という関数を用いて、訪問対象か否かというリストを作成する。 | ||
+ | まず、設定まで調整したモデルを、学習用データ(tic.learn)から得る。 | ||
+ | |||
+ | < | ||
+ | tic.rpart <- rpart(V86~., | ||
+ | </ | ||
+ | |||
+ | 次に、このモデル(ここではtic.rpart)を検証用データ(tic.eval)に適用して、契約してくれるか否かの予測を行う。 | ||
+ | この際、0.05という閾値も調整の必要がある。 | ||
+ | |||
+ | < | ||
+ | tic.eval.visit <- predict(tic.rpart, | ||
+ | </ | ||
+ | |||
+ | このモデルに予測に基づいた訪問の成果を検証するには、訪問対象のリストtic.visitと検証用データの正解V86のクロス集計を行えばよい。 | ||
+ | |||
+ | < | ||
+ | table(tic.eval.visit) | ||
+ | |||
+ | tic.eval.visit | ||
+ | FALSE TRUE | ||
+ | | ||
+ | |||
+ | table(tic.eval.visit, | ||
+ | |||
+ | tic.eval.visit | ||
+ | FALSE 2310 79 | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ここでは、訪問対象に1452+159=1611人を選定し、そのうちの159人が実際に契約してくれる人だったことになる。契約率は159/ | ||
+ | また誤判別率は | ||
+ | < | ||
+ | (79+1452)/ | ||
+ | </ | ||
+ | で38.275%となる。 | ||
+ | |||
+ | == 想定される困難 == | ||
+ | |||
+ | 次の1行を実行すると、かなり時間がかかってエラーになる。 | ||
+ | < | ||
+ | tic.glm.step <- step(glm(V86~., | ||
+ | </ | ||
+ | |||
+ | 次の4行、いずれもエラーになる。変数間の関係が悪すぎるよう。変数の意味を考えて、追加しないといけないかも。 | ||
+ | |||
+ | < | ||
+ | tic.glm <- glm(V86~V1+V2+V3+V4+V5+V6+V7+V8+ | ||
+ | V11+V12+ | ||
+ | V21+V22+V23+ | ||
+ | V33+V34+V35+ | ||
+ | V42+V43+V44+V45+V46+V47+V48+V49+V50+ | ||
+ | V51+V52+V53+V54+V55+V56+V57+V58+V59+V60+ | ||
+ | V61+V62+V63+V64+V65+V66+V67+V68+V69+V70+ | ||
+ | V71+V72+V73+V74+V75+V76+V77+V78+V79+V80+ | ||
+ | V81+V82+V83+V84+V85, | ||
+ | table(predict(tic.glm, | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | tic.glm <- glm(V86~ | ||
+ | V11+V12+ | ||
+ | V21+V22+V23+ | ||
+ | V33+V34+V35+ | ||
+ | V42+V43+V44+V45+V46+V47+V48+V49+V50+ | ||
+ | V51+V52+V53+V54+V55+V56+V57+V58+V59+V60+ | ||
+ | V61+V62+V63+V64+V65+V66+V67+V68+V69+V70+ | ||
+ | V71+V72+V73+V74+V75+V76+V77+V78+V79+V80+ | ||
+ | V81+V82+V83+V84+V85, | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | tic.glm <- glm(V86~V44+V45+V46+V47+V48+V49+V50+ | ||
+ | V51+V52+V53+V54+V55+V56+V57+V58+V59+V60+ | ||
+ | V61+V62+V63+V64+V65+V66+V67+V68+V69+V70+ | ||
+ | V71+V72+V73+V74+V75+V76+V77+V78+V79+V80+ | ||
+ | V81+V82+V83+V84+V85, | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | tic.glm <- glm(V86~V44+V45+V46+V47+V48+V49+V50+ | ||
+ | V51+V52+V53+V54+V55+V56+V57+V58+V59+V60+ | ||
+ | V61+V62+V63+V64, | ||
+ | </ | ||
+ | |||
+ | 次の1行を実行すると、不契約ばかり。 | ||
+ | < | ||
+ | tic.rpart <- rpart(V86~., | ||
+ | </ | ||
+ | |||
+ | 次の1行は、動かない。 | ||
+ | < | ||
+ | tic.gam <- gam(V86~V1+s(V2)+s(V3)+s(V4)+V5+s(V6)+s(V7)+s(V8)+s(V9)+s(V10)+ | ||
+ | s(V11)+s(V12)+s(V13)+s(V14)+s(V15)+s(V16)+s(V17)+s(V18)+s(V19)+s(V20)+ | ||
+ | s(V21)+s(V22)+s(V23)+s(V24)+s(V25)+s(V26)+s(V27)+s(V28)+s(V29)+s(V30)+ | ||
+ | s(V31)+s(V32)+s(V33)+s(V34)+s(V35)+s(V36)+s(V37)+s(V38)+s(V39)+s(V40)+ | ||
+ | s(V41)+s(V42)+s(V43)+s(V44)+s(V45)+s(V46)+s(V47)+s(V48)+s(V49)+s(V50)+ | ||
+ | s(V51)+s(V52)+s(V53)+s(V54)+s(V55)+s(V56)+s(V57)+s(V58)+s(V59)+s(V60)+ | ||
+ | s(V61)+s(V62)+s(V63)+s(V64)+s(V65)+s(V66)+s(V67)+s(V68)+s(V69)+s(V70)+ | ||
+ | s(V71)+s(V72)+s(V73)+s(V74)+s(V75)+s(V76)+s(V77)+s(V78)+s(V79)+s(V80)+ | ||
+ | s(V81)+s(V82)+s(V83)+s(V84)+s(V85), | ||
+ | </ | ||
+ | |||
+ | s()が使えるのはデータが4種類以上ある時だけ、というメッセージが出るので、各変数の値の数を数えて、3個以下のものだけ表示させてみる。 | ||
+ | < | ||
+ | for( j in c(1:86) ) { | ||
+ | tmp <- table(tic.learn[, | ||
+ | if(dim(tmp)< | ||
+ | print(j) | ||
+ | print(tmp) | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | これを反映させると、こうなる。 | ||
+ | < | ||
+ | tic.gam <- gam(V86~V1+s(V2)+s(V3)+s(V4)+V5+s(V6)+s(V7)+s(V8)+s(V9)+s(V10)+ | ||
+ | s(V11)+s(V12)+s(V13)+s(V14)+s(V15)+s(V16)+s(V17)+s(V18)+s(V19)+s(V20)+ | ||
+ | s(V21)+s(V22)+s(V23)+s(V24)+s(V25)+s(V26)+s(V27)+s(V28)+s(V29)+s(V30)+ | ||
+ | s(V31)+s(V32)+s(V33)+s(V34)+s(V35)+s(V36)+s(V37)+s(V38)+s(V39)+s(V40)+ | ||
+ | s(V41)+s(V42)+s(V43)+s(V44)+s(V45)+s(V46)+s(V47)+s(V48)+s(V49)+s(V50)+ | ||
+ | s(V51)+s(V52)+s(V53)+s(V54)+s(V55)+s(V56)+ | ||
+ | s(V61)+ | ||
+ | s(V71)+s(V72)+s(V73)+s(V74)+ | ||
+ | V81 + V82 +s(V83)+ | ||
+ | </ | ||
+ | |||
+ | さらにここから次の1行を実行すると、エラーになる。 | ||
+ | < | ||
+ | tic.gam.step <- step(gam(V86~V1+s(V2)+s(V3)+s(V4)+V5+s(V6)+s(V7)+s(V8)+s(V9)+s(V10)+ | ||
+ | s(V11)+s(V12)+s(V13)+s(V14)+s(V15)+s(V16)+s(V17)+s(V18)+s(V19)+s(V20)+ | ||
+ | s(V21)+s(V22)+s(V23)+s(V24)+s(V25)+s(V26)+s(V27)+s(V28)+s(V29)+s(V30)+ | ||
+ | s(V31)+s(V32)+s(V33)+s(V34)+s(V35)+s(V36)+s(V37)+s(V38)+s(V39)+s(V40)+ | ||
+ | s(V41)+s(V42)+s(V43)+s(V44)+s(V45)+s(V46)+s(V47)+s(V48)+s(V49)+s(V50)+ | ||
+ | s(V51)+s(V52)+s(V53)+s(V54)+s(V55)+s(V56)+ | ||
+ | s(V61)+ | ||
+ | s(V71)+s(V72)+s(V73)+s(V74)+ | ||
+ | V81 + V82 +s(V83)+ | ||
+ | </ | ||
+ | |||
+ | === おまけ === | ||
+ | |||
+ | AdaBoostを適用するには、adaパッケージをインストールする。 | ||
+ | < | ||
+ | install.packages(c(" | ||
+ | </ | ||
+ | |||
+ | 決定木を弱学習機械として用いるには例えば、 | ||
+ | < | ||
+ | tic.ada <- ada(V86~., | ||
+ | data=tic.learn, | ||
+ | iter=100, | ||
+ | control=rpart.control(maxdepth=1, | ||
+ | </ | ||
+ | とする。rpart.controlの中身は、 | ||
+ | * maxdepth=1が1回だけ分岐せよ | ||
+ | * cp=-1は不純度によらず必ず分岐せよ | ||
+ | * minsplit=0は親ノードのレコード数が幾つでも必ず分岐せよ | ||
+ | と、必ず1段の決定木を学習で得ること、と指定されている。 | ||
+ | |||
+ | これでiterとmaxdepthを変えると、もしかして良い訪問案が学習できるかもしれない? | ||
+ | ただしこの二つのパラメータを大きくすると、計算時間が増大するので要注意。 | ||
+ | iterに比例し、2のmaxdepth乗にも比例して、増えていく。 | ||