その1: Weather Undergroundからデータを収集する
この記事は、Pythonと機械学習を使って、Weather Undergroundから収集したデータに基づいて気温を予測するモデルを構築する複数回連載の第1回目です。
このシリーズは、機械学習プロジェクトの主要な側面を説明する3つの異なる記事で構成される予定です。
取り上げるトピックは以下の通りです。
- データの収集と処理(本記事)
- 線形回帰モデル(本記事2)
- ニューラルネットワークモデル(本記事3)
本連載で使用するデータは、Weather UndergroundのフリーティアAPIウェブサービスから収集します。
私は、ネブラスカ州リンカーン市の2015年以降の気象データを引き出すために、APIと対話するためにrequestsライブラリを使用する予定です。
収集した後は、データを加工してデータ分析に適した形式に集約し、クリーニングする必要があります。
第2回目は、statsmodels と scikit-learn Python ライブラリを使用して線形回帰モデルを構築するための適切な特徴を選択することを目標に、データの傾向を分析することに焦点を当てます。
線形回帰モデルを使用するために必要な前提条件を理解することの重要性について述べ、堅牢なモデルを構築するための特徴量を評価する方法を示します。
この記事は、Linear Regressionモデルのテストと検証についての議論で締めくくられます。
最後の記事は、ニューラルネットワークの使用に焦点を当てます。
ニューラルネットワークモデルの構築プロセス、結果の解釈、そして全体的な精度を、前の記事で構築した線形回帰モデルとニューラルネットワークモデルとで比較します。
ウェザーアンダーグラウンドを使いこなす
Weather Undergroundは、世界中の様々な気象観測データを収集し、配信している会社です。
この会社は、商用・非商用に関わらず利用可能なAPIを提供しています。
この記事では、非商用目的で利用できる無料のサービス層を使って、Weather Undergroundから毎日の気象データをプログラムで取得する方法を説明します。
このチュートリアルに沿って進めるには、ここで無料の開発者アカウントにサインアップする必要があります。
このアカウントでは、1分間に10リクエスト、1日に合計500リクエストまでウェブサービスにアクセスできるAPIキーが提供されます。
Weather Undergroundは、データにアクセスするための様々なウェブサービスAPIを提供していますが、今回取り上げるのはそのうちの1つ、履歴APIです。
履歴APIは、特定の日のある都市や州の様々な気象測定値の概要を提供します。
履歴APIリソースへのリクエストの形式は以下のとおりです。
http://api.wunderground.com/api/API_KEY/history_YYYYMMDD/q/STATE/CITY.json
-
API_KEY
: Weather Underground がアカウントで提供する API_KEY -
YYYYMMDD
: リクエストの対象日を表す文字列 -
STATE
: アメリカ合衆国における2文字の州の略称 -
CITY
: リクエストされた状態に関連する都市名
APIへのリクエストの作成
Weather Underground history APIにリクエストを行い、返されたデータを処理するために、いくつかの標準的なライブラリと、人気のあるサードパーティライブラリを使用します。
以下は、使用するライブラリの一覧とその説明です。
インストール方法については、記載されているドキュメントを参照してください。
| ライブラリ|使用説明|ソース
| — | — | — |
| datetime|リクエストを一日単位で増加させるために使用|標準ライブラリ
| time|1分間に10回以下になるようにリクエストを遅らせるために使用|Standard Library|標準ライブラリ
| コレクション|データの構造化されたコレクションに名前付きタプルを使用|Standard Library|スタンダードライブラリ
| pandas|データを処理し、整理し、きれいにするために使用|サードパーティライブラリ||リクエスト
| リクエスト|APIへのネットワーク接続されたリクエストを行うために使用|サードパーティライブラリ
| matplotlib|グラフィカルな分析に使用|サードパーティライブラリ|これらをインポートして始めましょう。
それでは、これらのライブラリをインポートして始めましょう。
from datetime import datetime, timedelta
import time
from collections import namedtuple
import pandas as pd
import requests
import matplotlib.pyplot as plt
次に、私がリクエストするAPIエンドポイントの API_KEY
と BASE_URL
を表す定数をいくつか定義します。
Weather Undergroundのアカウントにサインアップして、自分のAPI_KEY`を受け取る必要があることに注意してください。
この記事が公開される頃には、私はこのアカウントを解除していることでしょう。
BASE_URL
は、中括弧で表された2つのプレースホルダーを持つ文字列です。
最初の {}
には API_KEY
が入り、2番目の {}
には日付の文字列が入ります。
両方の値は str.format(…) 関数を用いて BASE_URL
文字列に補間される。
API_KEY = '7052ad35e3c73564'
BASE_URL = "http://api.wunderground.com/api/{}/history_{}/q/NE/Lincoln.json"
次に、対象日を2015年の元旦に初期化します。
次に、APIから返されるレスポンスから解析したい機能を指定します。
featuresは、JSONレスポンスの history -> dailysummary
部分に存在するキーにすぎません。
これらの特徴は DailySummary
という namedtuple
を定義するために使用され、これを使用して個々のリクエストのデータを DailySummary タプルのリストで整理することになります。
target_date = datetime(2016, 5, 16)
features = ["date", "meantempm", "meandewptm", "meanpressurem", "maxhumidity", "minhumidity", "maxtempm",
"mintempm", "maxdewptm", "mindewptm", "maxpressurem", "minpressurem", "precipm"]
DailySummary = namedtuple("DailySummary", features)
このセクションでは、以下に定義する関数を使って、実際にAPIにリクエストを行い、成功したレスポンスを収集することにする。
この関数は url
, api_key
, target_date
, days
というパラメータを受け取ります。
def extract_weather_data(url, api_key, target_date, days):
records = []
for _ in range(days):
request = BASE_URL.format(API_KEY, target_date.strftime('%Y%m%d'))
response = requests.get(request)
if response.status_code == 200:
data = response.json()['history']['dailysummary'][0]
records.append(DailySummary(
date=target_date,
meantempm=data['meantempm'],
meandewptm=data['meandewptm'],
meanpressurem=data['meanpressurem'],
maxhumidity=data['maxhumidity'],
minhumidity=data['minhumidity'],
maxtempm=data['maxtempm'],
mintempm=data['mintempm'],
maxdewptm=data['maxdewptm'],
mindewptm=data['mindewptm'],
maxpressurem=data['maxpressurem'],
minpressurem=data['minpressurem'],
precipm=data['precipm']))
time.sleep(6)
target_date += timedelta(days=1)
return records
まず、パースされたデータを DailySummary
namedtuple
として保持する records というリストを定義することから始めます。
for ループは、関数に渡された日数分のループを反復するように定義されています。
次に、str.format()
関数を用いて、API_KEY
と文字列フォーマットされた target_date
オブジェクトを補間して、リクエストをフォーマットする。
フォーマットされたリクエスト変数は requests
オブジェクトの get()
メソッドに渡され、レスポンスは response
という変数に代入されます。
返されたレスポンスで、HTTPステータスコードが200であることを確認し、リクエストが成功したことを確認したいと思います。
成功した場合は、返されたレスポンスオブジェクトの json()
メソッドを使用して、レスポンスのボディを JSON にパースします。
同じ json()
メソッド呼び出しに連動して、履歴と日別サマリー構造のインデックスを選択し、 dailysummary
リストの最初の項目を取得して、それを data
という変数に代入しています。
これで、変数 data
から参照されるディクショナリ形式のデータ構造ができたので、必要なフィールドを選択して DailySummary
namedtuple
の新しいインスタンスを作成し、それを records
リストに追加することができるようになりました。
最後に、ループの各反復は time モジュールの sleep
メソッドを呼び出してループの実行を 6 秒間停止させることで終了します。
これは、1 分間に 10 件以上のリクエストが発生しないことを保証し、 Weather Underground の制限内であることを維持します。
次に、 datetime
モジュールの timedelta
オブジェクトを使用して target_date
を1日分増加させ、次のループの繰り返しで翌日の日次サマリーを取得できるようにします。
第1回リクエスト
早速ですが、無料開発者アカウントで1日に割り当てられる最大のリクエスト数である500件のリクエストの第一陣がスタートします。
そして、コーヒー (または他の好みの飲み物) をお代わりして、お気に入りのテレビ番組に追いつくことをお勧めします。
この機能はネットワークの遅延に依存して少なくとも 1 時間かかるからです。
これで、今日一日のリクエストの上限を超えましたが、これは我々が扱うデータの約半分に過ぎません。
明日には最後のリクエストを終え、機械学習プロジェクトに適した方法でデータの処理とフォーマットを行う予定です。
records = extract_weather_data(BASE_URL, API_KEY, target_date, 500)
データ取得の仕上げ
さて、新しい日になったので、私たちはまっさらな状態で、Weather Undergroundの履歴APIにできる最大500のリクエストを持っています。
昨日発行された500リクエストのバッチは、2015年1月1日に始まり、2016年5月15日に終了しました(失敗したリクエストはなかったと仮定しています)。
もう一度、500リクエストの別のバッチを開始しましょう。
しかし、このデータの最後のチャンクが収集されると、我々はPandas DataFrameにそれをフォーマットし始め、潜在的に有用な機能を導き出すつもりなので、今回は私を残して行かないでください。
# if you closed our terminal or Jupyter Notebook, reinitialize your imports and
# variables first and remember to set your target_date to datetime(2016, 5, 16)
records += extract_weather_data(BASE_URL, API_KEY, target_date, 500)
PandasのDataFrameのセットアップ
さて、DailySummary
という名前のタプルの素敵で大きなレコードリストができたので、それを使ってPandas DataFrameを構築してみましょう。
Pandas DataFrameは、機械学習プロジェクト(または実験)で使用するデータのクリーニングと処理のために最もよく知られている多くのプログラミングタスクのための非常に便利なデータ構造です。
ここでは、Pandas.DataFrame(...)
クラスのコンストラクタを使用して、DataFrameオブジェクトのインスタンスを作成することにします。
コンストラクタに渡されるパラメータは、DataFrame のデータを表すレコードと、DataFrame のカラムを指定する DailySummary
namedtuple
を定義するために使用した特徴リストです。
set_index()` メソッドは、DataFrame のインスタンス化に連鎖して、インデックスとして日付を指定するために使用されます。
df = pd.DataFrame(records, columns=features).set_index('date')
特徴量の導出
機械学習プロジェクトは実験とも呼ばれ、しばしば少し矛盾するような特徴を持つことがある。
つまり、調査対象の領域に関する主題的な知識を持ち、データから起こりうるパターンについて熟考した上で、調査すべき有意義な特徴を選択することは非常に有用である。
しかし、私は、データについてほとんど素朴な、あるいは少なくとも非常にオープンで最小限の前提を持つことによって、非常に影響力のある説明変数やパターンが生じるのを見たことがあります。
潜在的に有用な特徴やパターンを探すための知識ベースの直感と、予期せぬ特異性を偏りなく探す能力を持つことは、分析プロジェクトを成功させる上で非常に重要な要素になります。
この点で、私たちは、返された日次サマリーデータを解析する際に、かなり多くの特徴を選択して、研究に使用することにしました。
しかし、これらの多くは、使用するモデルの種類によっては、気温の予測に役立たない、あるいは不適切な候補となることが十分に予想されますが、肝心なことは、データを厳密に調査してみないと分からないということです。
私は気象学や天気予報のモデルについて詳しいわけではありませんが、機械学習を使って気温を予測した先行研究については、最低限の調査を行いました。
その結果、このトピックに関する研究論文はかなり多く、2016年のHolmstrom, Liu, and Voは、まさにそれを行うためにLinear Regressionを使用することを説明しています。
彼らの論文「Machine Learning Applied to Weather Forecasting」では、前2日間の気象データを使って、次のような測定を行っています。
- 最高気温
- 最低気温
- 平均湿度
- 平均気圧
私は、彼らの特徴量リストを拡張し、以下のものを使用することにします。
- 平均気温
- 平均露点
- 平均気圧
- 最大湿度
- 最小湿度
- 最大露点
- 最小露点
- 最大圧力
- 最低気圧
- 降水量
そこで次は、これらの新しい機能をDataFrameのカラムとして含める方法を考えなければなりません。
そのために、現在のDataFrameのサブセットを小さくして、これらの特徴を作成するアルゴリズムを開発しながら作業しやすくすることにします。
10個のレコードと meantempm
と meandewptm
という特徴量からなる tmp
というDataFrameを作成します。
tmp = df[['meantempm', 'meandewptm']].head(10)
tmp
| 日付|meantempm|meandewptm|。
何を達成したいのかを分解し、コードに変換してみましょう。
各日(行)と与えられた特徴(列)について、その特徴のN日前の値を見つけたいと思います。
Nの値(ここでは1-3)ごとに、N日前の測定値を表す新しい列をその特徴量に対して作りたい。
# 1 day prior
N = 1
# target measurement of mean temperature
feature = 'meantempm'
# total number of rows
rows = tmp.shape[0]
# a list representing Nth prior measurements of feature
# notice that the front of the list needs to be padded with N
# None values to maintain the constistent rows length for each N
nth_prior_measurements = [None]*N + [tmp[feature][i-N] for i in range(N, rows)]
# make a new column name of feature_N and add to DataFrame
col_name = "{}_{}".format(feature, N)
tmp[col_name] = nth_prior_measurements
tmp
| 日付|Meenempm|Meandewptm|Meenempm_1|の順に表示します。
| — | — | — | — |
| 2015-01-01|-6|-12|なし|||。
| 2015-01-03 | -4 | -11 | -6 |
| 2015-01-04 | -14 | -19 | -4 |
| 2015-01-05 | -9 | -14 | -14 |
| 2015-01-06 | -10 | -15 | -9 |
| 2015-01-07 | -16 | -22 | -10 |
| 2015-01-08 | -7 | -12 | -16 |
| 2015-01-09 | -11 | -19 | -7 |
| 2015-01-10 | -6 | -12 | -11 |
さて、これで新機能を作るのに必要な基本的なステップは揃ったようです。
では、これらのステップを再利用可能な関数にまとめ、必要な機能をすべて構築するためにそれを使用することにします。
def derive_nth_day_feature(df, feature, N):
rows = df.shape[0]
nth_prior_measurements = [None]*N + [df[feature][i-N] for i in range(N, rows)]
col_name = "{}_{}".format(feature, N)
df[col_name] = nth_prior_measurements
ここで、先ほど定義した素性リストの素性に対してループを書き、「日付」以外の素性、N日1から3までの素性に対して、気温を予測するために評価したい派生素性を追加する関数を呼び出すことにします。
for feature in features:
if feature != 'date':
for N in range(1, 4):
derive_nth_day_feature(df, feature, N)
そして、念のため、列が期待通りに見えるかどうか見てみます。
df.columns
Index(['meantempm', 'meandewptm', 'meanpressurem', 'maxhumidity',
'minhumidity', 'maxtempm', 'mintempm', 'maxdewptm', 'mindewptm',
'maxpressurem', 'minpressurem', 'precipm', 'meantempm_1', 'meantempm_2',
'meantempm_3', 'meandewptm_1', 'meandewptm_2', 'meandewptm_3',
'meanpressurem_1', 'meanpressurem_2', 'meanpressurem_3',
'maxhumidity_1', 'maxhumidity_2', 'maxhumidity_3', 'minhumidity_1',
'minhumidity_2', 'minhumidity_3', 'maxtempm_1', 'maxtempm_2',
'maxtempm_3', 'mintempm_1', 'mintempm_2', 'mintempm_3', 'maxdewptm_1',
'maxdewptm_2', 'maxdewptm_3', 'mindewptm_1', 'mindewptm_2',
'mindewptm_3', 'maxpressurem_1', 'maxpressurem_2', 'maxpressurem_3',
'minpressurem_1', 'minpressurem_2', 'minpressurem_3', 'precipm_1',
'precipm_2', 'precipm_3'],
dtype='object')
素晴らしい!必要なものが揃ったようですね。
次にしたいことは、データの品質を評価し、必要な部分をクリーンアップすることです。
データクリーニング – 最も重要な部分
このセクションのタイトルにあるように、分析プロジェクトで最も重要なことは、高品質のデータを使用していることを確認することです。
機械学習に関しては、「ゴミが入ればゴミが出る」という格言がありますが、これはまさにその通りです。
しかし、分析プロジェクトにおけるデータのクリーニングは、最も重要な作業の1つであるだけでなく、最も時間と労力を要する作業でもあります。
このセクションでは、このプロジェクトのデータの品質を確保するために、不要なデータ、欠損値、データタイプの一貫性、異常値を特定し、それらが発生した場合にどのように処理するかを決定したいと思います。
まず、DataFrameの中で興味のない列を削除し、扱うデータ量を減らします。
このプロジェクトのゴールは、過去3日間の気象測定値から将来の気温を予測することです。
このことを念頭に置いて、各日の最低、最高、平均気温と、最後のセクションで追加した新しい派生変数のみを保持したいと思います。
# make list of original features without meantempm, mintempm, and maxtempm
to_remove = [feature
for feature in features
if feature not in ['meantempm', 'mintempm', 'maxtempm']]
# make a list of columns to keep
to_keep = [col for col in df.columns if col not in to_remove]
# select only the columns in to_keep and assign to df
df = df[to_keep]
df.columns
Index(['meantempm', 'maxtempm', 'mintempm', 'meantempm_1', 'meantempm_2',
'meantempm_3', 'meandewptm_1', 'meandewptm_2', 'meandewptm_3',
'meanpressurem_1', 'meanpressurem_2', 'meanpressurem_3',
'maxhumidity_1', 'maxhumidity_2', 'maxhumidity_3', 'minhumidity_1',
'minhumidity_2', 'minhumidity_3', 'maxtempm_1', 'maxtempm_2',
'maxtempm_3', 'mintempm_1', 'mintempm_2', 'mintempm_3', 'maxdewptm_1',
'maxdewptm_2', 'maxdewptm_3', 'mindewptm_1', 'mindewptm_2',
'mindewptm_3', 'maxpressurem_1', 'maxpressurem_2', 'maxpressurem_3',
'minpressurem_1', 'minpressurem_2', 'minpressurem_3', 'precipm_1',
'precipm_2', 'precipm_3'],
dtype='object')
次にしたいことは、Pandasに組み込まれているいくつかの関数を使用して、データの理解を深め、エネルギーを集中させる領域を特定することです。
最初の関数は info()
と呼ばれるDataFrameのメソッドで、驚くことに… DataFrameの情報を提供してくれます。
興味深いのは、出力の「データ型」カラムです。
df.info()
<class 'pandas.core.frame.dataframe'="">
DatetimeIndex: 1000 entries, 2015-01-01 to 2017-09-27
Data columns (total 39 columns):
meantempm 1000 non-null object
maxtempm 1000 non-null object
mintempm 1000 non-null object
meantempm_1 999 non-null object
meantempm_2 998 non-null object
meantempm_3 997 non-null object
meandewptm_1 999 non-null object
meandewptm_2 998 non-null object
meandewptm_3 997 non-null object
meanpressurem_1 999 non-null object
meanpressurem_2 998 non-null object
meanpressurem_3 997 non-null object
maxhumidity_1 999 non-null object
maxhumidity_2 998 non-null object
maxhumidity_3 997 non-null object
minhumidity_1 999 non-null object
minhumidity_2 998 non-null object
minhumidity_3 997 non-null object
maxtempm_1 999 non-null object
maxtempm_2 998 non-null object
maxtempm_3 997 non-null object
mintempm_1 999 non-null object
mintempm_2 998 non-null object
mintempm_3 997 non-null object
maxdewptm_1 999 non-null object
maxdewptm_2 998 non-null object
maxdewptm_3 997 non-null object
mindewptm_1 999 non-null object
mindewptm_2 998 non-null object
mindewptm_3 997 non-null object
maxpressurem_1 999 non-null object
maxpressurem_2 998 non-null object
maxpressurem_3 997 non-null object
minpressurem_1 999 non-null object
minpressurem_2 998 non-null object
minpressurem_3 997 non-null object
precipm_1 999 non-null object
precipm_2 998 non-null object
precipm_3 997 non-null object
dtypes: object(39)
memory usage: 312.5+ KB
すべての列のデータ型は、”object “型であることに注意してください。
我々は、実行したいタイプの数値解析のために、これらの特徴列をすべて浮動小数点に変換する必要があります。
これを行うために、私は apply()
DataFrame メソッドを使って、Pandasの to_numeric
メソッドをDataFrameのすべての値に適用しようと思います。
error=’coerce’` パラメータは、任意のテキスト値をNaNに埋めます。
通常、データコレクターから取得したデータには、文字列が含まれていない、あるいは無効なものがあります。
df = df.apply(pd.to_numeric, errors='coerce')
df.info()
<class 'pandas.core.frame.dataframe'="">
DatetimeIndex: 1000 entries, 2015-01-01 to 2017-09-27
Data columns (total 39 columns):
meantempm 1000 non-null int64
maxtempm 1000 non-null int64
mintempm 1000 non-null int64
meantempm_1 999 non-null float64
meantempm_2 998 non-null float64
meantempm_3 997 non-null float64
meandewptm_1 999 non-null float64
meandewptm_2 998 non-null float64
meandewptm_3 997 non-null float64
meanpressurem_1 999 non-null float64
meanpressurem_2 998 non-null float64
meanpressurem_3 997 non-null float64
maxhumidity_1 999 non-null float64
maxhumidity_2 998 non-null float64
maxhumidity_3 997 non-null float64
minhumidity_1 999 non-null float64
minhumidity_2 998 non-null float64
minhumidity_3 997 non-null float64
maxtempm_1 999 non-null float64
maxtempm_2 998 non-null float64
maxtempm_3 997 non-null float64
mintempm_1 999 non-null float64
mintempm_2 998 non-null float64
mintempm_3 997 non-null float64
maxdewptm_1 999 non-null float64
maxdewptm_2 998 non-null float64
maxdewptm_3 997 non-null float64
mindewptm_1 999 non-null float64
mindewptm_2 998 non-null float64
mindewptm_3 997 non-null float64
maxpressurem_1 999 non-null float64
maxpressurem_2 998 non-null float64
maxpressurem_3 997 non-null float64
minpressurem_1 999 non-null float64
minpressurem_2 998 non-null float64
minpressurem_3 997 non-null float64
precipm_1 889 non-null float64
precipm_2 889 non-null float64
precipm_3 888 non-null float64
dtypes: float64(36), int64(3)
memory usage: 312.5 KB
さて、全てのデータが私の望むデータ型になったので、特徴の要約統計を見て、統計的経験則を使って極端な外れ値の存在をチェックしたいと思います。
DataFrame メソッド describe()
は、カウント、平均、標準偏差、最小値、25%値、50%値(または中央値)、75%値、最大値を含む DataFrame を生成します。
これは、特徴データの分布を評価するのに非常に有用な情報である。
この情報に加えて、外れ値の存在を示す別の出力列を計算したいと思う。
極端な外れ値を特定するための経験則は、25パーセンタイルより3四分位範囲未満、または75パーセンタイルより3四分位範囲より上の値である。
四分位範囲とは、簡単に言えば、75パーセンタイルと25パーセンタイルの差である。
# Call describe on df and transpose it due to the large number of columns
spread = df.describe().T
# precalculate interquartile range for ease of use in next calculation
IQR = spread['75%'] - spread['25%']
# create an outliers column which is either 3 IQRs below the first quartile or
# 3 IQRs above the third quartile
spread['outliers'] = (spread['min']<(spread['25%']-(3*IQR)))|(spread['max'] > (spread['75%']+3*IQR))
# just display the features containing extreme outliers
spread.ix[spread.outliers,]
| 数|平均|標準|最小|25%|50%|75%|最大|外れ値|の順で表示されます。
| — | — | — | — | — | — | — | — | — | — |
| maxhumidity_1|999.0|88.107107|9.273053|47.0|83.0|90.0|93.00|100.00|真|||||||||||||の順で表示される。
| maxhumidity_Θ2|998.0|88.102204|9.276407|47.0|83.0|90.0|93.00|100.00|True|の順となります。
997.0 | 88.093280 | 9.276775 | 47.0 | 83.0 | 90.0 | 93.00 | 100.00 | True|。
| maxpressurem___1 | 999.0 | 1019.924925 | 7.751874 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 | True|。
| maxpressurem_2 | 998.0 | 1019.922846 | 7.755482 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 | True|。
| maxpressuremère_3 | 997.0 | 1019.927783 | 7.757805 | 993.0 | 1015.0 | 1019.0 | 1024.00 | 1055.00 | True|。
| minpressurem_1| 999.0| 1012.329329| 7.882062| 956.0| 1008.0| 1012.0| 1017.00| 1035.00| True||。
| minpressuremère_2 | 998.0 | 1012.326653 | 7.885560 | 956.0 | 1008.0 | 1012.0 | 1017.00 | 1035.00 | True|||。
| minpressurem_3 | 997.0 | 1012.326981 | 7.889511 | 956.0 | 1008.0 | 1012.0 | 1017.00 | 1035.00 | True|||||||Minpressurem_3 | 997.0 | 1012.326981 | 7.889511 | 957.0 | 1018.0 | 1017.00 | True
| precipm_1| 889.0| 2.908211| 8.874345| 0.0| 0.51| 95.76| True|||| 0.0| 0.0| 0.0| 0.51| 95.76| 0.0
| precipm_2| 889.0| 2.908211| 8.874345| 0.0| 0.0| 0.51| 95.76| True|||| | precipm_2| 0.0| 0.0| 0.0| 0.51| 95.76| True
| precipmanthus_3| 888.0| 2.888885| 8.860608| 0.0| 0.0| 0.51| 95.76| True||。
外れ値の潜在的な影響を評価することは、あらゆる分析プロジェクトにおいて難しい部分です。
一方では、モデルに大きな影響や偏りを与える偽のデータアーティファクトを導入する可能性について懸念する必要があります。
一方、外れ値は、特殊な状況下で生じる結果を予測する上で、極めて有意義なものとなり得ます。
これらの外れ値を含む特徴をそれぞれ説明し、それらをどのように扱うべきかについて合理的な結論に達することができるかどうかを確認します。
最初の特徴は、すべて最大湿度に関連しているように見えます。
データを見ると、この特徴量カテゴリの異常値は、明らかに非常に低いmin値によるものであることがわかります。
これは確かにかなり低い値のようで、できればグラフ化して詳しく見てみたいと思います。
リソース
このチュートリアルで使用されているツール、機械学習、データ分析について学びたいですか?ここでは、そのための素晴らしいリソースをいくつか紹介します。
- PandasとPythonを使ったデータ解析
- Deep Learning Prerequisites: Pythonによる線形回帰
- データサイエンスと機械学習のためのPython Bootcamp
結論
この記事では、将来の気温を予測する機械学習プロジェクトに関する今後の記事で使用する、適度な大きさのデータセットを収集、洗浄、処理するプロセスについて説明した。
おそらく、この機械学習プロジェクトに関する記事の中で最も退屈なものになるだろうが、価値のある機械学習実験に適した質の高いデータを収集することの重要性を強調しようとしたつもりである。
お読みいただきありがとうございました。
このプロジェクトに関する今後の記事を楽しみにしていてください。
このシリーズの第2部、第3部をお探しですか?どうぞ。
- 機械学習による天気予報。パート2
- 機械学習による天気予報。第3回