【R】"Need numeric dependent variable for regression."の原因と対応

# はじめに
今年は機械学習の勉強をやり直すことにしました。昨年はやる気とか伏せてしまったこともあって機械学習の勉強を断念したのですが、競馬予想とか株価予想とかの記事を見かけるようになって、本格的にやってみたいなと思い始めました。

# Rの導入
参考にしようと思ったサイトが R だったんだけど、Pythonに移植しながら覚えていけばいいかと思って、R と R Studioを導入しました。
[MacにRとR Studioをインストール](https://qiita.com/azzeten/items/1031c788ed093d3b3946)

* Mac OS Big Sur バージョン 11.1
* R 4.0.3
* R Studio 1.3.1093

# 線形SVMでエラー
いきなりつまづきました。

[機械学習でサザエさんと本気でじゃんけんしてみた①](https://r-std.hatenablog.com/entry/2018/12/30/215859)

```R
###データの読み込み
sze_row=read.csv("2017sze.csv",header = T)
sze=sze_row[,-9]

#1992年～2016年までを学習用、2017年分をテスト用とする
train=c(1:1254)
test=c(1255:1302)

###seedはサザエさん(3383)とする
set.seed(3383)

###線形SVM
library(e1071)
sze.svm=svm(X~.,data=sze[train,],
            method="C-classification",
            kernel="linear",
            cost=2.5)
test.svm=predict(sze.svm, sze[test,])
svm.tab=table(sze[test,1],test.svm)
svm.tab
sum(svm.tab[row(svm.tab)==col(svm.tab)])/sum(svm.tab) #識別率
```

線形SVMで下記エラーが出てしまう。

```
svm.default(x, y, scale = scale, ..., na.action = na.action) でエラー: 
  Need numeric dependent variable for regression.
```

Google翻訳だと「回帰には数値従属変数が必要です。」となります。もう、なんなん？

## 調査
「Need numeric dependent variable for regression.」で検索してみるのですが、最初に見つかるのが下記サイトですね。
>Try to specify that you wish a classification rather than regression
>[SVM:Need numeric dependent variable for regression](https://stackoverflow.com/questions/43499772/svmneed-numeric-dependent-variable-for-regression)

Google翻訳だと「回帰ではなく分類を希望することを指定してみてください」となっているが、"C-classification"で分類を指定しています。
他のデータなら使えるのか確認するため、「svm C-classification iris」で検索してみて「[農学情報科学](https://axa.biopapyrus.jp/machine-learning/svm/r/)」のサイトにあるプログラムは正常に動作することが分かった。

再度、「Need numeric dependent variable for regression.」で検索で幾つか探っていった時に、下記情報が引っかかた。

>You have to make sure that all of the columns in your data.frames are
of the right type. If you're doing classification, change your label
column to a factor. In your case, where you are explicitly passing a y
vector, instead of this:
>
>R> model<- svm(train,cl);
>
>do this
>
>R> cl <- factor(cl)
>R> model <- svm(train, cl)
>https://stat.ethz.ch/pipermail/r-help/2010-June/244021.html

Google翻訳だと「分類を行う場合は、因子の列に変更してください」となり、上記では `factor`関数で変換しています。
`str`関数を使用することで対象のデータ型が分かるので実行してみると、`X` の型は `chr` になっています。

```
> str(sze[train,])
'data.frame':	1254 obs. of  8 variables:
 $ X    : chr  "C" "P" "G" "C" ...
 $ X1   : chr  "G" "C" "P" "G" ...
 $ X2   : chr  "P" "G" "C" "P" ...
 $ X3   : chr  "G" "P" "G" "C" ...
 $ Q    : int  1 0 0 0 0 0 0 0 0 0 ...
 $ Grate: num  0.333 0.361 0.394 0.333 0.37 ...
 $ Crate: num  0.333 0.278 0.303 0.333 0.259 ...
 $ Prate: num  0.333 0.361 0.303 0.333 0.37 ...
```

正常に実行できた、irisデータはどうなっているのかをみると、`Species` の型は `Factor` になっていました。

```
> str(iris)
'data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
```

型を `Factor` に変更すればできそうだ。でも、どうやればいいのやら・・・「r csv 読み込み factor」で検索しました。
>引数にstringsAsFactors = Fを指定して、因子型化を防ぎます。
>[R：read.csv / read.tableで型と列名を指定して読み込む。](https://qiita.com/dokokano_panda/items/f12d1d2e4c7f63020440)

逆に、`stringsAsFactors = T`を指定すれば、因子型になりそうだ。

## 原因
>Ｒをバージョン４にアップデートした場合の注意点
(中略)
read.csv などのテキストファイルから表形式のデータを読み込む関数では、stringsAsFactors = FALSE が既定値になりました。なので、バージョン３以前と同じ動作をさせるときには stringsAsFactors = TRUE を指定する必要があります。
https://www.yodosha.co.jp/correction/9784758120951.html

Ｒをバージョン4にしたことにより、read.csvのデータ読み込みでデフォルトの型が因子型から文字列型になったため。
参考サイトのプログラムは、まだバージョン3を使用していた。

## 対応
read.csv などのテキストファイルから表形式のデータを読み込む関数では、`stringsAsFactors = TRUE` を指定する

```
sze_row=read.csv("2017sze.csv",header = T, stringsAsFactors=T)
```

これにより、因子型になりました。

```
> str(sze[train,])
'data.frame':	1254 obs. of  8 variables:
 $ X    : Factor w/ 3 levels "C","G","P": 1 3 2 1 1 3 2 1 3 2 ...
 $ X1   : Factor w/ 3 levels "C","G","P": 2 1 3 2 1 1 3 2 1 3 ...
 $ X2   : Factor w/ 3 levels "C","G","P": 3 2 1 3 2 1 1 3 2 1 ...
 $ X3   : Factor w/ 3 levels "C","G","P": 2 3 2 1 3 2 1 1 3 2 ...
 $ Q    : int  1 0 0 0 0 0 0 0 0 0 ...
 $ Grate: num  0.333 0.361 0.394 0.333 0.37 ...
 $ Crate: num  0.333 0.278 0.303 0.333 0.259 ...
 $ Prate: num  0.333 0.361 0.303 0.333 0.37 ...
```

これでようやっと、エラーがなくなり結果が出力されるようになりました。

```
   test.svm
     C  G  P
  C 13  2  2
  G  2  9  4
  P  5  1 10
```

# 最後に
R をまともにさわってこなかったので因子型自体を今回初めて知りました。Ｒをバージョン4にしたことでデフォルト設定が変わったのはキツかったな。
原因が分かってしまえば納得はするんですが、それが分かるまでが辛かったので、調査方法から原因にたどり着くまで、グダグダと書いてしまいました。
これでやりたいことがやっと進めることができる。