重回帰分析を実装する前に、少しでも精度を上げるために、データの前処理をする必要があります。
1.機械学習のアルゴリズムに適用できる形に変換する前処理
2.モデルの精度を向上させるために行う前処理
の2つのフェーズに分けることができますので、それぞれ書いておきます。
1.機械学習のアルゴリズムに適用できる形に変換する前処理
1-1.データの確認
1-2.重複行の確認
1-3.欠損値処理
1-4.カテゴリカル変数処理
1-5.重回帰分析の実装
以上のような流れで機械学習のアルゴリズムに適用できる形に変換していきます。
重複行の確認
重複の確認には、df.duplicated()
を使用します。
()
の中をkeep=False
にすることで、重複データをすべてTrue, それ以外をFalseと返します。
# 重複行の数の確認
df.duplicated(keep=False).value_counts()
# 重複行の削除
df.drop_duplicates()
欠損値処理
欠損値とは、NaN
と表記されているもののことです。csvの中でいう空白のセルです。
欠損値の確認は、df.isnull()
で確認できます。
df.isnull().sum()
で各列ごとの欠損値の数の合計を確認できます。
欠損値の除去
df.dropna()
で欠損値が含まれる全ての行が削除されます。
df.dropna(subset=['列名'], axis=0)
とすると、'列名'
の列に欠損値が含まれている行を削除できます。
列の中身のほとんどが欠損値の場合は、列ごと削ってしまってもいいかもしれません。
その場合は、df.drop(labels='列名', axis=1)
で列を削除できます。
欠損値の補完
欠損値を平均値や中央値で補完する時もあります。
どちらを使うかはケースバイケースです。
正規分布に近いような分布をしている時は、平均値を当てはめるといいかもしれません。
df.describe()
でデータ統計量の確認ができます。
plt.hist(df['列名']
で列の中のデータがどのような分布をしているか可視化できます。
補完する時は.fillna()
を使います。
# 欠損値を平均値で補完
df.fillna({'列名':df['列名'].mean()})
# 欠損値を中央値で補完
df.fillna({'列名':df['列名'].median()})
カテゴリカル変数処理
文字列データ含め、カテゴリを表すデータをカテゴリカル変数といいます。質的変数とも呼ばれます。
例えば「男性, 女性」というような文字列データはカテゴリカル変数です。
また、男性を 0, 女性を 1 と置き換えた「0,1」のデータも、値としては文字列ではなく数値ですが、カテゴリカル変数です。
補完する時は、最頻値を使用するケースが多いです。
最頻値は.mode()
で取得できます。
どのような文字が入っているかを調べるときは.unique()
で見ることができます。
# 最頻値(abc)を使用して欠損値を補完
df.fillna({'abc':df['列名'].mode()[0]})
Label Encodeing
Label Encodingは各カテゴリに 0, 1, 2, ... と数値を割り振る変換です。
scikit-learnの中でも前処理系のものを取り扱うにはpreprocessing
を使用します。
# モデルの宣言
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(df['列名'])
# モデルの適用
le.transform(df['列名'])
どのカテゴリがどのラベルに変換されたかはle.classes_
で確認できます。
One-Hot Encoding
One-Hot Encodingはダミー変数化とも言われ、各カテゴリの値ごとに0, 1の列を作成します。
カテゴリの値の種類の数だけ列が増えます。
pd.get_dummies()
でできます。
2.モデルの精度を向上させるために行う前処理
2-1.特徴量エンジニアリング
2-2.外れ値除去
特徴量エンジニアリング
特徴量エンジニアリングとは現在あるデータを用い、より有用なデータを作成することです。
例えば、「カツオ、リンゴ、レモン、イワシ、ブタ、ウシ」という文字列が含まれる列の場合、
カツオとイワシは魚なので、1
リンゴとレモンは果物なので、2
ブタとウシは肉なので、3
のようにグルーピングしてみると、分析結果が良くなるかもしれません。
# クラス分けのリストの定義
class_1 = ['カツオ', 'イワシ']
class_2 = ['リンゴ', 'レモン']
class_3 = ['ブタ', 'ウシ']
# それぞれを置換するリストの作成
food = []
for i in df['列名']:
if i in class_1:
food.append(1)
elif i in class_2:
food.append(2)
elif i in class_3:
food.append(3)
# データフレームに列を追加
df['food'] = food
このように、多いカテゴリをより有用な少ないカテゴリに分け直すような方法以外にも、
- a複数変数をかけ合わせて、交互作用特徴量を得る
- ある変数の累乗をとって、多項式特徴量を得る
- ある変数の対数をとる
- 連続値を離散値に変換する(ビニング)
など、さまざまな方法があります。
外れ値除去
外れ値を除去する時は、「3σ法(平均値ベース)」と「ハンベル判別法(中央値ベース)」の2つの手法が主です。
基本的には3σ法を採用し、それでうまく外れ値を検知出来ない場合はハンペル判別法を使うといいです。
ハンペル判別法は外れ値の数が多く、平均が引っ張られている場合などに有用な手法です。
3σ法
# 3σ法
mu = df['列名'].mean() # 平均値
sigma = df['列名'].std() # 標準偏差
df = df[(mu - 3 * sigma <= df['列名']) & (df['列名'] <= mu + 3 * sigma)]
ハンペル判別法
3σ法における平均値が中央値に、標準偏差が中央絶対偏差(MAD)に変わります。
# ハンペル判別法
median = df['列名'].median() #中央値
MAD = 1.4826 * np.median(abs(df['列名']-median))
df = df[(median - 3 * MAD <= df['列名']) & (df['列名'] <= median + 3 * MAD)]