Lattix/Understandのメトリクスをデータ分析してみた③([Lattix] Sturtevantの構造複雑度)

はじめに

前回、こちらのブログ記事にて、Sturtevantの構造複雑度を使用したメトリクスの活用という題目のもと、VFI・VFO(Visibility Fun-in/out)を使った閾値分けについて紹介しました。[第2回記事はこちらから]

今回はこのシリーズの最後としまして、閾値分けを行ったVFI・VFOに対して、分析しやすいように、グラフにプロットすることご紹介します。

プロット関数の定義

まず、グラフとしてプロットするために、必要なプロット関数の定義を以下のように行います。
今回はプロット関数を2種類用意し、グラフにプロットしていきます。

構造複雑度別に各ファイルをプロットする関数
def plot_xy(x_metrics,y_metrics,df,title=""):
    if title == "":
        title = str(x_metrics)+"-"+str(y_metrics)+"のグラフ(構造複雑度別)"
    x_metrics = x_metrics
    y_metrics = y_metrics

    x = df[x_metrics]
    y = df[y_metrics]
    group = df["group"]

    import plotly.express as px

    symbols =["circle","square","star","x","cross"]
    data = [
        go.Scatter(
            x=x[group==i], y=y[group==i],
            name=groupname[i],
            mode = 'markers',
            marker = dict(color=px.colors.qualitative.Plotly[i],
                size=6,
                symbol='star'
                ),
            text = df["サブシステム"][group==i]
        )
        for i in range(len(groupname))
    ]

    fig = go.Figure(data=data)
    fig.update_xaxes(title_text=x_metrics)
    fig.update_yaxes(title_text=y_metrics, hoverformat=".3f")
    fig.update_layout(title=dict(text='<b>'+title,
                             font=dict(size=26,
                                       color='black'),
                             xref='paper', # container or paper
                             x=0.5,
                             y=0.9,
                             xanchor='center'
                            ))

    plotly.offline.iplot(fig)
    return fig

クロス集計した結果をプロットする関数
def plot_xy_cross(x_metrics,y_metrics,df,title=""):
    if title == "":
        title = str(x_metrics)+"-"+str(y_metrics)+"のグラフ(クロス集計)"
    x_metrics = x_metrics
    y_metrics = y_metrics

    x = df[x_metrics]
    y = df[y_metrics]
    group = df["group"]
    cyc_group = df["cyc_group"]

    

    symbols =["circle","square","star","x","cross"]
    data = [
        go.Scatter(
            x=x[cyc_group==i][group==j], y=y[cyc_group==i][group==j],
            name=cyc_groupname[i]+" & "+groupname[j],
            mode = 'markers',
            marker = dict(color=px.colors.qualitative.Plotly[i],
                size=4,
                symbol=symbols[j]
                ),
            text = df["サブシステム"][group==j][cyc_group==i]
        )
        for i in range(len(cyc_groupname)) for j in range(len(groupname))
        
    ]

    fig = go.Figure(data=data)
    fig.update_xaxes(title_text=x_metrics)
    fig.update_yaxes(title_text=y_metrics, hoverformat=".3f")
    fig.update_layout(title=dict(text='<b>'+title,
                             font=dict(size=26,
                                       color='black'),
                             xref='paper', # container or paper
                             x=0.5,
                             y=0.9,
                             xanchor='center'
                            ))

    plotly.offline.iplot(fig)
    return fig

VFI-VFOグラフの描画

ここからは上記で定義したプロット関数を使って、VFI-VFOグラフを描画していきます。

VFI-VFOグラフの描画
fig = plot_xy("VFI","VFO",df_ltx_file,"VFIとVFOの各ファイル分布(構造複雑度別)")
fig.write_html("VFIとVFOの各ファイル分布(構造複雑度別).html")

今回出力するVFI-VFOグラフはplotlyで触れるインタラクティブなグラフを生成しているため、(jupyterから出力されたhtmlでもインタラクティブ性が維持される)以下のようなこともグラフに対して操作できます。

  • 各データ点をマウスオーバーすることでファイル名のポップアップ
  • 凡例毎に表示/非表示の操作
  • グラフ内をドラッグすることで範囲を限定して表示(グラフをダブルクリックで全体表示に戻る)
  • x軸、y軸のスクロールの操作

出力すると以下のようなグラフを表示することができます。

fig = plot_xy_cross("VFI","VFO",df_ltx_file,"VFIとVFOの各ファイル分布(クロス集計)")
fig.write_html("VFIとVFOの各ファイル分布(クロス集計).html")

このグラフから、ファイルがどこの閾値のグループに属しているのかを視覚的に確認することができます。
また、影響が大きいファイルを事前に把握することで、属するグループ毎に、重点的にレビューやテストを行うなどの対応策を事前に打ち出すことができます。その結果、ソースコードの修正の効率化、不具合混入のリスクを下げるなどの効果を期待できます。

まとめ

今回、計3回に渡って、Sturtevantの構造複雑度の分析スクリプトをご紹介しました。
Understand・Lattixでメトリクスを計測することはできていても、なかなかどのように活用すればよいか分からない、効率的にソースコードの保守を行うにはどうすればよいのか分からない、といった、課題について、解決策のひとつとして参考いただけると幸いです。
また、今後もこのような分析を手助けするようなTipsもご紹介できればと思います。

最後までご覧いただきありがとうございました。

タイトルとURLをコピーしました
Close Bitnami banner
Bitnami