はじめに
これまでの記事で重回帰分析と分散分析を行った。そこで、今回はロジスティック回帰分析をPythonで行っておこうと思います。
今回はKaggleで見つけた航空会社の顧客満足度のデータセット 1 を使用したいと思います。その説明文にもある通り、航空会社は、顧客満足度を高めるために、自社が提供するサービスのどの側面に重点を置く必要があるかを把握する必要があります。そこで、このデータセット(これまでの顧客の満足度調査)を利用して(将来の)顧客がサービスに満足するかどうかを予測するモデルをロジスティック回帰分析で構築して、その結果を評価しようと思います。
パッケージのインポートとデータの読み込み
パッケージをインポート
まず初めにモデルを構築、視覚化、評価するにあたって必要なパッケージをインポートします。
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import sklearn.metrics as metrics
データの読み込み
データを読み込んで、データの確認を行います。
df_original = pd.read_csv("Invistico_Airline.csv")
print(df_original.shape)
(129880, 23)
列数が多いので折り返し、省略がされないようにして先頭データの確認を行います。
pd.set_option('display.expand_frame_repr', False)
pd.set_option('display.max_columns', 23)
print(df_original.head())
satisfaction Gender Customer Type Age Type of Travel Class Flight Distance Seat comfort Departure/Arrival time convenient Food and drink Gate location Inflight wifi service On-board service Leg room service Baggage handling Checkin service Cleanliness Online boarding Departure Delay in Minutes Arrival Delay in Minutes
0 satisfied Female Loyal Customer 65 Personal Travel Eco 265 0 0 0 2 2 3 0 3 5 3 2 0 0.0
1 satisfied Male Loyal Customer 47 Personal Travel Business 2464 0 0 0 3 0 4 4 4 2 3 2 310 305.0
2 satisfied Female Loyal Customer 15 Personal Travel Eco 2138 0 0 0 3 2 3 3 4 4 4 2 0 0.0
3 satisfied Female Loyal Customer 60 Personal Travel Eco 623 0 0 0 3 3 1 0 1 4 1 3 0 0.0
4 satisfied Female Loyal Customer 70 Personal Travel Eco 354 0 0 0 3 4 2 0 2 4 2 5 0 0.0
データ探索(EDA)、データ クリーニング、およびモデルの準備
データの探索
ロジスティック回帰モデルでは数値データが想定されることを念頭において各列のデータ型を確認します。
print(df_original.dtypes)
satisfaction object
Gender object
Customer Type object
Age int64
Type of Travel object
Class object
Flight Distance int64
Seat comfort int64
Departure/Arrival time convenient int64
Food and drink int64
Gate location int64
Inflight wifi service int64
Inflight entertainment int64
Online support int64
Ease of Online booking int64
On-board service int64
Leg room service int64
Baggage handling int64
Checkin service int64
Cleanliness int64
Online boarding int64
Departure Delay in Minutes int64
Arrival Delay in Minutes float64
dtype: object
データセット内の顧客満足度のカラム値を確認する
顧客満足度を予測する為に、モデルの構築前にデータセット内の顧客満足度のカラムを確認します。
print(df_original['satisfaction'].value_counts(dropna = False))
satisfied 71087
dissatisfied 58793
Name: satisfaction, dtype: int64
value_countsは引数なしのデフォルトではNaNが除外されますが、 dropna = False とするとNaNもカウントされます。NaNの件数が無いことから、顧客満足度のカラムには欠損値が無いことが確認出来ました。
欠損値の確認
ロジスティック回帰モデルでは、欠損値が存在しないことが前提となります。そこで、データの行に欠損値がないかを確認します。
print(df_original.isnull().sum())
satisfaction 0
Gender 0
Customer Type 0
Age 0
Type of Travel 0
Class 0
Flight Distance 0
Seat comfort 0
Departure/Arrival time convenient 0
Food and drink 0
Gate location 0
Inflight wifi service 0
Inflight entertainment 0
Online support 0
Ease of Online booking 0
On-board service 0
Leg room service 0
Baggage handling 0
Checkin service 0
Cleanliness 0
Online boarding 0
Departure Delay in Minutes 0
Arrival Delay in Minutes 393
dtype: int64
欠損値は全体のレコード数、129,880に対しての393レコードだけとその割合は僅かであることから、今回は欠損値のある行を削除することにします。
df_subset = df_original.dropna(axis=0).reset_index(drop = True)
データの準備
ロジスティック回帰分析を行うにあたって、説明変数と目的変数を設定したいと思います。ここでは説明変数を機内エンターテイメント体験(Inflight entertainment)、目的変数を顧客満足度(satisfaction)として、機内エンターテイメント体験の向上が顧客満足度の向上につながるかどうかを予測しようと思います。
顧客満足度のカテゴリ値を数値に変換しておく
顧客満足度のデータ型が「object 型」になっているので、扱いやすくするためにOne-Hotエンコーディングを使用して、カテゴリ値を数値に変換しておきます。
df_subset['satisfaction'] = OneHotEncoder(drop='first').fit_transform(df_subset[['satisfaction']]).toarray()
トレーニングデータとテストデータの作成
回帰モデルの結果をより適切にテストおよび評価する為に、ホールドアウト法(Hold-out)を用いて、データの 70% をトレーニングデータ、残りの 30% をテストデータに分割します。トレーニングデータはモデルを構築するために使用し、テストデータは構築後のモデルのパフォーマンスを評価するために使用します。そうすることで過剰適合(オーバーフィッティング)や不足適合(アンダーフィッティング)に対処します。
X = df_subset[["Inflight entertainment"]]
y = df_subset["satisfaction"]
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.3, random_state=42)
二項ロジスティック回帰モデルの構築
ロジスティック回帰モデルをデータに適合さる
ロジスティック回帰モデルを構築し、そのモデルをトレーニングデータに適合させます。つまり、X_trainに対してY_trainが導かれるようにパラメータを推定させます。
clf = LogisticRegression().fit(X_train,y_train)
パラメータ推定値の取得
モデルから偏回帰係数と切片の2つのパラメータを取得します。
偏回帰係数
print(clf.coef_)
[[0.99752883]]
切片
print(clf.intercept_)
[-3.19359054]
モデルのプロットの作成
モデルのプロットを作成し、結果を視覚化します。
sns.regplot(x="Inflight entertainment", y="satisfaction", data=df_subset, logistic=True, ci=None)
plt.show()
考察
グラフは、機内エンターテイメントの価値が高いほど顧客満足度も高くなることを示しているようです。ですが、これだけで結論を導くのはいささか早急なのでもう少し詳細な分析を行います。
混同行列を使用した二項ロジスティック回帰モデルの生成とその評価
テストデータセットの結果の予測
回帰分析が完了したので、結果を確認して分析します。まず、ホールドアウト法で分離したテストデータを predict 関数に入力して、モデルから値を取得します。そして、その値をテストデータの顧客満足度の値と比較することで予測の精度を確認、評価します。
各種評価指標の定義の確認
正解率(Accuracy)
精度ともいい、正しく分類されたデータの比率。
正解率(Accuracy)の計算式は以下の通り:
Accuracy = \frac{True Positives + False Negatives}{True Positives + False Positives + True Negatives + False Negatives}
適合率(Precision)
陽性的中率(positive predictive value)ともいい、陽性であると予測されたデータが実際に陽性である比率。
適合率(Precision)の計算式は以下の通り:
Precision = \frac{True Positives}{True Positives + False Positives}
再現率(Recall)
実際に陽性であるすべてのデータのうち、陽性として予測されたデータの比率。
再現率(Recall)の計算式は以下の通り:
Recall = \frac{True Positives}{True Positives + False Negatives}
F1スコア(F1 Score)
F-値とも言い、適合率と再現率の調和平均。
F1スコア(F1 Score)の計算式は以下の通り:
F = 2 \div (\frac{1}{precision} + \frac{1}{recall}) = 2 \times \frac{precision \times recall}{precision + recall}
Pythonでこれを実装します。
各種評価指標の出力
# XのテストデータよりYの予測値を取得する
y_pred = clf.predict(X_test)
# 各種指標の出力
print("正解率(Accuracy):", "%.6f" % metrics.accuracy_score(y_test, y_pred))
print("適合率(Precision):", "%.6f" % metrics.precision_score(y_test, y_pred))
print("再現率(Recall):", "%.6f" % metrics.recall_score(y_test, y_pred))
print("F1スコア(F1 Score):", "%.6f" % metrics.f1_score(y_test, y_pred))
正解率(Accuracy): 0.801529
適合率(Precision): 0.816142
再現率(Recall): 0.821530
F1スコア(F1 Score): 0.818827
考察
モデルの正解率は 80.2%であり、これはデータセットの顧客満足度54.7% (71,087/129,880) よりも向上しています。また、適合率も81.6%と高い数値を示しており、偽陽性が少ないことを示しています。(偽陽性が全く存在しなければ適合率は100%になります)。同じく再現率も82.2%となっており、偽陰性が少ないことを示しています。(こちらも偽陰性が全く存在しなければ再現率は100%になります)。F1スコアも81.9%と適合率と再現率の両方が適度にバランスが取れていることを示し、モデルの予測精度が高いと考えられます。(どちらも完璧であった場合、最大値の100%になります)。
混同行列(Confusion Matrix) の数字の理解と解釈
混同行列(Confusion Matrix) の各象限の定義の確認
混同行列は、分類器の性能を要約するのに役立ちます。混同行列の構成要素は、ロジスティック回帰分類器を評価するためのメトリクスを計算するために使用されます。
混同行列の4つの象限は、二項ロジスティック回帰分析では、以下のとおりです:
- 右上の第一象限には、偽陽性の数が示されます
- 左上の第二象限には、真陰性の数が示されます
- 左下の第三象限には、偽陰性の数が示されます
- 右下の第四象限には、真陽性の数が示されます
つまり、今回の例でいけば
- 偽陽性: モデルが誤って予測した顧客満足度の数
- 真陰性: モデルが正しく予測した顧客満足度の数
- 偽陰性: モデルが誤ってに予測した顧客満足度の数
- 真陽性: モデルが正しくに予測した顧客満足度の数
です。
モデルの当てはまりがよければ真陰性と真陽性のみを出力し、偽陰性や偽陽性は出力しません。
混同行列の生成
cm = metrics.confusion_matrix(y_test, y_pred, labels = clf.classes_)
disp = metrics.ConfusionMatrixDisplay(confusion_matrix = cm,display_labels = clf.classes_)
disp.plot()
plt.show()
考察
第一象限(偽陽性)と第三象限(偽陰性)の値が4,000未満と第二象限(真陰性) 、第四象限(真陽性)が共に13,000を超えていることに比べると少ない値です。また偽陽性と偽陰性の数値に大きな差はありません。
結論
よって、「機内エンターテイメントを高く評価した顧客は、満足度が高い傾向にありました。機内エンターテイメントを改善すれば、顧客満足度が向上するはずです」、となります。
-
Airlines Customer satisfaction https://www.kaggle.com/datasets/sjleshrac/airlines-customer-satisfaction/data ↩