TPTブログ

テックポート株式会社のブログです。 技術情報や製品・サービス情報、 また未経験社員がデータサイエンティストを 目指す奮闘記など、更新していきます。

Kaggleに挑戦しよう! ~コード説明1~

f:id:tbtech:20190419183826j:plain
前回に引き続きKaggleで私が投稿したコードを説明したいと思います!

初心者の私が書いたものなので初歩的なものですが、同じ初心者の方のヒントになり

熟練者の方には助言をいただけたら嬉しいです(;_;) 

データセット概要

前回もお見せした、こちらのデータセットを扱います。

https://www.kaggle.com/kemical/kickstarter-projects

この「KickstarterProjects」は、クラウドファンディング愛好家さんが出したもので

Kickstarterというサイトで行われたクラウドファンディングの過去のデータを基に

それが成功するか、失敗するのか分類を予測する問題です。

データはks-projects-201612とks-projects-201801の2つで

2016年と2018年に録られた記録だと思われます。

今回私は2016年のデータを使って解析を行いました。


 データの変数は以下の通りです。

・ID:クラウドファンディングの個別ID

・name:クラウドファンディングの名前

・category:詳細なカテゴリー

・main_category:大まかなカテゴリー

・currency :使用された通貨

・deadline:締め切り日時

・goal:目標調達資金額

・launched:開始した日時

・pledged:集まった資金

・state:プロジェクトの状態(成功、失敗、キャンセルなど)

・backer:集まった支援者

・country:プロジェクトが開かれた国

・usd pledged: 集まった資金の米ドル換算

 以上のことから目的変数は「state」で説明変数がその他になります。

データを見てみると、列がずれて欠損値がある行がありました。

同様の行が何個かあったので、処理方法は欠損値を含む行を削除しようと思いました。

データ数は十分に多く、最頻値や平均値などで補う必要は無いと考えたからです。


コード内容

それではコードについて順に説明していきます。

準備

まずは必要なライブラリを読み込みます。
データ解析に欠かせないpandas, numpy, matplotlib,
さらにseabornはmatplotlibより美しいグラフの描画が出来ます。
scikit-learnの各種ライブラリと、日時を扱うためのdatetimeもインポートしています。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline  #matplotlibのグラフを表示する
import seaborn as sns
from sklearn.preprocessing import StandardScaler #preprocessing:前処理  StandardScaler:標準化
from sklearn.model_selection import train_test_split #データを訓練データとテストデータに分割する
from sklearn.linear_model import SGDClassifier #クラス分類をする
from sklearn.metrics import log_loss, accuracy_score, precision_recall_fscore_support, confusion_matrix 
#log_loss:対数尤度 ,accuracy_score:正答率 ,precision_recall_fscore_support:適合率,再現率,F1値 ,confusion_matrix:クロス集計表
from sklearn.metrics import mean_absolute_error #平均絶対誤差
import datetime as dt #日時を扱う


次にデータを読み込み、DataFrameの型にします。
codecsを読み込みcodecs.openで開くデータのフォントを指定することができます。

import codecs 
with codecs.open('../input/ks-projects-201612.csv', "r", "Shift-JIS", "ignore") as file:  #フォントをShift-JISに, ignoreでエラーが出ても無視します
    df = pd.read_csv(file, delimiter=",") #読み込んだCSVファイルを” , ”で区切ります
df.columns = df.columns.str.replace(" ", "") #列名に含まれる空白を除きます


読み込んだデータを頭から数行表示してみます。
デフォルトは5で例えば10行表示したい場合は.head(10)とします。

df.head()

f:id:tbtech:20190419152407j:plain

前処理

ここからは前処理を行いデータを解析しやすいように整えていきます。

先ほどデータを見たところ空白の列があったので、その行を削除します
f:id:tbtech:20190419155158j:plain
.dropでdf(データフレーム)の行列を削除します。列名を指定しaxis=1を入れると列の削除になります。
dfは上書きされないので、新規dfに代入するか、上書きしたい場合は以下のように元のdfに入れます。

df = df.drop(['Unnamed:13','Unnamed:14','Unnamed:15','Unnamed:16'], axis=1)

データ情報確認
.infoでデータ情報を確認します。

df.info()

行の数:323750, 列の数:13であることが赤線よりわかります。
nameを例に見ると緑線はnon-nullつまり空白ではない行数を表します。
行の数が323750であることから、nameには5つ欠損値があることがわかります。
また、objectは型名です。
f:id:tbtech:20190419160817j:plain

日時変換
次にdeadlineとlaunchedに着目します。
これはプロジェクトの開始日と終了日ですが、これらの日付よりも
その間の日数の方が重要ではないかと考えました。
まずはdeadlineとlaunchedをobject型からdatetime型に変更し、日時として扱えるようにします。
エラーはcoerceにすると強制変更されます。

df['deadline'] = pd.to_datetime(df['deadline'], errors = 'coerce')
df['launched'] = pd.to_datetime(df['launched'], errors = 'coerce')

datetime型に変更した2つの変数を引いたものから日数を取り出すために.dt.daysをつけて
新たにperiodという変数に日数を入れます。

df['period'] = (df['deadline'] - df['launched']).dt.days

不要になったdeadlineとlaunchedの列を削除します。

df = df.drop(['deadline', 'launched'], axis=1)

その他の型変換
残りの変数のうち、数値のものをobject型からfloat型に変更します。

df['goal'] = pd.to_numeric(df['goal'], errors ='coerce')
df['pledged'] = pd.to_numeric(df['pledged'], errors ='coerce')
df['backers'] = pd.to_numeric(df['backers'], errors ='coerce')
df['usdpledged'] = pd.to_numeric(df['usdpledged'], errors ='coerce')

データ整理
ここで一度、不要であると考えた変数を削除します。
IDとnameはプロジェクトの成功に関連が無いと考えました。
categoryはmain_categoryがあるので不要、countryは数が多いため断念しました。。

df = df.drop(['ID','name','category','country'], axis=1)

解析に使用する変数が決まったところで、変数を見やすいように並び替えます。
目的変数を一番左に移動します。

df = df.ix[:,[4,2,5,7,3,6,0,1]]

f:id:tbtech:20190419173219j:plain

欠損値処理
まずは欠損値の有無を確認します。

df.isnull().sum()

f:id:tbtech:20190419180515j:plain
欠損値が最大で4413であり、データ数は323750と十分に多いので、
欠損値を埋めるのではなく、欠損値を含む行を削除する方法を選びました。

df = df.dropna()

欠損値の有無を再度確認すると以下のようになりました。
f:id:tbtech:20190419181646p:plain

目的変数の処理
目的変数であるstateも解析できるように処理をします。
まずはstateの中身を確認します。.uniqueでstateに何が含まれているか確認できます。

df['state'].unique()

f:id:tbtech:20190419182224j:plain
stateの中には成功(successful)と失敗(failed)以外も含まれることがわかりました。
成功と失敗以外の行を削除します。successfulとfailedの行のみをstateに入れます。

df = df[(df_crdf['state'] == 'successful') | (df['state'] == 'failed')]

再度stateの中身を確認すると、成功と失敗のみになっています。
f:id:tbtech:20190419182715j:plain

つづく
ここまで前処理を進めてきましたが、前処理はまだ!終わりません!!
次回は質的データの処理や、相関係数の可視化など前処理の後半を説明します。
そして解析結果ももちろんお見せしますのでお楽しみに^^!!