記述統計学
あらまし
機械学習エンジニアに未経験から転職した。研修期間に学んだことを書きます。
📌 文系にもわかりやすいように、わかりやすく書く。
🔗Outline
📘Instructions
データを分類する
データにはその特徴別に種類があります。それらを識別することで、その特徴にあった記述や推測が可能になります。
- カテゴリー型(質的変数 or Categorical Variables)
- 数値型(量的変数 or Numeric Variables)
- 離散型(Discrete Variables)
- 連続型(Continuous Variables)
カテゴリー型は性別や国籍などあるカテゴリーに属するデータです。対して、数値型はその名の通り数値で表現されたデータになります。
数値型はさらに、離散型と連続型に分けることができます。離散型はサイコロの目のように飛び飛びの値では取れない変数。つまり、小数点などに細かく値をとれない変数となります。対して、連続型はどこまでも細かく数値をとることが可能です。
データの特徴を調べる
- 統計量
-
分散
S^2 = \frac{1}{n}\Sigma_{i=1}^{n}(x_i-\bar{x})^2 = 分散S^2
=x_i 個目のデータ_i
= データの平均\bar{x}
= データの数量n 分散 = 分布のひろがりを表す統計量
-
不変分散
S^2 = \frac{1}{n-1}\Sigma_{i=1}^{n}(x_i-\bar{x})^2 不変分散 = 分散よりも少し大きい値になっており、分散よりも母分散に近づくとされている
-
標準偏差
\sigma = \sqrt{S^2} = 分散S^2
= 標準偏差\sigma
-
基礎統計量とは、データ分布の特徴を数値で表す指標です。有名なものだと、平均や中央値などがあります。これらの説明は割愛しますが、統計学において大事な基礎統計量の一つである、分散と標準偏差について解説します。
標準偏差とは分布のひろがりや散らばり具合を表す統計量です。推測などをする際に、データが散らばっていると推測しづらくなります。二乗している理由は、負の値が出てしまうと正の値と打ち消しあってしまい、ばらつき具合を加算していかなくなるためです。
しかし、このままでは二乗している関係で、単位が変わってしまいます。身長を例に出すと
-
可視化
- 1変数
-
ヒストグラム
-
スニペット
#distplotはヒストグラムを描写 sns.distplot(train['column'])
#数値型のみのヒストグラムをforループで複数描写 cols = 3 rows = 3 num_cols = df.select_dtypes(exclude='object').columns fig = plt.figure( figsize=(cols*5, rows*5)) for i, col in enumerate(num_cols): ax=fig.add_subplot(rows,cols,i+1) sns.histplot(x = df[col], ax = ax) fig.tight_layout() plt.show()
-
特徴
- データの範囲や峰の数、データの集中具合がわかる
- 特徴量の歪度がわかる
- 異常値の有無がわかる
-
-
ヒストグラム
- 2変数
- 数値型
-
散布図
-
スニペット
sns.jointplot(x='numeric_column', y='numeric_column', hue = "column", data=df)
-
特徴
- 当てはめるモデルを予測しやすい
- 外れ値がわかる
-
kind='reg’
を入れることで、線形回帰を描写できる
-
-
棒グラフ
-
スニペット
#countplotは棒グラフを描写 sns.countplot(x="column",y='numeric_column',hue="column", data=df) #barplotは棒グラフ+信頼区間をグラフ化 sns.barplot(x="column",y='numeric_column', data=df)
-
特徴
- データの範囲や峰の数、データの集中具合がわかる
- 特徴量の歪度がわかる
- 異常値の有無がわかる
-
-
KDEプロット
-
スニペット
#KDE単体 sns.kdeplot(x='column', data=df, hue='column')
#ヒストグラム+KDE sns.histplot(x='column', data=df, kde=True)
-
特徴
- ある変数の分布を別ものと比較できる
- ある変数の分布を別ものと比較できる
-
-
ラグプロット
-
スニペット
#ラグプロット+ヒストグラム+KDE sns.rugplot(x='column', data=df, height=.03, color='darkblue') sns.histplot(x='column', data=cars, kde=True)
-
特徴
- 異常値がどこにあるかわかる
- 異常値がどこにあるかわかる
-
-
箱ひげ図
-
スニペット
#通常 sns.boxplot(x=df['cplumn'])
#多くの箱ひげ図を出すとき cols = 3 rows = 3 num_cols = df.select_dtypes(exclude='object').columns fig = plt.figure(figsize= (15,9)) for i, col in enumerate(num_cols): ax=fig.add_subplot( rows, cols, i+1) sns.boxplot(x=df[col], ax=ax) fig.tight_layout() plt.show()
#カウントグラフと箱ひげ図を上下に並べて比較する fig = plt.figure() #カウントグラフ ax1 = fig.add_subplot(2,1,1) sns.countplot(data = df, x = 'column', ax = ax1) #箱ひげ図 ax2 = fig.add_subplot(2,1,2) sns.boxplot(data = df, x='column', y='column2' , ax = ax2)
-
特徴
- 数値型特徴量の分布、中心、歪度、外れ値、最大値、最小値などわかる
- ヒストグラムより詳細でないが、小さく素早くプロット可能
-
-
バイオリンプロット
-
スニペット
sns.violinplot(data = df, x='column', y='column2')
-
特徴
- バイオリンプロットとKDEプロットの特徴を持つ
- バイオリンプロットとKDEプロットの特徴を持つ
-
-
ストリッププロット
-
スニペット
sns.stripplot(x=df["cplumn"])
-
特徴
- 外れ値
- 箱ひげ図と違い相対的な中心を確立するのが難しく、より小さなデータセットに最適
-
-
散布図
- カテゴリー型
-
クロス集計表
-
スニペット
#pandasで実装 #2変数 pd.crosstab([df["categorical_column"],df["categorical_column"]) #3変数 pd.crosstab([df["categorical_column"],df["categorical_column"]], df["categorical_column"])
-
特徴
- シンプルに結果がわかる
- シンプルに結果がわかる
-
-
カウントプロット
-
スニペット
#基本形1 sns.countplot(x="column", data=data) #オブジェクトクラスの数量でソートしたいとき data['categorical_class'].value_counts().plot(kind="bar")
#複数のカテゴリー変数をforループでプロットする cols = 4 rows = 1 fig = plt.figure(figsize= (16,6)) all_categs = df.select_dtypes(include='object') cat_cols = all_categs.columns[all_categs.nunique() < 10] for i, col in enumerate(cat_cols): ax=fig.add_subplot(rows, cols, i+1) sns.countplot(x=cars[col], ax=ax) plt.xticks(rotation=45, ha='right') fig.tight_layout() plt.show()
-
特徴
- データ中に各クラスが何回現れるかわかる
- データ中に各クラスが何回現れるかわかる
-
-
パイチャート
-
スニペット
#seabornにはない df_column_val = df['column'].value_counts() plt.pie(df_column_val, labels=df.index, autopct="%.0f%%");
-
特徴
- シンプルで分かりやすい
- 可視化コミュニティではあまり人気がない
- グループが4つ以上になると、グラフが乱雑に見えること
- スライスの幅が直感的にわかりにくい場合があること
-
-
クロス集計表
- 数値型
- 1変数
-
相関
-
数値型
-
ピアソンの積率相関係数
r =\frac{\Sigma{(x_i-\bar{x})(y_i-\bar{y})}}{\sqrt{\Sigma{(x_i-\bar{x})^2(y_i-\bar{y})^2}}} = 相関係数r
=x_i 変数の値x
=\bar{x} 変数の平均x
=y_i 変数の値y
=\bar{y} 変数の平均y -
スニペット
#ヒートマップで比較する場合 #import seaborn as sns #import matplotlib.pyplot as plt #%matplotlib inline CONTINUOUS_VARIABLES = ["column", "column", "column", "column", "column"] #CONTINUOUS_VARIABLESの新しいデータフレームを作成する cont_variables_dataframe = **df**[CONTINUOUS_VARIABLES] #CONTINUOUS_VARIABLESの相関を計算する cont_variables_correlation = cont_variables_dataframe.corr() #ヒートマップにしてプロット ax = sns.heatmap(cont_variables_correlation, annot=True, linewidths=.5, cmap="YlGnBu", square=True );
-
-
カテゴリー型
-
クラメール連関係数
V = \sqrt{\frac{\chi^2}{n×min(r-1,c-1)}} = 相関係数V
= カイ二乗値\chi^2
= サンプルサイズn
= 行数r
= 列数c -
スニペット
#クラメールV def cramersV(x, y): table = np.array(pd.crosstab(x, y)) #クロス集計 n = table.sum() #実測度数 colsum = table.sum(axis=0) #縦計 rowsum = table.sum(axis=1) #横計 expect = np.outer(rowsum, colsum) / n #期待度数 chisq = np.sum((table - expect) ** 2 /expect) #カイ二乗値 return np.sqrt(chisq / (n * np.min(table.shape) -1)) #クラメール連関係数 name = [] result = [] for column_name, item in df.iteritems(): name.append(column) x = cramersV(df[x], item) result.append(x) # データフレーム化 df_result = pd.DataFrame({'factor':name, 'cramersV':result}) df_result
#カテゴリー型変数の相関をforループで描写する #from scipy import stats CATEGORICAL_VARIABLES = ["column", "column", "column", "column", "column"] for c in CATEGORICAL_VARIABLES: if c not in ["column", "column", "column"]:#2値データの選択 correlation = stats.pearsonr(df[c], df["y_column"])#ピアソンの相関係数 else: correlation = stats.pointbiserialr(dataset[c], df["y_column"])#点双列相関係数 print("Correlation of %s to **column** is %s" %(c, correlation))
#カテゴリー変数をラベルエンコーディングする場合 label_encoder = LabelEncoder() data.iloc[:,0] = label_encoder.fit_transform(data.iloc[:,0]).astype('float64') corr = data.corr() sns.heatmap(corr)
-
相関係数は2種類のデータ間の関連性の強さを示す指標で、どれだけ直線の関係に近いかわかる。相関係数が1に近いと正の相関が強く、-1に近いと負の相関が近い。0に近いと相関が薄い。ただし、外れ値に影響されるので注意が必要。
-
📄References
- https://qiita.com/zumitan/items/dd4bfc7e7d5624c74bee
- https://www.kaggle.com/code/nextbigwhat/eda-for-categorical-variables-a-beginner-s-way/notebook
- https://towardsdatascience.com/8-seaborn-plots-for-univariate-exploratory-data-analysis-eda-in-python-9d280b6fe67f
- https://www.kaggle.com/code/vmalyi/finding-the-most-correlating-variables/notebook
- https://www.kaggle.com/code/bbloggsbott/feature-selection-correlation-and-p-value
- https://zenn.dev/ohrzw/articles/a9a818e71c3278
Discussion