0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Saas製品のオンボーディングにおける各設定項目がPaidへの影響度を分析してみた。

Last updated at Posted at 2025-02-22

はじめに

自分が今、Saasベンダーに勤めております。
初めて自社製品を利用するユーザー向けに新しいオンボーディングのガイドを設計することが現在の主な仕事です。

したがって、現在のオンボーディングにおける各設定項目の中でどの項目がPaid率への影響が大きいかを分析し、メインの改善内容に示唆だしたいと思います。

分析の目的

オンラインユーザー活躍度とPaid率を向上させるため、優先的に取り掛かるべき行動を見出すことです。

実行環境

パソコン:MacBook Pro
開発環境:Google Coraboratory
言語:Python
ライブラリ:Pandas、Numpy、Matplotlib

分析の流れ

  1. csvデータの準備
  2. モデルの選択
  3. データの前処理
  4. ロジステック分析の実行
  5. グラフによる可視化

1. csvデータの準備

オンボーディングの各項目の設定状況とPaidステータスのデータは自社BIツールからダウンロードしたものです。

利用するデータ(一部抜粋)

image.png

全部で8450本記録です。
※一部モザイクをかけています。

2. モデルの選択

分析したい内容:各項目の設定状況がPaidの有無にどれぐらい影響あるか
説明変数:各項目の設定状況
目的変数:Paid状態

目的変数のPaid状態はPaidとUnPaid2つしかないので、ロジスティック回帰を使うことにしました。

3. データの前処理

必要なライブラリをインポートする

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

ファイルを読み込む

df = pd.read_csv('/content/onbo.csv')
df

データを出力してみると、*FirstOrderDate* の欄に空値があることがわかりました。

image.png

左から4列目からは各項目になります。中にはUndone,BeforePaid,AfterPaidの値が入っています。

念の為、その他の列に空値があるかを確認します。

空値の確認

df.isnull().sum()

出力結果は以下になります。
FirstOrderDate以外に、ProjectCreatTime列にも空値があります。
ただし、今回の説明変数にProjectCreatTimeを使いませんので、特に処理しなくても良いです。
image.png

データの変換

FirstOrderDateの列は
・値がある=Paidした
・空値=Paidしていない

また、項目の列は
・Undone=設定していない
・BeforePaid=Paidになる前で設定した
・AfterPaid=Paidになった後で設定した

そこで、FirstOrderDateの空値を0に、空値ではないところを1に変換します。

df['First Order Start Date'] = df['First Order Start Date'].apply(lambda x: 0 if pd.isnull(x) else 1)

各項目の列に、以下の様にデータを変換します。

・Undoneを0に
・BeforePaidを1に
・AfterPaidを2に

df = df.replace({'Undone':0,'Before Paid':1,'After Paid':2})

分析する際に、ProjectIDProjectCreateTimeの2列を使わないので、削除します。
FirstOrderDateの名前をPaidStatusに変更します。

df = df.drop(['Project ID',' Project Create Time'], axis = 1)
df = df.rename(columns = {'First Order Start Date':'Paid Status'})
df.head()

このようにきれいなデータが完成です。

image.png

4. ロジステック分析の実行

データの分割

モデルの選択節では、以下を説明しましたので、
その通り説明変数と目的変数を定義し、データを学習用と検証用に分割します。

説明変数:各項目の設定状況
目的変数:Paid状態

x = df.drop('Paid Status', axis = 1)
y = df['Paid Status']

x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.3, random_state= 5)

説明変数の標準化

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(x_train)

x_train_std = sc.transform(x_train)
x_test_std = sc.transform(x_test)

分析を実行

model = LogisticRegression()
model.fit(x_train_std, y_train)
print(model.coef_)
print(model.intercept_)

Datacenterの項目を完了したユーザーがPaidに至る確率は高い傾向が見受けられます。

image.png

モデルを評価する

model.score(x_train, y_train)

ロジスティック回帰の場合、mode.score()ではAccuracyを返します。
image.png

一見したところAccuracyが高いです。
他の指標も使ってモデルを評価してみます。

from sklearn.metrics import (
    confusion_matrix,
    precision_score,
    recall_score,
    roc_auc_score,
    f1_score)
print(confusion_matrix(y_test,model.predict(x_test_std)))
print(f'precision: {precision_score(y_test,model.predict(x_test_std))}')
print(f'recall: {recall_score(y_test,model.predict(x_test_std))}')
print(f'roc_auc: {roc_auc_score(y_test,model.predict(x_test_std))}')
print(f'f1_score: {f1_score(y_test,model.predict(x_test_std))}')

出力の結果
適合率は微妙ですが、ROC-AUCは高い傾向が見受けられます。

image.png

Precision(適合率): 0.916 (92%)
陽性と予測したもののうち、実際に陽性だった割合
Recall(再現率): 0.422 (42%)
実際の陽性のうち、正しく陽性と予測できた割合
ROC-AUC: 0.710 (71%)
モデルの全体的な識別能力
F1スコア: 0.578 (58%)
PrecisionとRecallの調和平均


次はROC曲線を出してみます。

from sklearn.metrics import roc_curve, auc

#検証データがクラス1に属する確率
y_score = model.predict_proba(x_test_std)[:, 1] 

#ROC曲線のデータを計算
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=y_score)

#ROC曲線のプロット
plt.plot(fpr, tpr, label='roc curve (area = %0.3f)' % auc(fpr, tpr))
plt.plot([0, 1], [0, 1], linestyle='--', label='random')
plt.plot([0, 0, 1], [0, 1, 1], linestyle='--', label='ideal')

#グラフの設定
plt.legend()
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.show()

出力結果
image.png

指標 解釈
AUC (曲線下面積) 0.931 優れた識別能力
理想曲線との乖離 小さい ほぼ最適に近い性能
ランダム予測差 43% (0.930 - 0.5) × 100

5. グラフによる可視化

feature_names = x.columns 
feature_importance = pd.DataFrame({'feature': feature_names, 'importance': model.coef_[0]})
feature_importance = feature_importance.sort_values('importance', ascending=False)


plt.figure(figsize=(10, 6))
sns.barplot(x='importance', y='feature', data=feature_importance)
plt.title('Feature Importance')
plt.show()

print("\n各項目の重要性:")
print(feature_importance)

出力結果

image.png

結論

目的変数のPaidに対して、Datacenterは最も重要度が高く、Heatmapの重要度が低いという結果になりました。
ただし、heatmapは自社製品の主軸機能になりますので、オンボーディング段階では捨てるわけにはいけません。
-0.01という結果から、オンボーディングにおけるheatmap項目の改善を急ぐべきという示唆が得られると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?