前回に引き続き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()
前処理
ここからは前処理を行いデータを解析しやすいように整えていきます。先ほどデータを見たところ空白の列があったので、その行を削除します
.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は型名です。
日時変換
次に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]]
欠損値処理
まずは欠損値の有無を確認します。df.isnull().sum()
欠損値が最大で4413であり、データ数は323750と十分に多いので、
欠損値を埋めるのではなく、欠損値を含む行を削除する方法を選びました。
df = df.dropna()
欠損値の有無を再度確認すると以下のようになりました。
目的変数の処理
目的変数であるstateも解析できるように処理をします。まずはstateの中身を確認します。.uniqueでstateに何が含まれているか確認できます。
df['state'].unique()
stateの中には成功(successful)と失敗(failed)以外も含まれることがわかりました。
成功と失敗以外の行を削除します。successfulとfailedの行のみをstateに入れます。
df = df[(df_crdf['state'] == 'successful') | (df['state'] == 'failed')]
再度stateの中身を確認すると、成功と失敗のみになっています。
つづく
ここまで前処理を進めてきましたが、前処理はまだ!終わりません!!次回は質的データの処理や、相関係数の可視化など前処理の後半を説明します。
そして解析結果ももちろんお見せしますのでお楽しみに^^!!