データの前処理(preproceccing)

機械学習ではデータの前処理が大事になってくる。

 

 

例えば、以下のようなデータを考える

Country

Age

Salary

Purchased

France

44

72000

No

Spain

27

48000

Yes

Germany

30

54000

No

Spain

38

61000

No

Germany

40

 

Yes

France

35

58000

Yes

Spain

 

52000

No

France

48

79000

Yes

Germany

50

83000

No

France

37

67000

Yes

 

1列目は国、2列目は年齢、3列目は給料、4列目は購入したかどうかのデータが入っている。

 

機械学習で大事なことは、上記のようなデータセットが与えられた時、特徴行列と変数ベクトルに区別することである。

 

上記の例で考えると、予測したいものは購入したかどうかなので、特徴行列は1〜3行目から10列目の行列、変数ベクトルは4行目から10列目のものである。

 

そして区別するためのデータセットをpandasによって作っていく。

 

dataset = pd.read_csv('Data.csv') これで上記のcsvファイルを読み込む

 

X = dataset.iloc[:,:-1].values これが特徴行列になる

[]の左側が行をしている所で、右側が列を指定している所である。今回の場合、行は全ての行が欲しいので何も選択せず、列は1番右の列以外のものを選択している。

 

y = dataset.iloc[:,3].values これが変数ベクトルになる。

1番右の列の全ての行のデータが欲しいのでこのような記述になる。

 

欠損の処理

データを見ると所々抜けがあることがわかる。こういったデータを機械学習に使うにはデータを削除するか、抜けを埋めてあげる必要がある。

 

大切なデータを削除するのは危険なので普通はデータを埋める方式を使う。

 

scikitlearnのpreproceccingからImputerクラスを使う。

 

具体的な使い方

from sklearn.preprocessing import Imputer

#NaNの部分をaxis=0(列)の平均値(strategy="mean")で埋める

imputer = Imputer(missing_values="NaN",strategy="mean",axis=0)
imputer = imputer.fit(X[:,1:3])
X[:,1:3] = imputer.transform(X[:,1:3])

 

fitとtransformの違いは??

fitは適用したいオブジェクトから指定した情報を引き抜く(上の例の場合、欠損値と列の平均値)

一方、transformはその変換を適用する時に使う

 

categorical variableとは?

上のデータの例だとCountryとPurchasedである。国はFrance、Spain、Germanyの3つに分かれており、PurchasedはYesとNoに分かれている。

 

機械学習では数式が用いられるため、このようなtextの形だと問題がある。

 

なのでそれらをtextからnumberにencodeする必要がある。

 

エンコードの仕方

sklearn.preprocessingのLabelEncoderクラスを使う。

from sklearn.preprocessing import LabelEncoder
labelencoder_X = LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])

 

 

Xの中身

[0, 44.0, 72000.0],
[2, 27.0, 48000.0],
[1, 30.0, 54000.0],
[2, 38.0, 61000.0],
[1, 40.0, 63777.77777777778],
[0, 35.0, 58000.0],
[2, 38.77777777777778, 52000.0],
[0, 48.0, 79000.0],
[1, 50.0, 83000.0],
[0, 37.0, 67000.0]]

 

問題点

無事に国名が0~2にエンコードされたが、この問題点はなんだろうか。

機械学習をする上で、このような数字に変換してしまうと、SpainはFranceとGermanyより大きく、またGermanyはFranceより大きく、Franceは1番小さいという意味がない分類分けが影響を与えてしまう可能性がある。

 

それを解決するためにOneHotEncoderを使う。

 

OneHotEncoderの使い方

from sklearn.preprocessing import OneHotEncoder

onehotencoder = OneHotEncoder(categorical_features = [0]) #引数はどの列に対して
X = onehotencoder.fit_transform(X).toarray()

f:id:minmin_std:20191222153954j:plain

0~2の列がそれぞれ変換された国名に対応しており、1だったらその国名に該当することを意味する。例えば0行目0列目は1で0行目1列目0行目2列目は0なので0行目のデータはFranceのデータである。

 

このようにすることで国名によって数字の大きさが変わることがなくなるので、それが機械学習に反映されなくなり、良い。

 

fit_transformの働きは??

 LabelEncoderクラスから呼ばれるfit_transformはcategorical strings(categorical varibales)をintegers(整数)に変換する。Franceは0に、Germanyは1に、Spainは2になる。

OneHotEncoderクラスから呼ばれるfit_transformはラベルによって0か1に分けられた列を作る。分けられた列はdummy variablesと言われる。