【R】検索結果から検索アルゴリズムの精度評価【kaggle,SVM,NLP】

今回は[rerockさんのカーネル](https://www.kaggle.com/wliang88/extra-engineered-features-w-svm)を紹介しながら写経していきます。

コンペの趣旨は、検索アルゴリズムが正確に働いているかってどうやって評価するのか？
検索に使ったクエリと、検索結果と、その検索結果の説明文から、クエリと結果の精度を確かめよう。ってコンペ。

261の検索クエリを用意して、検索結果と結果の説明文と、関連度の評価(1~4点)の入ったデータがある。
これをtrainとして、モデルを考え、
testのクエリや結果、結果の説明文から関連度を予測する。

#例

```R
#ID
8	

#query
oakley polarized radar	

#result(title)
Oakley Sunglasses - Radar Path Polished Black/Gray Sunglasses	

#description
Durability and all-day comfort of lightweight, stress-resistant O MATTER® frame material Integrated surge ports to channel cooling airflow Optimized peripheral view and side coverage of Polari...	

#median_relevance
3	

#relevance_variance
1.166
```


#早速やってみる

```R
library(readr)
library(Matrix)
library(Metrics)
library(tm)
library(SnowballC)
library(e1071)
library(SparseM)
library(caTools)
train <- read_csv("C:/train.csv")
test  <- read_csv("C:/test.csv")
```

ごみの削除
httpの要素、拡張子とかフォントとかを消す
for文でごみリストの中身に一致するものを空白に置き換える関数を定義

```R
rm_garbage = function(string){
  garbage = c("<.*?>", "http", "www","img","border","style","px","margin","left", "right","font","solid","This translation tool is for your convenience only.*?Note: The accuracy and accessibility of the resulting translation is not guaranteed")
  for (i in 1:length(garbage)){
    string = gsub(garbage[i], "", string)
  }
  return (string)
}
```


ゴミを取り除いたものをproductという新しい列に格納する

```R
train$product_description = lapply(train$product_description,rm_garbage)
test$product_description = lapply(test$product_description,rm_garbage)
```

```R
test_id = test$id
train_relevance = as.factor(train$median_relevance)
train_variance = train$relevance_variance
train$median_relevance = NULL
train$relevance_variance = NULL
```

```R
n_words = function(string){return(sapply(gregexpr("[[:alpha:]]+", string), function(x) sum(x > 0)))}
```
gregexpr パターンにマッチした場合、その単語の文字の位置を数字として返す
[[:alpha:]]では正規表現A-Za-z大文字も小文字も対象としているらしい。upperにすると大文字だけ。

 

```R
train_pt_words = apply(train[3],1,n_words)
test_pt_words = apply(test[3],1,n_words) 
pt_words = c(train_pt_words,test_pt_words)
```

pt_wordsのなかには、a-zもしくはA-Zではじまる単語が何個含まれているのかをカウントしている。
sumを行わないと、単語の開始点が何文字目であるかを全単語について返すので、合計9万単語の開始地点が羅列されることになる。
（trainの中に何個単語が含まれているかを調べたいなら、sumをとらずにlengthをつかったら調べられる。）


```R
#------------ bag of words 
DTM = function(corpus){
dtm = DocumentTermMatrix(corpus,
  control=list(tolower=TRUE,#大文字は小文字に変換する
    removePunctuation=TRUE,#ピリオド削除
    removeNumbers=TRUE,#数字削除
    stopwords=TRUE,
    stemming=TRUE,
    weighting=function(x) weightTfIdf(x,normalize=T)))
  return (dtm)
}
```

tdidf処理はDocumentTermMatrix関数のweightingオプションに組み込まれているみたい。
言語処理のあたり不明なので[このあたりを参照した](https://stackoverflow.com/questions/14820590/trying-to-get-tf-idf-weighting-working-in-r)←stackoverflowへ

```R
combi = rbind(train,test)
all_text = Corpus(VectorSource(combi$query))
dtm = DTM(all_text)
```

このあたりなにやってるのか分からないので個人的興味で確認。

```R
names(dtm)
dtm$dimnames
str(dtm)
```

単語名433個 ncolに一致
testとtrain合計すると32671行になる
dtmのnrowは一致する
jとiは73096になっている。約二倍だが正確に二倍ではない。

dtm$vはどうやって計算されているのか?
なんかコーパスってのが関係してる?

```
    コーパス（corpus）とは、言語学において、自然言語処理の研究に用いるため、自然言語の文章を構造化し大規模に集積したもの。
    コーパス - Wikipedia
単なる文章の集合体ではなく、文章に対してその意味や構造などを付与した大規模なデータのこと。作成にはとてつもない人手と手間がかかる。
例えば、京都大学テキストコーパスは、毎日新聞の記事に対して、形態素(名詞・動詞など)と構文情報(文節の係り受け構造)を付与した約4万文のデータである。自動で付与された解析データを全て人がチェックすることで作成された。
```

文字の数値化は何か本を読んだほうが体系的に理解できそうなのでいったん置いておく。
コサイン類似度的な？


#もとにもどって

```R
df_q = as.data.frame(as.matrix(dtm))
colnames(df_q) = paste("q_",colnames(df_q),sep="")
combi = cbind(df_q,pt_words)  
```


```R
#-------------------------------- svm to predict relevance 
# Use naiveBayes to test various of ideas.. svm takes too long to run  
new_train = combi[1:10158,]
new_test = combi[10159:32671,]

#---separated the train set into train and test sets to play around with the "cost" variable in the svm. 
#---did fixed set cross validation to tune the model according to the in sample ScoreQuadraticWeightedKappa. 

sparse_train = Matrix(as.matrix(new_train),sparse=T)
sparse_test = Matrix(as.matrix(new_test),sparse=T)

model = svm(sparse_train,train_relevance, kernel="linear", cost=0.3)
pred = predict(model,sparse_test)
Newsubmission = data.frame(id=test_id, prediction = pred)
write.csv(Newsubmission,"model.csv",row.names=F) 
```

作ったモデルを出力すると、一致度は

```R
0.60718
```

になるらしい。

SVMでの言語処理について一つ流れを追ってみました。
言語処理については齧るどころか触れたこともなかったのでどんなプロセスでやっていくのか勉強していきたいです。

#以上