LoginSignup
7
7

More than 5 years have passed since last update.

Kaggle何から進めると良いか!?(Kaggle攻略)

Posted at

とりあえず

KaggleのTitanicチュートリアルにおいて、精度を上げるために何をやっていけば良いのか?を上位者のアイディアを参考に前処理フローを整理する。

前処理フロー

データを読み込む

兎にも角にもデータを読み込む。やり方はPandasでDataFrameとして読み込む。
使うコマンド:pd.read_csv()

データを見る

  • 観点1:項目名の意味を書き出す。
  • 観点2:項目毎の欠損データを書き出す。
  • 観点3:数値データと文字データを分類する。(把握するだけでOK)(型:objectが文字データ扱い)

ココが割と重要。欠損データは”消すでは無く”、”補完し利用する”事を優先する。
項目毎の意味を理解しないと欠損データの補完のアイディアが出ない。よって”意味”も大事。
使うコマンド:pd.info()

第一欠損値補完

初めは中央値、平均、ゼロ。から適切なものを入れてみる。

文字データの取り扱いを決める(型:object)

文字データの意味を考え適切な数値データを導出する。

  • 観点1:文字->数値の単一変換ができそうなモノはそのまま変換する。
  • 観点2:複雑なモノは、必要要素だけ抜き出し成分値を導出する。
  • 観点3:わからないモノは、一旦除外する。(最終手段)

Titanicの場合

 [Name]・・・名前 =>観点2
 [Sex]・・・性別 =>観点1
 [Ticket]・・・チケット番号 =>観点2
 [Cabin]・・・部屋番号 =>観点2
 [Embarked]・・・乗船した港 =>観点1

<観点1>
[Sex]・・・性別
male/femaleを数値に置き換える(0,1)
[Embarked]・・・乗船した港
Cherbourg、Queenstown、Southamptonの頭文字C,Q,Sを数値に置き換える(0,1,2)

<観点2>
[Name]・・・名前
パッと見わからない。。。敬称で分類する。(敬称もMr,Miss,Msだけじゃない・・・ 英語だけじゃなく多国語における貴族敬称とかも考えたらしい。)
[Capt,Col,Countess,Don,Dr,Jonkheer,Lady,Major,Master,Miss,Mlle,Mme,Mr,Mrs,Ms,Rev,Sir]
手順
1.まずは名前を単語に分類し、タイトルの一覧を見てみる。

def get_title(name):
    title_search = re.search(' ([A-Za-z]+)\.', name)
    if title_search:
        return title_search.group(1)
    return "" 

for row in train:
    row['honorific'] = row['Name'].apply(get_title)

print(pd.crosstab(train['honorific'], train['Sex']))

2.同じ意味合いのモノはまとめる。

train['honorific'] = train['honorific'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
train['honorific'] = train['honorific'].replace('Mlle', 'Miss')
train['honorific'] = train['honorific'].replace('Ms', 'Miss')
train['honorific'] = train['honorific'].replace('Mme', 'Mrs')

3.敬称を分類し数値に変える。

honorific_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5} 
for row in train: 
    row['honorific'] = row['honorific'].map(honorific_mapping) 
    row['honorific'] = row['honorific'].fillna(0)

[Ticket]・・・チケット番号
パッと見わからない。。。チケットの頭文字で分類する。

手順

1.頭文字を取ってきてグループ化。

for row in train:
    row['Ticket_Lett'] = row['Ticket'].apply(lambda x: str(x)[0])
    row['Ticket_Lett'] = row['Ticket_Lett'].apply(lambda x: str(x)) 
    row['Ticket_Lett'] = np.where((row['Ticket_Lett']).isin(['1', '2', '3', 'S', 'P', 'C', 'A']), row['Ticket_Lett'], np.where((row['Ticket_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0')) 
    row['Ticket_Len'] = row['Ticket'].apply(lambda x: len(x))
train['Ticket_Lett']=train['Ticket_Lett'].replace("1",1).replace("2",2).replace("3",3).replace("0",0).replace("S",3).replace("P",0).replace("C",3).replace("A",3)

[Cabin]・・・部屋番号
パッと見わからない。。。チケットの頭文字で分類する。

手順

1.頭文字を取ってきてグループ化。

for row in train: 
    row['Cabin_Lett'] = row['Cabin'].apply(lambda x: str(x)[0]) 
    row['Cabin_Lett'] = row['Cabin_Lett'].apply(lambda x: str(x)) 
    row['Cabin_Lett'] = np.where((row['Cabin_Lett']).isin([ 'F', 'E', 'D', 'C', 'B', 'A']),row['Cabin_Lett'], np.where((row['Cabin_Lett']).isin(['W', '4', '7', '6', 'L', '5', '8']), '0','0'))

train['Cabin_Lett']=train['Cabin_Lett'].replace("A",1).replace("B",2).replace("C",1).replace("0",0).replace("D",2).replace("E",2).replace("F",1)

他に関連性がありそうなデータを作る

Titanicの場合

 Pclass、Sibsp、Parchに注目。

  • Pclassは何等級のところに乗っていたかを表す。
  • Sibspは乗っていた夫婦と兄弟の人数を表す。
  • Parchは乗っていた親と子供の人数を表す。

これを元に以下を導出する
FamilySize(家族の人数) = Sibsp+Parch+1が
IsAlone(一人かどうか) = FamilySizeが1なら1

train["FamilySize"] = train["SibSp"] + train["Parch"] + 1
for row in train:
    row['IsAlone'] = 0
    row.loc[row['FamilySize'] == 1, 'IsAlone'] = 1

モデリング

 前処理を行ったモノの内数値データのみを使う。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7