وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

استفاده از یادگیری ماشینی برای پیش بینی آب و هوا: قسمت 1

0 79
زمان لازم برای مطالعه: 16 دقیقه


قسمت 1: جمع آوری داده ها از آب و هوای زیرزمینی

این اولین مقاله از یک مجموعه چند قسمتی است روی استفاده از Python و Machine Learning برای ساخت مدل هایی برای پیش بینی دمای هوا بر اساس داده های جمع آوری شده از Weather Underground. این مجموعه از سه مقاله مختلف تشکیل شده است که جنبه های اصلی یک پروژه یادگیری ماشین را توضیح می دهد. موضوعاتی که قرار است پوشش داده شود عبارتند از:

  1. جمع آوری و پردازش داده ها (این مقاله)
  2. مدل های رگرسیون خطی (ماده 2)
  3. مدل های شبکه عصبی (ماده 3)

داده های مورد استفاده در این مجموعه از سرویس وب API لایه رایگان Weather Underground جمع آوری می شود. من از کتابخانه درخواست‌ها برای تعامل با API برای جمع‌آوری داده‌های آب‌وهوا از سال 2015 برای شهر لینکلن، نبراسکا استفاده خواهم کرد. پس از جمع آوری، داده ها باید جمع آوری شوند process و در قالبی که برای تجزیه و تحلیل داده ها مناسب است جمع آوری و سپس پاکسازی شود.

مقاله دوم تمرکز خواهد کرد روی تحلیل روند داده ها با هدف انتخاب ویژگی های مناسب برای ساخت الف رگرسیون خطی مدل با استفاده از مدل های آماری و scikit-یادگیری کتابخانه های پایتون من اهمیت درک مفروضات لازم برای استفاده از یک مدل رگرسیون خطی را مورد بحث قرار خواهم داد و نشان خواهم داد که چگونه می توان ویژگی ها را برای ساخت یک مدل قوی ارزیابی کرد. این مقاله با بحث در مورد آزمایش و اعتبارسنجی مدل رگرسیون خطی به پایان خواهد رسید.

مقاله نهایی تمرکز خواهد کرد روی با استفاده از شبکه های عصبی من مقایسه خواهم کرد process ساخت یک مدل شبکه عصبی، تفسیر نتایج و دقت کلی بین مدل رگرسیون خطی ساخته شده در مقاله قبلی و مدل شبکه عصبی.

آشنایی با آب و هوای زیرزمینی

آب و هوا زیرزمینی شرکتی است که داده ها را جمع آوری و توزیع می کند روی اندازه گیری های مختلف آب و هوا در سراسر جهان این شرکت مجموعه ای از API ها را ارائه می دهد که هم برای استفاده های تجاری و هم برای استفاده های غیر تجاری در دسترس هستند. در این مقاله، روش برداشت برنامه‌ای داده‌های آب و هوای روزانه از Weather Underground را با استفاده از سطح رایگان خدمات موجود برای اهداف غیرتجاری شرح خواهم داد.

اگر می خواهید همراه با آموزش دنبال کنید، می خواهید برای حساب توسعه دهنده رایگان آنها در اینجا ثبت نام کنید. این حساب یک کلید API برای دسترسی به وب سرویس با نرخ 10 درخواست در دقیقه و در مجموع حداکثر 500 درخواست در روز ارائه می دهد.

Weather Underground بسیاری از API های سرویس وب مختلف را برای دسترسی به داده ها ارائه می دهد، اما موردی که ما به آن توجه خواهیم کرد API تاریخچه آنها است. تاریخچه API خلاصه ای از اندازه گیری های مختلف آب و هوا برای یک شهر و ایالت را ارائه می دهد روی یک روز خاص

فرمت درخواست منبع تاریخچه API به شرح زیر است:

http://api.wunderground.com/api/API_KEY/history_YYYYMMDD/q/STATE/CITY.json
  • API_KEY: API_KEY که Weather Underground با حساب شما ارائه می کند
  • YYYYMMDD: رشته ای که تاریخ هدف درخواست شما را نشان می دهد
  • STATE: مخفف حالت دو حرفی در ایالات متحده است
  • CITY: نام شهر مرتبط با ایالتی که درخواست کردید

درخواست به API

برای درخواست به Weather Underground history API و process داده های برگشتی از چند کتابخانه استاندارد و همچنین برخی از کتابخانه های محبوب شخص ثالث استفاده خواهم کرد. در زیر جدولی از کتابخانه هایی که استفاده خواهم کرد و توضیحات آنها آمده است. برای دستورالعمل‌های نصب، لطفاً به اسناد ذکر شده مراجعه کنید.

کتابخانه شرح استفاده Source
زمان قرار برای افزایش درخواست های ما در روز استفاده می شود کتابخانه استاندارد
زمان برای به تأخیر انداختن درخواست های اقامت زیر 10 در دقیقه استفاده می شود کتابخانه استاندارد
مجموعه ها از namedtuples برای جمع آوری ساختار یافته داده ها استفاده کنید کتابخانه استاندارد
پانداها عادت داشتن process، داده ها را سازماندهی و تمیز کنید کتابخانه شخص ثالث
درخواست ها برای ایجاد درخواست های شبکه ای به 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_KEY و BASE_URL از نقطه پایانی API که درخواست خواهم کرد. توجه داشته باشید که باید برای یک حساب کاربری با Weather Underground ثبت نام کنید و حساب خود را دریافت کنید API_KEY. تا زمانی که این مقاله منتشر شود، این یکی را غیرفعال خواهم کرد.

BASE_URL یک رشته با دو نگهدارنده مکان است که با براکت های مجعد نشان داده شده است. اولین {} توسط پر خواهد شد API_KEY و دومی {} با یک تاریخ قالب بندی رشته ای جایگزین می شود. هر دو مقدار در درون یابی می شوند BASE_URL رشته با استفاده از str.format (…) تابع.

API_KEY = '7052ad35e3c73564'
BASE_URL = "http://api.wunderground.com/api/{}/history_{}/q/NE/Lincoln.json"

سپس تاریخ هدف را به اولین روز سال در سال 2015 مقداردهی می کنم. سپس ویژگی هایی را که می خواهم از پاسخ های برگردانده شده از API تجزیه و تحلیل کنم، مشخص می کنم. ویژگی ها به سادگی کلیدهای موجود در هستند history -> dailysummary بخشی از پاسخ JSON از این ویژگی ها برای تعریف a استفاده می شود namedtuple تماس گرفت DailySummary که من از آن برای سازماندهی داده های درخواست فردی در لیستی از تاپل های 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س حلقه for طوری تعریف می شود که برای تعداد روزهایی که به تابع منتقل می شود روی حلقه تکرار می شود.

سپس درخواست با استفاده از فرمت می شود str.format() تابع درون یابی API_KEY و رشته فرمت شده است target_date هدف – شی. پس از قالب بندی، متغیر درخواست به آن ارسال می شود get() روش از requests شی و پاسخ به متغیری به نام تخصیص داده می شود response.

با بازگشت پاسخ، می‌خواهم با ارزیابی اینکه کد وضعیت HTTP برابر با 200 است، مطمئن شوم که درخواست موفقیت‌آمیز بوده است. اگر موفقیت آمیز بود، بدنه پاسخ را با استفاده از JSON به JSON تجزیه می‌کنم. json() متد شی پاسخ برگشتی زنجیر شده به همان json() فراخوانی متد، فهرست‌های تاریخچه و ساختارهای خلاصه روزانه را انتخاب می‌کنم، سپس اولین مورد را در آن می‌گیرم dailysummary لیست کنید و آن را به متغیری با نام اختصاص دهید data.

اکنون که ساختار داده‌ای شبیه dict را دارم که به آن ارجاع داده شده است data متغیر من می توانم فیلدهای مورد نظر را انتخاب کنم و نمونه جدیدی از آن را نمونه سازی کنم DailySummary namedtuple که به ضمیمه شده است records فهرست

در نهایت، هر تکرار از حلقه با فراخوانی به پایان می رسد sleep روش ماژول زمان برای توقف اجرای حلقه به مدت شش ثانیه، تضمین می کند که بیش از 10 درخواست در دقیقه انجام نمی شود و ما را در محدوده Weather Underground نگه می دارد.

سپس target_date با استفاده از 1 روز افزایش می یابد timedelta موضوع از datetime ماژول، بنابراین تکرار بعدی حلقه، خلاصه روزانه را برای روز بعد بازیابی می کند.

اولین دسته از درخواست ها

بدون تأخیر بیشتر، اولین مجموعه درخواست‌ها را برای حداکثر درخواست اختصاص داده شده روزانه تحت حساب توسعه‌دهنده رایگان 500 شروع می‌کنم. سپس به شما پیشنهاد می‌کنم قهوه (یا نوشیدنی ترجیحی دیگر) خود را دوباره پر کنید و درگیر شوید. روی برنامه تلویزیونی مورد علاقه شما، زیرا بسته به عملکرد حداقل یک ساعت طول می کشد روی تأخیر شبکه با این کار، ما درخواست‌های روزانه خود را به حداکثر رسانده‌ایم، و این فقط نیمی از داده‌هایی است که با آن کار خواهیم کرد.

بنابراین، فردا برگردید، جایی که آخرین دسته درخواست‌ها را تکمیل می‌کنیم، سپس می‌توانیم کار را شروع کنیم روی پردازش و قالب بندی داده ها به روشی مناسب برای پروژه یادگیری ماشین ما.

records = extract_weather_data(BASE_URL, API_KEY, target_date, 500)

اتمام بازیابی داده ها

بسیار خوب، اکنون که روز جدیدی است، ما یک صفحه تمیز و حداکثر 500 درخواست داریم که می‌توان به API تاریخچه آب و هوای زیرزمینی ارسال کرد. دسته ای از 500 درخواست ما که دیروز صادر شد آغاز شد روی 1 ژانویه 2015 و به پایان رسید روی 15 مه 2016 (با فرض اینکه هیچ درخواست ناموفقی نداشته باشید). یک بار دیگر اجازه دهید دسته ای دیگر از 500 درخواست را شروع کنیم، اما، این بار من را برای این روز رها نکنید، زیرا هنگامی که این آخرین تکه داده جمع آوری شد، ما شروع به قالب بندی آن به یک Pandas DataFrame می کنیم و ویژگی های بالقوه مفیدی را استخراج می کنیم.



records += extract_weather_data(BASE_URL, API_KEY, target_date, 500)

راه اندازی Pandas DataFrame ما

اکنون که من یک لیست رکوردهای خوب و قابل توجهی دارم DailySummary به نام tuples من از آن برای ساخت یک استفاده خواهم کرد Pandas DataFrame. Pandas DataFrame یک ساختار داده بسیار مفید برای بسیاری از کارهای برنامه نویسی است که بیشتر برای تمیز کردن و پردازش داده ها برای استفاده در پروژه ها (یا آزمایشات) یادگیری ماشین شناخته شده است.

من استفاده خواهم کرد Pandas.DataFrame(...) سازنده کلاس برای نمونه سازی یک شی DataFrame. پارامترهای ارسال شده به سازنده رکوردهایی هستند که داده های DataFrame را نشان می دهند، لیست ویژگی هایی که من نیز برای تعریف آن استفاده کردم. DailySummary namedtuples که ستون های DataFrame را مشخص می کند. این set_index() متد به نمونه DataFrame زنجیر می شود تا تاریخ را به عنوان شاخص مشخص کند.

df = pd.DataFrame(records, columns=features).set_index('date')

استخراج ویژگی ها

پروژه‌های یادگیری ماشینی که به آنها آزمایش نیز گفته می‌شود، اغلب دارای چند ویژگی هستند که کمی به هم ریخته هستند. منظور من این است که داشتن دانش موضوعی در حوزه مورد بررسی برای کمک به انتخاب ویژگی های معنادار برای بررسی همراه با یک فرض متفکرانه از الگوهای احتمالی در داده ها بسیار مفید است.

با این حال، من متغییرها و الگوهای توضیحی بسیار تأثیرگذار را نیز دیده‌ام که از پیش‌فرض‌های تقریباً ساده‌لوحانه یا حداقل بسیار باز و حداقلی در مورد داده‌ها ناشی می‌شوند. داشتن شهود مبتنی بر دانش برای دانستن اینکه کجا باید ویژگی‌ها و الگوهای مفید بالقوه را جستجو کرد و همچنین توانایی جستجوی ویژگی‌های غیرقابل پیش‌بینی به شیوه‌ای بی‌طرفانه بخش بسیار مهمی از یک پروژه تحلیلی موفق است.

در این راستا، ما چندین ویژگی را در حین تجزیه داده های خلاصه روزانه بازگشتی برای استفاده در مطالعه خود انتخاب کرده ایم. با این حال، من کاملاً انتظار دارم که بسیاری از این موارد در پیش‌بینی دمای هوا یا نامزدهای نامناسب باشند. روی نوع مدلی که استفاده می شود، اما نکته اصلی این است که تا زمانی که داده ها را به دقت بررسی نکنید، نمی دانید.

اکنون نمی توانم بگویم که دانش قابل توجهی از هواشناسی یا مدل های پیش بینی آب و هوا دارم، اما یک جستجوی حداقلی در کار قبلی انجام دادم. روی استفاده از یادگیری ماشینی برای پیش بینی دمای هوا همانطور که مشخص است تعداد زیادی مقاله تحقیقاتی وجود دارد روی موضوع و در سال 2016 Holmstrom، Liu، و Vo استفاده از رگرسیون خطی را برای انجام این کار توصیف کردند. در مقاله خود، یادگیری ماشینی برای پیش بینی آب و هوا به کار می رود، آنها از داده های آب و هوا استفاده کردند روی دو روز قبل برای اندازه گیری های زیر

  • حداکثر دما
  • دمای دقیقه
  • میانگین رطوبت
  • میانگین فشار اتمسفر

من لیست ویژگی های آنها را با استفاده از موارد ذکر شده در زیر گسترش خواهم داد و به جای استفاده از دو روز قبل، سه روز به عقب باز خواهم گشت.

  • میانگین دما
  • میانگین نقطه شبنم
  • فشار متوسط
  • حداکثر رطوبت
  • حداقل رطوبت
  • حداکثر نقطه شبنم
  • نقطه شبنم دقیقه
  • حداکثر فشار
  • حداقل فشار
  • ته نشینی

بنابراین، راه بعدی پیدا کردن راهی برای گنجاندن این ویژگی های جدید به عنوان ستون در DataFrame ما است. برای انجام این کار، یک زیرمجموعه کوچکتر از DataFrame فعلی ایجاد می کنم تا کار با آن را در حین توسعه الگوریتمی برای ایجاد این ویژگی ها آسان تر کنم. یک را خواهم ساخت tmp DataFrame فقط از 10 رکورد و ویژگی ها تشکیل شده است meantempm و meandewptm.

tmp = df(('meantempm', 'meandewptm')).head(10)
tmp
تاریخ meantempm meandewptm
01-01-2015 -6 -12
02/01/2015 -6 -9
03/01/2015 -4 -11
04/01/2015 -14 -19
05/01/2015 -9 -14
06/01/2015 -10 -15
07/01/2015 -16 -22
08/01/2015 -7 -12
09/01/2015 -11 -19
2015/01/10 -6 -12

اجازه دهید آنچه را که امیدواریم انجام دهیم، تجزیه و سپس آن را به کد ترجمه کنیم. برای هر روز (ردیف) و برای یک ویژگی معین (ستون) می خواهم مقدار آن ویژگی را N روز قبل پیدا کنم. برای هر مقدار N (در مورد ما 1-3) می‌خواهم یک ستون جدید برای آن ویژگی ایجاد کنم که نشان‌دهنده Nامین اندازه‌گیری روز قبل است.


N = 1


feature = 'meantempm'


rows = tmp.shape(0)




nth_prior_measurements = (None)*N + (tmp(feature)(i-N) for i in range(N, rows))


col_name = "{}_{}".format(feature, N)
tmp(col_name) = nth_prior_measurements
tmp
تاریخ meantempm meandewptm meantempm_1
01-01-2015 -6 -12 هیچ یک
02/01/2015 -6 -9 -6
03/01/2015 -4 -11 -6
04/01/2015 -14 -19 -4
05/01/2015 -9 -14 -14
06/01/2015 -10 -15 -9
07/01/2015 -16 -22 -10
08/01/2015 -7 -12 -16
09/01/2015 -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')

عالی! به نظر می رسد آنچه را که نیاز داریم داریم. کار بعدی که می خواهم انجام دهم این است که کیفیت داده ها را ارزیابی کرده و در صورت لزوم آن ها را پاکسازی کنم.

پاکسازی داده ها – مهمترین بخش

همانطور که عنوان بخش می گوید، مهمترین بخش یک پروژه تحلیلی این است که مطمئن شوید از داده های با کیفیت استفاده می کنید. ضرب المثل “زباله داخل، زباله بیرون” مثل همیشه در مورد یادگیری ماشینی مناسب است. با این حال، بخش تمیز کردن داده‌ها در یک پروژه تحلیلی نه تنها یکی از مهم‌ترین بخش‌ها است، بلکه زمان‌برترین و پر زحمت‌ترین بخش نیز است. برای اطمینان از کیفیت داده‌های این پروژه، در این بخش به دنبال شناسایی داده‌های غیرضروری، مقادیر از دست رفته، سازگاری انواع داده‌ها و موارد پرت هستم و سپس در مورد روش رسیدگی به آنها در صورت بروز تصمیم‌گیری می‌کنم.

اولین کاری که می‌خواهم انجام دهم این است که ستون‌هایی از DataFrame را که علاقه‌ای به آن‌ها ندارم رها کنم تا حجم داده‌ای را که با آن کار می‌کنم کاهش دهم. هدف این پروژه پیش بینی دمای آینده بر اساس سه روز گذشته اندازه گیری آب و هوا است. با در نظر گرفتن این موضوع، ما فقط می‌خواهیم حداقل، حداکثر و میانگین دما را برای هر روز به اضافه همه متغیرهای مشتق شده جدیدی که در بخش‌های گذشته اضافه کردیم، حفظ کنیم.


to_remove = (feature 
             for feature in features 
             if feature not in ('meantempm', 'mintempm', 'maxtempm'))


to_keep = (col for col in df.columns if col not in to_remove)


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')

کار بعدی که می‌خواهم انجام دهم این است که از برخی توابع داخلی پاندا استفاده کنم تا درک بهتری از داده‌ها داشته باشم و به طور بالقوه مناطقی را برای تمرکز انرژی خود شناسایی کنم. روی. اولین تابع یک متد DataFrame است که نامیده می شود info() که، شگفتی بزرگ … اطلاعاتی را ارائه می دهد روی 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 برای اعمال پانداها to_numeric روش به تمام مقادیر DataFrame. این error='coerce' پارامتر هر مقدار متنی را پر می کند NaNs. یافتن مقادیر متنی در داده‌های وحشی که معمولاً از جمع‌آورنده داده‌ها که در آن داده‌ها گم شده یا نامعتبر است، منشأ می‌گیرند، معمول است.

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() یک DataFrame حاوی تعداد، میانگین، انحراف معیار، حداقل، صدک 25، صدک 50 (یا میانه)، صدک 75 و حداکثر مقدار تولید می کند. این می تواند اطلاعات بسیار مفیدی برای ارزیابی توزیع داده های ویژگی باشد.

من می خواهم با محاسبه ستون خروجی دیگری که نشان دهنده وجود نقاط پرت است به این اطلاعات اضافه کنم. قاعده کلی برای شناسایی یک نقطه پرت شدید مقداری است که کمتر از 3 باشد محدوده های بین چارکی زیر صدک 25 یا 3 محدوده بین چارکی بالاتر از صدک 75. محدوده بین چارکی به سادگی تفاوت بین صدک 75 و صدک 25 است.


spread = df.describe().T


IQR = spread('75%') - spread('25%')



spread('outliers') = (spread('min')<(spread('25%')-(3*IQR)))|(spread('max') > (spread('75%')+3*IQR))


spread.ix(spread.outliers,)
شمردن منظور داشتن std دقیقه 25% 50% 75% حداکثر موارد پرت
حداکثر رطوبت_1 999.0 88.107107 9.273053 47.0 83.0 90.0 93.00 100.00 درست است، واقعی
حداکثر رطوبت_2 998.0 88.102204 9.276407 47.0 83.0 90.0 93.00 100.00 درست است، واقعی
حداکثر رطوبت_3 997.0 88.093280 9.276775 47.0 83.0 90.0 93.00 100.00 درست است، واقعی
maxpressurem_1 999.0 1019.924925 7.751874 993.0 1015.0 1019.0 1024.00 1055.00 درست است، واقعی
maxpressurem_2 998.0 1019.922846 7.755482 993.0 1015.0 1019.0 1024.00 1055.00 درست است، واقعی
maxpressurem_3 997.0 1019.927783 7.757805 993.0 1015.0 1019.0 1024.00 1055.00 درست است، واقعی
minpressurem_1 999.0 1012.329329 7.882062 956.0 1008.0 1012.0 1017.00 1035.00 درست است، واقعی
minpressurem_2 998.0 1012.326653 7.885560 956.0 1008.0 1012.0 1017.00 1035.00 درست است، واقعی
minpressurem_3 997.0 1012.326981 7.889511 956.0 1008.0 1012.0 1017.00 1035.00 درست است، واقعی
precipm_1 889.0 2.908211 8.874345 0.0 0.0 0.0 0.51 95.76 درست است، واقعی
precipm_2 889.0 2.908211 8.874345 0.0 0.0 0.0 0.51 95.76 درست است، واقعی
precipm_3 888.0 2.888885 8.860608 0.0 0.0 0.0 0.51 95.76 درست است، واقعی

ارزیابی تاثیر بالقوه نقاط دورافتاده بخش دشواری از هر پروژه تحلیلی است. از یک طرف، شما باید نگران پتانسیل معرفی مصنوعات داده های جعلی باشید که به طور قابل توجهی بر مدل های شما تأثیر می گذارد یا سوگیری می کند. از سوی دیگر، نقاط پرت می توانند در پیش بینی نتایجی که در شرایط خاص به وجود می آیند بسیار معنادار باشند. ما در مورد هر یک از این موارد پرت که حاوی ویژگی‌ها هستند بحث خواهیم کرد و خواهیم دید که آیا می‌توانیم به یک نتیجه معقول در مورد روش برخورد با آنها برسیم.

به نظر می رسد اولین مجموعه از ویژگی ها به حداکثر رطوبت مربوط می شود. با نگاه کردن به داده ها می توانم بگویم که نقطه پرت برای این دسته ویژگی به دلیل مقدار کم ظاهرا بسیار کم است. در واقع به نظر می رسد که این مقدار بسیار کم است و من فکر می کنم می خواهم نگاهی دقیق تر به آن بیندازم، ترجیحاً به صورت گرافیکی. برای این کار از هیستوگرام استفاده می کنم.

%matplotlib inline
plt.rcParams('figure.figsize') = (14, 8)
df.maxhumidity_1.hist()
plt.title('Distribution of maxhumidity_1')
plt.xlabel('maxhumidity_1')
plt.show()

هیستوگرام حداکثر رطوبت

نگاهی به هیستوگرام مقادیر برای maxhumidity داده‌ها کمی انحراف منفی را نشان می‌دهند. من می خواهم این را در هنگام انتخاب مدل های پیش بینی و ارزیابی قدرت تأثیر حداکثر رطوبت در نظر داشته باشم. بسیاری از روش های آماری اساسی فرض می کنند که داده ها به طور معمول توزیع شده اند. در حال حاضر فکر می کنم آنها را به حال خود رها خواهم کرد، اما خوب است که این را در ذهن داشته باشیم و نسبت به آن شک و تردید داشته باشیم.

در ادامه به توزیع ویژگی فشار حداقل می پردازم.

df.minpressurem_1.hist()
plt.title('Distribution of minpressurem_1')
plt.xlabel('minpressurem_1')
plt.show()

هیستوگرام فشار حداقل

این طرح ویژگی جالب دیگری را به نمایش می گذارد. از این نمودار، داده ها است چند وجهی، که من را به این باور می رساند که دو مجموعه بسیار متفاوت از شرایط محیطی در این داده ها آشکار است. من در حذف این مقادیر مردد هستم زیرا می دانم که نوسانات دما در این منطقه از کشور می تواند بسیار شدید باشد به خصوص در بین فصول سال. من نگران هستم که حذف این مقادیر پایین ممکن است سودمندی توضیحی داشته باشد، اما یک بار دیگر در همان زمان در مورد آن تردید خواهم داشت.

طبقه بندی نهایی ویژگی های حاوی نقاط پرت، یعنی بارش، کمی راحت تر قابل درک است. از آنجایی که روزهای خشک (یعنی بدون بارندگی) بسیار بیشتر است، دیدن نقاط پرت در اینجا معقول است. برای من این دلیلی برای حذف این ویژگی ها نیست.

آخرین مشکل کیفیت داده که باید به آن پرداخته شود، کمبود مقادیر است. با توجه به روشی که من DataFrame را ساخته‌ام، مقادیر از دست رفته توسط NaNs نشان داده می‌شوند. احتمالاً به خاطر دارید که من عمداً مقادیر گمشده را برای سه روز اول داده‌های جمع‌آوری‌شده با استخراج ویژگی‌هایی که سه روز قبل از اندازه‌گیری‌ها را نشان می‌دهند، معرفی کرده‌ام. تا روز سوم نیست که می‌توانیم آن ویژگی‌ها را استخراج کنیم، بنابراین واضح است که می‌خواهم آن سه روز اول را از مجموعه داده‌ها حذف کنم.

دوباره به خروجی آخرین باری که من صادر کردم نگاه کنید info روش. یک ستون خروجی وجود دارد که مقادیر غیر تهی را برای هر ستون ویژگی فهرست می کند. با نگاهی به این اطلاعات می توانید ببینید که در بیشتر موارد ویژگی ها حاوی مقادیر نسبتاً کمی گمشده (تهی / NaN) هستند، عمدتاً فقط مواردی که من معرفی کردم. با این حال، به نظر می رسد که ستون های بارش بخش قابل توجهی از داده های خود را از دست داده اند.

داده های از دست رفته یک مشکل ایجاد می کند زیرا اکثر روش های یادگیری ماشینی به مجموعه داده های کامل و عاری از هرگونه داده از دست رفته نیاز دارند. جدا از این موضوع که بسیاری از روش‌های یادگیری ماشینی به داده‌های کامل نیاز دارند، اگر بخواهم تمام ردیف‌ها را فقط به این دلیل حذف کنم که ویژگی بارش حاوی داده‌های از دست رفته است، بسیاری از اندازه‌گیری‌های ویژگی مفید دیگر را حذف می‌کنم.

همانطور که می بینم من چند گزینه برای مقابله با این مشکل داده های از دست رفته دارم:

  1. من به سادگی می‌توانم ردیف‌هایی را که حاوی مقادیر از دست رفته هستند حذف کنم، اما همانطور که قبلاً اشاره کردم با بیرون ریختن این مقدار داده، مقدار زیادی از داده‌ها حذف می‌شود.
  2. من می توانم مقادیر از دست رفته را با یک مقدار درون یابی شده پر کنم که تخمین معقولی از مقادیر واقعی است.

از آنجایی که ترجیح می‌دهم تا آنجا که می‌توانم داده‌ها را حفظ کنم، در جایی که کمترین خطر وارد کردن مقادیر اشتباه وجود دارد، می‌خواهم مقادیر بارش از دست رفته را با رایج‌ترین مقدار صفر پر کنم. من احساس می کنم این یک تصمیم معقول است زیرا اکثر مقادیر در اندازه گیری های بارش صفر هستند.


for precip_col in ('precipm_1', 'precipm_2', 'precipm_3'):
    
    missing_vals = pd.isnull(df(precip_col))
    df(precip_col)(missing_vals) = 0

اکنون که تمام مقادیر از دست رفته را که می‌توانم پر کرده‌ام، در حالی که مراقب بودم تأثیر منفی بر کیفیت نداشته باشم، راحت می‌توانم رکوردهای باقی‌مانده حاوی مقادیر گمشده را از مجموعه داده‌ها حذف کنم. رها کردن ردیف هایی از DataFrame حاوی NaN بسیار آسان است. تنها کاری که باید انجام دهم این است که متد را فراخوانی کنم dropna() و پانداها همه کارها را برای من انجام خواهند داد.

df = df.dropna()

منابع

آیا می خواهید ابزارها، یادگیری ماشینی و تجزیه و تحلیل داده های مورد استفاده در این آموزش را یاد بگیرید؟ در اینجا چند منبع عالی برای شروع شما وجود دارد:

نتیجه

در این مقاله من شرح داده ام process جمع آوری، تمیز کردن و پردازش یک مجموعه داده با اندازه مناسب برای استفاده در مقالات آینده روی یک پروژه یادگیری ماشینی که در آن دمای هوای آینده را پیش‌بینی می‌کنیم.

در حالی که این احتمالاً خشک ترین مقاله در مورد این پروژه یادگیری ماشینی خواهد بود، من سعی کرده ام بر اهمیت جمع آوری داده های با کیفیت مناسب برای یک آزمایش یادگیری ماشینی ارزشمند تأکید کنم.

ممنون که خواندید و امیدوارم منتظر مقالات بعدی باشید روی این پروژه.

به دنبال قسمت های 2 و 3 این مجموعه هستید؟ اینجا برو:

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-29 03:52:04

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید