AI_ML_DL’s diary

人工知能、機械学習、ディープラーニングの日記

Titanic: Machine Learning from Disaster - 2

Titanic: Machine Learning from Disaster - 2

 

A. Geronさんのテキスト第2章の勉強の成果を試そう!

 

意気込んでとりかかったのはよいが、いきなり、つまづいた。

A. Geronさんのテキストで学んだhousingは、住宅価格を予測するということで、回帰問題、regressionである。

対して、Titanicは、乗客が生存するかどうか予測するという、分類問題、classificationである。

housingは主として数値を扱っていて、唯一のカテゴリーデータocean_proximityは、OneHotEncoderで配列に変換して、回帰問題として扱い、機械学習モデルで扱えるようにした、ということだが、住宅価格の予測に対して、どう作用しているのか、直観的には理解できていない。

分類問題において、数値とカテゴリー(テキスト)はどう扱われているのか。これまでは、明確に意識してこなかったので、今回は、分類問題における数値とテキストの扱い方に注意しながら学習しよう。

 

データ数は、Titanicが、train:891, test:418、housingがtotal:20640である。つまり、Titanicのデータ数は、housingの6.3%である。

このデータ数が少ないことは、overfittingしやすいことを意味している。

 

Alexis Cook's Titanic Tutrialでは、

features = ["Pclass", "Sex", "SibSp", "Parch"]

この4つのattributeを使って、RandomForestClassifierを学習させている。

Pclass(等級), SibSup(兄弟または配偶者の人数), Parch(両親または子供の人数)は、整数、Sexは文字列である。

文字列と整数ならOKということかな。

そうではなく、pd.get_dummys( )を使うことによって、自動的に、

Sex_femaleとSex_maleに分けていて、情報量で表現しているようだ。

X = pd.get_dummies(train_data[features])

        Pclass  SibSp  Parch   Sex_female Sex_male
0         3         1         0             0                 1
1         1         1         0             1                 0
2         3         0         0             1                 0
3         1         1         0             1                 0
4         3         0         0             0                 1

 

分類用のprint(train.columns)機械学習モデルの性能を生かすために、テキストを情報量で表現しなおすこと、数値を、3~10段階くらいにクラス分けして、整数で表現するなどの操作を行なっているようである。

 

少しコードを拝借してみようかな。

print(train.columns)

Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'], dtype='object')

print("Percentage of females who survived:", train["Survived"][train["Sex"] == 'female'].value_counts(normalize = True)[1]*100)

Percentage of females who survived: 74.20

 print("Percentage of Pclass = 1 who survived:", train["Survived"][train["Pclass"] == 1].value_counts(normalize = True)[1]*100)

Percentage of Pclass = 1 who survived: 62.96

#sort the ages into logical categories

train["Age"] = train["Age"].fillna(-0.5)
bins = [-1, 0, 5, 12, 18, 24, 35, 60, np.inf]
labels = ['Unknown', 'Baby', 'Child', 'Teenager', 'Student', 'Young Adult', 'Adult', 'Senior']
train['AgeGroup'] = pd.cut(train["Age"], bins, labels = labels)

#draw a bar plot of Age vs. survival
sns.barplot(x="AgeGroup", y="Survived", data=train)
plt.show()

年齢を分割して、カテゴリーに変換している。

関係なさそうなattributeは消去

train = train.drop(['Cabin'], axis = 1)

train = train.drop(['Ticket'], axis = 1)

すごいなと思ったのは、Nameから、Titleを抽出して、生存率を調べたり、Titleと年齢の相関から、年齢がNaNとなっている人の年齢をTitleから推定したり・・・。

高いスコアを出している人は、データを隅々まで調べて、生存率との相関をとっていることと、生存率との相関が認められないものは捨てている。最後に、予測精度が高い人は、trainとtestをきちんと切り分けているようにみえる。

 

Titanicコンペのnotebookに関するdiscussionを読んでいて感じたこと。 

グリッドサーチによるハイパーパラメータの最適化ができていない。

アンサンブル学習を利用している人が少ない。

RやC++の使い手が凄い。

まあ、初心者用コンペなので、トップコーダーたちは、あまり顔を出していない。

 

5月15日:A. Geronさんのテキストの第2章の復習等

housing.head( )

housing.tail( )

housing.info( )

housing["ocean_proximity"].value_counts( )

housing.describe( )

%matplotlib inline

housing.hist(bins=50, figsize=(20,15))

plt.show( )

from sklearn.model_selection import train_test_split

train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

housing["income_cat"] = pd.cat(housing["mediun_income"],

                                                    bins=[0., 1.5, 3.0, 4.5, 6., np.inf],

                                                    lables=[1, 2, 3, 4, 5])

housing["income_cat"].hist( )

from sklearn.model_selection import StratifiedShuffleSplit

split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)

for train_index, test_index in split.split(housing, housing["income_cat"]):

      strat_train_set = housing.loc[train_index]

      strat_test_set = housing.loc[test_index]

strat_test_set["income_cat"].value_counts( ) / len(strat_test_set)

for set_ in (strat_train_set, strat_test_set):

      set_.drop("incom_cat", axis=1, inplace=True)

housing = strat_train_set.copy( )

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,

      s=housing["population"]/100, lable="population", figsize=(10,7),

      c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,)

plt.legend( )

corr_matrix = housing.corr( )

corr_matrix["median_house_value"].sort_values(ascending=False)

median_house_value     1.000000

median_income             0.687170

total_rooms                   0.135231

housing_median_age    0.114220

from pandas.plotting import scatter_matrix

attributes = ["median_house_value", "median_incom", "total_rooms",                                                       "housing_median_age]

scatter_matrix(housing[attributes], figsize=(12,8))

housing.plot(kind="scatter", x="median_income", y="median_house_value", alpha=0.1)

# create new attribute

housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]

housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]

housing["population_per_household"]=housing["population"]/housing["households"]

# prepare the data

housing = strat_train_set.drop("median_house_value", axis=1)     # X_train

housing_lables = strat_train_set["median_house_value"].copy( )   # y_train

# data cleaning

housing.dropna(subset=["total_bedrooms"])      # option 1

housing.drop("total_bedrooms", axis=1)             # option 2

median = housing["total_bedrooms"].median( ) # option 3

housing["total_bedrooms"].fillna(median, inplace=True) 

# take care of missing values

from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy="median")

# median can only computed on numerical attributes

housing_num = housing.drop("ocean_proximity", axis=1) 

imputer.fit(housing_num)

X = imputer.transform(housing_num)

# handling text and categorical attributes 

housing_cat = housing"ocean_proximity"

from sklearn.preprocessing import OrdinalEncoder

ordinal_encoder = OrdinalEncoder( )

housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)

from sklearn.preprocessing import OneHotEncoder

cat_encoder = OneHotEncoder( )

housing_cat_1hot = cat_encoder.fit_transform(housing_cat)

# custom transformers

from sklearn.base import BaseEstimator, TransformerMixin

class CombinedAttributesAdder(BaseEstimator, TransformerMixin)

# feature scaling

min-max scaling (many people call this normalization)

standardization

# transformation pipelines

# training and evaluating on the training set

from sklearn.linear_model import LinearRegression

from sklearn.metrics import mean_square_error

from sklearn.tree import DecisionTreeRegressor

# cross-validation

from sklearn.model_selection import cross_val_score

tree_reg = DecisionTreeRegressor( )

scores = cross_val_score(tree_reg, housingprepared, housing_lables,

                                        scoring="neg_mean_squared_error", cv=10)

from sklearn.ensemble import RandomForestRegressor

forest_reg = RnadomForestRegressor( )

forest_scores = cross_val_score(forest_reg, housing_prepared, housing_labels,
                scoring="neg_mean_squared_error", cv=10)

# fine-tune

# grid search

 

おわり

 

f:id:AI_ML_DL:20200513183405p:plain

style=123 iteration=1

f:id:AI_ML_DL:20200513183511p:plain

style=123 iteration=20

f:id:AI_ML_DL:20200513183235p:plain

style=123 iteration=500