Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 21085

scikit-learnでirisなどの付属データセットではなく、独自データやインターネット上の外部データを読み込む方法

$
0
0

 書籍やネット上のscikit-learn教材には、irisやcancer等の付属データセットを使った解説が多いです。もちろん手軽で 同じ結果が得られる安心感もある一方、予定調和的で 深い学びが得にくいと感じる方も多いのではないかと思います。
 この記事では、自作データやネット上にある外部データを読み込んで、scikit-learnで分析する方法をご紹介します。
(検証環境:Windows10, Anaconda3, Python3.7.6, Jupyter Notebook6.0.3)

 CSVファイルの準備

 この記事では、例として機械学習・データサイエンス コミニティーである Kaggleが公開しているデータ World Happiness Report←リンク を使います。機械学習に使いやすいデータセットが揃っているので、ユーザー登録が必要ですが Kaggleを選択しました。
 Download (79 KB)というボタンからダウンロードして下さい。zipファイルを解凍すると 5つのCSVファイルが見つかりますが、ここでは 2019.csv を使います。

他のファイルを使う場合

  • 2019.csv はPythonデータ分析ライブラリである pandasで読み込み易いような「一行目に特徴量の名前、二行目以降にデータ」という配置になっています。そうでないデータは、エクセルの行削除などで成型して下さい。

  • エクセルファイル(.xls) など形式が違う場合は、読み込んだ後「ファイル-別名で保存」を行い、CSVファイル形式を選択します。区切り文字が選択可能な場合は ,(カンマ)にしておきます。

  • 保存場所はPythonの実行ファイル(pyやipynbファイル)があるフォルダにしておくと楽です。

 CSVファイルの読み込み

 ライブラリを使わずに 直接読み込む方法もありますが、以降の作業を楽にするため、この記事では pandasを使った方法を紹介します。
 pandasがまだインストールされていない場合は、この記事等を参考に行って下さい。

import pandas as pd
df = pd.read_csv('2019.csv')

 区切り文字がタブの場合は引数sep='\t'を、日本語が入っている場合は引数encoding='shift_jis'を加えます
df = pd.read_csv('ファイル名.csv', sep='\t', encoding='shift_jis')

 実行ファイルと別の場所にデータファイルを置く場合は df=pd.read_csv('data/2019.csv')と相対パスを加えるなどします。参考→Python, pathlibで絶対パスと相対パスを相互変換・判定

 特徴量名とデータ数の確認

print("データセットのキー(特徴量名)の確認==>:\n", df.keys())
print('dataframeの行数・列数の確認==>\n', df.shape)

上記のコマンドを実行すると、

データセットのキー(特徴量名)の確認==>:
 Index(['Overall rank', 'Country or region', 'Score', 'GDP per capita',
       'Social support', 'Healthy life expectancy',
       'Freedom to make life choices', 'Generosity',
       'Perceptions of corruption'],
      dtype='object')
dataframeの行数・列数の確認==>
 (156, 9)

と9つの特徴量があるサンプル数156のデータが読み込めたことが確認できます。

 欠損値等の処理をする

 データ中に欠損値(Null)が無いか、またデータ型を確認し、整数値のみ(int)/小数を含む数値(float)/文字列または文字列と数値の混在(object)なのかを見ます。

# dataframe各列の欠損値でないデータ数、データ型を確認
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 156 entries, 0 to 155
Data columns (total 9 columns):
 #   Column                        Non-Null Count  Dtype  
---  ------                        --------------  -----  
 0   Overall rank                  156 non-null    int64  
 1   Country or region             156 non-null    object 
 2   Score                         156 non-null    float64
 3   GDP per capita                156 non-null    float64
 4   Social support                156 non-null    float64
 5   Healthy life expectancy       156 non-null    float64
 6   Freedom to make life choices  156 non-null    float64
 7   Generosity                    156 non-null    float64
 8   Perceptions of corruption     156 non-null    float64
dtypes: float64(7), int64(1), object(1)
memory usage: 11.1+ KB

 Nullでは無いデータが156個⇒欠損値なし と確認できます。
 Overall rankは整数、Country or regionは文字列、それ以外は小数を含む数値 と意図通りのデータ型になっています。
 数値が入っているはずの列が objectになってしまっている場合は、

# 数値ではない型の要素の抽出
objectlist = df[['特徴量名を入れる']][df['特徴量名を入れる'].apply(lambda s:pd.to_numeric(s, errors='coerce')).isnull()]
objectlist

↑ を実行すると、文字列扱いになっているデータが抽出できます。

 このデータに文字列と数値の混在や欠損値はありませんでしたが、他データには様々な理由で、「空欄」「ゼロを意味する"0"以外の文字・記号」「単位付きの数字」等 そのままでは分析に不適当な値が入っていることがよくあります。

こちらの記事等を参考に、適切な処理をして下さい。

 Scikit-learn用のデータクラスを持つオブジェクト(空のデータセット)を作る

import sklearn
worldhappiness = sklearn.utils.Bunch()

worldhappinessの部分はデータセット名を表すよう、適宜変えて下さい。

 データセットにデータを入れていく

# 'Score'(幸福スコア)を目的変数'target'とする
worldhappiness['target'] = df['Score']
# 説明変数を'data'に入れる
worldhappiness['data'] = df.loc[:, ['GDP per capita',
       'Social support', 'Healthy life expectancy',
       'Freedom to make life choices', 'Generosity',
       'Perceptions of corruption']]

↑ 最初の3列以外の6列を指定します。「特徴量名の確認」で出力したデータをコピペすると楽です。

# 特徴量の名前も入れておくと、グラフの凡例等に使えます(無くても可)
worldhappiness['feature_names'] = ['GDP per capita',
       'Social support', 'Healthy life expectancy',
       'Freedom to make life choices', 'Generosity',
       'Perceptions of corruption']

 訓練セットとテストセットに分割

# 訓練セットとテストセットに分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    worldhappiness['data'], worldhappiness['target'], random_state=0)
print("X_train shape:", X_train.shape)
print("X_test shape:", X_test.shape)

 結び

 これで機械分析に進めると思います。間違い指摘・質問等ございましたら、お気軽にコメント下さい。


Viewing all articles
Browse latest Browse all 21085

Trending Articles