【このページは現在作成中です】
#準備(すべてに共通)
# PandasとNumpyをインポート
import pandas as pd
import numpy as np
# 日本語化Matplotlibもインポート
import matplotlib.pyplot as plt
!pip install japanize-matplotlib
import japanize_matplotlib
# Seabornもインポート
import seaborn as sns
# pickleをインポート(モデルの保存用)
import pickle
# データの取得
data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/bike-sharing-day.csv")
data
データが構造化された表にちゃんと収まっているかを確認する
df.shape
df.dtypes df.info()
df.isnull().sum()
df["列1"].value_counts()
分析用のデータセットの作成に向けて,データの型やインデクスを整えていく
df = data.copy()
#列を任意の型変換する
df["列1"] = df["列1"].astype("型名")
#日時型への変換
df["日時列2"] = pd.to_datetime(df["日時列2"])df.set_index("列1", inplace=True)df.drop(columns=["列1", "列2", ...], inplace=True)
#先頭数行の値を確認 data.head()
#型を確認 data.info()
#オリジナルデータをコピーして作業 df = data.copy()
#dtedayを日付型に変換 df["dteday"] = pd.to_datetime(df["dteday"]) #確認 df.info() df
#season, holiday, weekday, workingday, weathersitをカテゴリ型に変換
for col in ["season", "holiday", "weekday", "workingday", "weathersit"]:
df[col] = df[col].astype("category")
#確認
df.info()
df
#dtedayをインデクスに設定して時系列データにする
df.set_index("dteday", inplace=True)
#確認
df.info()
df
#instant, yr, mnth: 冗長なので削除 df.drop(columns=["instant", "yr", "mnth"], inplace=True) #確認 df.info() df
様々な観点からデータを探索(要約・可視化)して,データが持つ性質を理解する
可視化にはpythonのライブラリを使う
df.describe()
df["列1"].value_counts()
df.plot.box() sns.boxplot(df) #Seabornを使う場合
df["列1"].plot.hist() sns.histplot(df["列1"]) #Seabornを使う場合
sns.violinplot(df)
df.plot.bar() sns.barplot(df) #Seabornを使う場合
df["列1"].plot()
df["列1"].resample("周期").集約関数().plot() #週や月で時系列を集約して表示する場合
sns.lineplot(df) #Seabornを使う場合#describe()は基本的に数値列のみを要約する df.describe()
#カテゴリの列を要約
for col in ["season", "holiday", "weekday", "workingday", "weathersit"]:
print(f"\n【{col}の要約】")
print(df[col].value_counts())
#気象データの分布を箱ひげ図で可視化 sns.boxplot(df[["temp", "atemp", "hum", "windspeed"]])
#利用者データの分布を箱ひげ図で可視化 sns.boxplot(df[["casual", "registered", "cnt"]])
#各変数のヒストグラムを描いてみる.サブプロットを使って,1枚の図に並べる fig, axes= plt.subplots(nrows=4, ncols=2, tight_layout=True, squeeze=False) for i, col in enumerate(["temp", "atemp", "hum", "windspeed", "cnt", "casual", "registered"]): sns.histplot(df[col], ax=axes[i//2, i%2], bins=40)
#利用者データの推移を見てみる
fig, axes = plt.subplots(nrows=2, ncols=1, tight_layout=True, squeeze=False, figsize=(6,8))
#利用者データの推移
df[["casual", "registered", "cnt"]].plot(ax=axes[0,0], title="利用者データの推移(日次)")
#利用者データの月ごとの推移を棒グラフで(登録・都度の内訳)
df[["casual", "registered"]].resample("M").sum().plot.bar(stacked=True, ax=axes[1,0], title="利用者データの推移(月次)")
df.corr() sns.heatmap(df.corr(), annot=True) #ヒートマップで可視化する
df.plot.scatter(x=列1, y=列2) sns.scatterplot(df, x=列1, y=列2, hue=列3) #Seabornを使う場合.hueで色分けできる
sns.pairplot(df) #変数が多いと時間がかかるし見づらい
#相関係数を求める df.corr()
#カテゴリ変数も含めたければ,get_dummies()を行う pd.get_dummies(df).corr()
#ヒートマップで可視化 sns.heatmap(df.corr(), annot=True)
#気温と総利用者数の関係.季節で色分け sns.scatterplot(df, x="temp", y="cnt", hue="season")
#ペアプロット sns.pairplot(df)
df.groupby("カテゴリ列1").describe()["数値列2"]【比較の観点】
#統計量の要約
df.groupby(df.index.year).describe("cnt")
df.groupby("season").describe("cnt")
#以下同様
# :
#箱ひげ図で比較する
fig, axes = plt.subplots(nrows=4, ncols=2, figsize=(18,18))
sns.boxplot(df, y="cnt", x=df.index.year, ax=axes[0,0])
sns.boxplot(df, y="cnt", x="season", ax=axes[0,1])
sns.boxplot(df, y="cnt", x=df.index.month, ax=axes[1,0])
sns.boxplot(df, y="cnt", x="weekday", ax=axes[1,1])
sns.boxplot(df, y="cnt", x="holiday", ax=axes[2,0])
sns.boxplot(df, y="cnt", x="workingday", ax=axes[2,1])
sns.boxplot(df, y="cnt", x="weathersit", ax=axes[3,0])
#バイオリンプロットでもやってみてください # 略
df.isnull().sum() #列ごとの欠損値の数を数える df[df["列1"].isnull()] #列1が欠損している行を抜き出す
df = df.dropna() df = df.dropna(subset=[列1, 列2, ...]) #特定の列のNaNのみを対象
df = df.fillna(0)
df = df.fillna(df.集約関数()) #表全体 df["列1"] = df["列1"].fillna(df["列1"].集約関数()) #列ごと
df = df.fillna(method="ffill" または "bfill") #表全体 df["列1"] = df["列1"].fillna(method="ffill" または "bfill") #列ごと
df = df.interpolate() #表全体 df["列1"] = df["列1"].interpolate() #列ごと
# 箱ひげ図や散布図から見つける
df = df.drop(index=[行1, 行2, ...])
df.loc[行1, 列1] = 正しい値
df[df.duplicated(keep=False)]
df = df.drop_duplicates()
#クリーニングされていないシェアサイクルのデータをロード
data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/bike-sharing-unclean.csv")
#コピーしておく
df = data.copy()
#欠損値の個数を数える df.isnull().sum()
#tempが欠損している行を抜き出す df[df["temp"].isnull()]
#前後を見てみる df[185:195] #行ごと削除する (dfに代入していないので,dfはそのまま) df.dropna(subset=["temp"])[185:195]
#定数0で埋める (dfに代入していないので,dfはそのまま) df.fillna(0)[185:195]
#中央値で埋める (dfに代入していないので,dfはそのまま) df.fillna(df.median())[185:195]
#線形補間で埋める (dfに代入していないので,dfはそのまま) df.interpolate()[185:195]
#すべての欠損値を線形補間で埋める df = df.interpolate()
#欠損値を数える df.isnull().sum()
#要約統計量を求める df.describe()
#怪しそうな変数を表示する df[["casual", "registered", "cnt"]].plot.box() #条件で特定してみる df[df["cnt"] > 80000]
#周辺のデータを見てみる df[510:520]
#修正する df.loc[517, "casual"] = 533 df.loc[517, "cnt"] = 4127
#再度箱ひげ図で確認 df[["casual", "registered", "cnt"]].plot.box()
#重複行を見つける df[df.duplicated(keep=False)]
#重複行を削除する df = df.drop_duplicates()
#重複行を再度確認 df[df.duplicated(keep=False)]
pd.get_dummies(df, columns=[ダミー変数化する変数のリスト], drop_first=True)
#元データを適当に作る
df = pd.DataFrame(data={"物件No.":[1,2,3,4,5],
"駅からの距離":[0.2,0.8,1.5,3.4,4.8],
"築年数":[30, 25, 5, 20, 50],
"部屋数":[1,3,3,4,6],
"家賃":[55000,83000,64000,72000, 100000],
"管理費":[5000, 10000, 10000, 20000, 30000]},
).set_index("物件No.")
df
from sklearn.preprocessing import StandardScaler #標準化のためのスケーラー sc = StandardScaler() #各列にフィットさせる sc.fit(df) #スケール変換(sc.transform(df))して,データフレームに入れなおす df_sc = pd.DataFrame(sc.transform(df), index=df.index,columns=df.columns) #確認 df_sc
- 各データから最小値を引き,値域の幅で割る
from sklearn.preprocessing import MinMaxScaler #正規化のためのスケーラー sc = MinMaxScaler() #各列にフィットさせる sc.fit(df) #スケール変換(sc.transform(df))して,データフレームに入れなおす df_sc = pd.DataFrame(sc.transform(df), index=df.index,columns=df.columns) #確認 df_sc