コンサルでデータサイエンティスト

仕事でPythonを書いてます。機械学習、Webマーケティングに興味があります。趣味は旅です。

高い圧縮率を誇るbz2拡張子ファイルを圧縮・解凍する方法

サーバ上やローカルのLinuxで作業していると、直近で必要のないファイルが溜まって容量が不足してしまうことがありますよね。

そんな問題を解決してくれるのが圧縮・展開系のコマンドです。
zipやgzipなどさまざまなコマンドがありますが、それらと比較して高い圧縮率で圧縮できるのがbzip2コマンドです。
bzip2コマンドや、bz2拡張子を持つファイルに馴染みのない方も多いと思いますが、サーバの容量を圧迫したくないときなどにはおすすめなコマンドです。

今回はそんなbzip2による圧縮・解凍コマンドを備忘録としてまとめておきます。

 

目次

f:id:hktech:20181126222606j:plain
 

bz2ファイルへの圧縮方法

bzip2 コマンドによる圧縮方法は次の通りです。

$ bzip2 compression.log


圧縮後は以下のように拡張子.bz2を持つファイルに圧縮されます。

compression.log.bz2


圧縮処理自体に時間はかかりますが、ファイルによっては50倍以上の小ささに圧縮することができます。

また、ディレクトリ(フォルダ)ごと圧縮したい場合は以下のように圧縮することができます。

tar cvjf compression.tar.bz2 logs/

 

bz2ファイルの解凍方法

bz2拡張子を持つファイルの解凍方法は2通りあります。

bunzip2コマンドを使う場合は以下の通りです。bunzip2は解凍専用コマンドなので特にオプションは必要ありません。

$ bunzip2 compression.png.bz2

 

bzip2コマンドを使う場合は以下の通りです。d オプション (decompression) をつけることでファイルを解凍・展開することができます。

$ bzip2 -d compression.png.bz2

 

さきほどディレクトリごと圧縮する方法を紹介しましたが、このような場合の解凍方法は以下の通りです。

$ tar xvjf compression.tar.bz2

 

まとめ

bzip2 コマンドを使ったbz2拡張子ファイルの圧縮・解凍方法について紹介しました。さまざまな圧縮コマンドがありますが、Linux環境ではbzip2をおすすめします。実際の業務では、サーバの容量に制約条件があったりするので覚えておいて損はないと思います。容量があふれそうだけどファイルを消したくない、そんなときに試してみてはいかがでしょうか。

SSH先でJupyter notebook を使用する方法

Raspberry PiAWS EC2など、ローカルからリモートサーバに接続してPythonのプログラムを書く際にJupyter notebookを使いたくなることがあると思います。今回はSSH先でJupyter notebookを立ち上げて、ローカルで使用する方法についてご紹介します。

目次

SSH接続したリモート先の設定

リモートサーバ側の設定方法について確認していきます。
RaspberryPi でJupyter notebookを使用したい方は こちらの記事AWS EC2で使用したい方は こちらの記事を参考にしていただいてもよいかもしれません。


まずは外部接続環境用のJupyter notebook 設定ファイルを作成します。

mkdir ~/.jupyter


設定ファイル (config file) をviエディタで編集していきます。

vi ~/.jupyter/jupyter_notebook_config.py


ファイルが空の場合は下記の2行を書き込みましょう。

c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.port = 8888


ほとんどの場合、このファイルは空ではないので、該当行を探して編集しましょう。

vi ではスラッシュで文字列を検索できます。先頭のコメントアウト文字列#を消して、上の例のように2行分を編集しましょう。

/c.NotebookApp.ip


編集が完了したらファイルを保存してエディタを終了します。

:wq


最後に、Jupyter notebookを作成したいディレクトリに移動し下記のコマンドを実行します。

jupyter notebook


正常に起動できていれば、下記のようなメッセージが表示されます。

Copy/paste this URL into your browser when you connect for the first time,
to login with a token:
http://(raspberrypi or 127.0.0.1):8888/?token=abcabc123efg456xyz


リモート側の設定は以上となります。


ローカルの設定

ローカル側では特に設定は必要ありません。

適当なブラウザを開いて、URL欄に先ほどのURLを入力しましょう。

以下の画面が表示されれば無事にすべてのステップが完了です!

f:id:hktech:20181118231958p:plain

まとめ

SSH先でJupyter notebookを使用する方法についてご紹介しました。Python でプログラムを実装したり、データ解析などをしたい場合はJupyter notebookをリモートサーバだからJupyter notebookが使えないというのももったいないので、この記事を参考にしながら設定をしてみてはいかがでしょうか。


参考記事

RaspberryPi の場合

RaspberryPiでJupyter notebookを使う場合の設定方法はこちら
qiita.com

AWS EC2 の場合

AWS EC2でJupyter notebookを使う場合の設定方法はこちら
blog.roy29fuku.com

Pythonでk-NNをフルスクラッチで実装してみた

Scikit-learnを始めとしたパッケージが充実してきているおかげで、データ分析に関わる人もスクラッチから機械学習モデルを実装する機会が少なくなっています。

しかし、機械学習モデルを理解するためにはそのモデルを実装してみるのが一番早いと言われています。たとえパラメータをいじるだけの作業であったとしても、モデルの理解が深い人とそうでない人では、問題解決の質が変わってきます。

本記事では、最も基本的な分類モデルである k-NN (k-Nearest Neighbor) 法をフルスクラッチで実装したのでご紹介します。

目次

k-Nearest Neighbor法

k-Nearest Neighbor 法 (k-NN)k近傍法とも呼ばれ、分類モデルの中でももっともシンプルに実装できるものとして広く知られています。

k-NNとは、特徴量空間にデータをプロットしたときに、プロットと距離が近い学習データを近いものから順にk個選び出し、それらの学習データのクラスを多数決することでデータのクラスを決定する分類モデルです。

図のように、青四角クラス赤丸クラスの学習データが配置された特徴量空間を考えます。

k-NNのkは、テストデータ(星型)から何個の近傍点をクラス予測時に考慮するかということを決定するパラメータです。この例の場合、k=3のときは赤い学習データのほうが多いため赤クラスに分類されます。一方で、k=5のときは青のほうが多数となるため、テストデータは青クラスに分類されます。

f:id:hktech:20180926093820p:plain

k-NNをPythonで実装する

k-NNの概要については理解していただけたと思います。実にシンプルなモデルであるため、スクラッチから実装することはさほど難しくないです。それどころか、データサイエンティストであればこれくらいは実装できるのが最低要件だと思います。


シンプルである一方で、テストデータと複数の学習データとの距離をそれぞれ計算する必要があるため、計算量が多いという欠点があります。

こちらが実装したコードです。

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
import time


def load_data():
    iris = load_iris()
    return train_test_split(iris.data, iris.target, test_size=0.3)

def predict(k, test_plot, X_train,  y_train):
    dist_dict = {}

    for i, train_plot in enumerate(X_train):
        dist = np.linalg.norm(train_plot - test_plot)

        if len(dist_dict) <  k:
            dist_dict[dist] = y_train[i]    
        elif dist < np.max(list(dist_dict)) and len(dist_dict) == k:
            dist_dict.pop(np.max(list(dist_dict)))
            dist_dict[dist] = y_train[i]     

    count = np.bincount(list(dist_dict.values()))
    pred = np.argmax(count)
    return pred

def predict_test_data(k, X_train, X_test, y_train, y_test):
    pred_list = []
    
    for test_plot in X_test:
        pred = predict(k, test_plot, X_train, y_train)
        pred_list.append(pred)
    return f1_score(y_test, pred_list, average='macro')

if __name__ == '__main__':
    X_train, X_test, y_train, y_test = load_data()
    start_time = time.time()
    fscore = predict_test_data(3, X_train, X_test, y_train, y_test)
    process_time = time.time() - start_time
    print('F-score: {:.3f}'.format(fscore))
    print('Process time: {:.3f} sec'.format(process_time))

実装したモデルをirisデータセットを用いてF値で評価すると、次のような結果となりました。

F-score: 0.978
Process time: 0.118 sec

クラスの分類がうまくいっていることを確認することができました。

k-NNの特徴としてすべての点との距離を求める処理が必要となることから計算量が大きくなってしまうということがあります。そのため、プログラムの実行時間を計測できるような処理を実装しています。今回は何も考えずに最も単純な方法で実装したため計算量がかなり大きくなってしまっています。

Scikit-learnなどで実装されているk-NNは、この問題をできるだけ解決するように実装の工夫がなされています。実装を工夫した際のコードについてはまた別の機会にご紹介できればと思います。

まとめ

k-Nearest Neighbor法をフルスクラッチで実装してみました。まずは計算量などを考慮せずに最低限の精度が出るモデルの実装ができたので、次のステップとして高速化を考えていきたいです。k-NNは最も単純な機械学習モデルのひとつです。この記事を参考にしつつ、一から実装してみてはいかがでしょうか。


関連記事
決定木分類器をフルスクラッチで実装した際の記事です。
hktech.hatenablog.com

異常検知ビジネスで活用できる外れ値検知手法まとめ

機械学習の中でも教師なし学習に分類される分野として異常検知という技術があります。研究分野としては近年下火になりつつあるものの、人工知能やAIを使った異常検知技術はビジネス界隈では期待の大きい分野として有名です。

本記事では、異常検知分野のなかでも外れ値検知の一般的な手法についてまとめました。


目次

はじめに

外れ値検知はビジネスにおけるさまざまな場面で使用されています。

外れ値検知とは、正常時の状態から外れた点を見つけ出す異常検知の種類のひとつです。クレジットカードの利用状況の解析などでは、異常な行動を即時に検出することで被害の拡大を防ぐことができます。また、工場などのモニタリングでは、機械の異常状態をセンサなどで検知してアラートを出すなどのユースケースが考えられます。大量のデータをモニタリングする必要のあるセキュリティ分野や機械などを無人でモニタリングするスマートファクトリー分野のほか、高齢者の転倒検知や患者の体調急変といった予測に需要があるヘルスケア分野などでも実用化が始まっています。

それでは、最初におさえておきたい4つの基本的な外れ値検知手法について確認していきます。

ホテリング理論

最も基本的な手法として、ホテリング理論による外れ値検知について紹介します。

この手法は平均や分散といったデータの基本的な分布情報をもとに、観測値 x' より算出した異常度 a(x') を用いて外れ値検知を行うものです。まずは一般的な外れ値手法を理解するところから始めましょう。

はじめに、ほとんど外れ値が含まれていない1次元のデータセットを用意します。ホテリング理論ではこのデータセット正規分布に従うことを大前提としているため、ヒストグラムやQQ Plot などを使って正規分布であることを確認しておきましょう。もし正規分布でない場合は対数変換ボックスコックス変換などをかけて正規化する必要があります。

正規分布を仮定した場合、ホテリング理論をもとに算出した異常度はデータ数が十分に大きければ自由度1のカイ二乗分布に従うとされています。

chi_squared_distribution

異常発生の確率値 α を定義すれば、カイ二乗分布の表から異常度の閾値を求めてることができます。たとえば、発生確率が 1% 以下のものを異常値とするのであれば、α = 0.01 に対応する異常度を閾値に設定すればよいということになります。

異常度は次式で求めることができます。

 異常度  \,\,  a(x')= \Bigl(\frac{x'-\hat{\mu}}{\hat{\sigma}}\Bigr)


以上が1次元データにおけるホテリング理論による外れ値検知でした。



多次元データ(2次元以上)にこれを適用する場合は、マハラノビス距離という指標を異常度として採用します。マハラノビス距離とは、データの分布を考慮した距離の指標です。

1次元データでは平均と分散を求めましたが、多次元データでは標本平均と標本共分散行列を下記のように求めます。

 標本平均 \qquad \quad \, \, \hat{\mu} = \frac{1}{N} \sum_{n=1}^{N} x^{(n)}
 標本共分散行列 \quad \hat{\Sigma} \frac{1}{N}\sum_{n=1}^{N} (x^{(n)} - \hat{\mu})(x^{(n)} - \hat{\mu})^T


また、異常度はマハラノビス距離を用いて以下のように求めることができます。

 異常度  \,\,  a(x')= (x'-\hat{\mu})^T \hat{\Sigma}^{-1}(x'-\hat{\mu})


1次元でも多次元でも、異常度というスカラー値に落としこんでいるという点では共通していることがわかります。このように求めた異常度に閾値を設定することで、異常か正常かを識別することができます。
明らかに分布から外れている異常点を検出したいときには有効な手法です。

k-近傍法 (k-NN)

あまり有名ではないものの、シンプルに実装ができる古典的な手法として k-近傍法 (k-NN) による外れ値検知 があります。k-近傍法は k-nearest neighbor 法とも呼ばれていますが、異常検知におけるk-近傍法は機械学習の最も基本的な分類手法である k-NNとは少し異なることに注意してください。

想像ができている方もいらっしゃると思いますが、この手法ではk-NNと同様にある点から最も近い k 個の点を考慮して外れ値検知を行います。対象の点から近傍のk個の点を含むような円を描きます。

次の例では k=5 のときを考えます。

knn_anomaly

このとき、データ群から離れた異常点が描く円の半径 ε は正常データ群のものよりも大きくなっていることがわかります。
この性質に基づき、ε を異常度として使用して外れ値検知を行います。具体的には、εがある閾値を超えた場合は異常、そうでない場合は正常といったようにスカラー値に落として外れ値を検出することができます。
メリットとして、多次元データにもそのまま適用できるということがあります (ただし、次元数が10以下を目安と考えたほうがよいでしょう)。一方で、すべての点との距離を計算する必要があることから、計算量が大きくなってしまうというデメリットがあります。


Local Outlier Factor (LOF)

同じく距離をベースにした外れ値検知手法として、Local Outlier Factor (LOF) を紹介します。
この手法では 局所密度 (Local density) という指標に注目します。 局所密度は、周辺の点との密度を表します。点Aは近傍の点 B, C, D との距離が大きいため、局所密度が低いということになります。一方で、点B, C, D はそれぞれの近傍点との距離が近いため局所密度が高いといえます。

Local Outlier Factor (LOF)

つまり、近傍点の局所密度が類似している場合には近くにデータが集まっているということがわかります。点Aのようにデータ群と離れているような点の場合、自身の局所密度と近傍点の局所密度の差が大きいということになります。この差を利用して外れ値を検出することができるのが LOF です。

より詳しい内容については次の記事でまとめたので興味がある方はご確認ください。

hktech.hatenablog.com


One class SVM (Support Vector Machine)

分類アルゴリズムである Support Vector Machine (SVM) を応用した外れ値検知手法として、One class SVM を紹介します。

One class SVMとは、機械学習の分類アルゴリズムである Support Vector Machine (SVM) を教師なしの1クラスに適用した手法です。正常データとして1つのクラス分を学習させ、識別境界を決定することで、その境界を基準として外れ値を検出します。異常がほとんど発生せず、異常クラスのデータを集めにくいようなシステムで異常検知を実現したい場合には有効な外れ値検知手法です。

One class SVMではすべての学習データをクラスタ 1とし、原点のみをクラスタ -1に属するようにカーネルトリックと呼ばれる手法を用いて、高次元空間の特徴空間へデータを写像します。このとき、学習データは原点から遠くに配置されるように写像されるため、もとの学習データと類似していないデータは原点の近くに集まるようになります。

one_class_svm

One class SVM のメリットとしては、学習したデータをもとに複雑な境界線を引くことができるという点があります。一方で、パラメータをチューニングする必要があるというデメリットもあります。

One class SVM については次の記事でより詳細にまとめています。
hktech.hatenablog.com

まとめ

異常検知ビジネスで活用できる一般的な外れ値検知手法についてまとめました。外れ値検知をサービスや研究などで使おうと考えている方には参考になる内容になっているかと思います。Deep Learning などを使ってなにかを始めようとする前に、まずはこの記事で紹介されているような基本的なアルゴリズムで試してみてはいかがでしょうか。



異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

One class SVM による外れ値検知についてまとめた

はじめに

異常検知技術が実用システムに導入される例が増えています。今回は外れ値検知手法として人気が高いアルゴリズムのひとつであるOne class SVMについてご紹介します。

One class SVMとは、機械学習の分類アルゴリズムである Support Vector Machine (SVM) を教師なしの1クラス分類に応用した手法です。正常データとして1つのクラス分を学習させ、識別境界を決定することで、その境界を基準に外れ値を検出します。異常がほとんど発生せず、異常クラスのデータが集まらないようなシステムで異常検知を実現したい場合には有効な外れ値検知手法です。

最後にPythonによる簡単な実装例についてご紹介します。

One Class SVMSVMの違い

One Class SVMSVM の違いについて理解するためには、まずSupport Vectorとは何かということを把握する必要があります。Support Vectorとは学習データの中で最も他クラスと近い位置に点を指します。Support Vector Machineでは、各クラスのSupport Vectorを基準として、それらのユークリッド距離が最大化するように識別境界を設定します。これをマージン最大化と呼びます。

f:id:hktech:20181011233116p:plain


また、識別境界が非線形の場合はカーネルを用いてデータを特徴空間に写像します。カーネルを適切に選択することで、複雑なデータ配置でも識別境界を引くことができます。

f:id:hktech:20181011233133p:plain


通常のSVMでは、学習データとして複数クラスのデータが用意されています。したがって、学習時に識別境界を決定すれば、あるデータがどのクラスに分類されるかを判別する分類器として使うことができます。

しかし、One Class SVMでは学習データとして正常データの1つのクラスしか用意されていません。One class SVMは識別境界を設定するという点では共通しているものの、分類手法としての役割を持つSVMと異なり、識別境界を境に正常データと異常データを識別する外れ値検知手法として使うことができます。

One class SVMによる外れ値検知

SVMでは複数のクラスのSupport Vectorを基準として識別境界を決定するということは理解できました。One class SVMでは1つのクラスのみでどのように識別境界を求めるのかということについて明らかにしていきます。

One class SVMではすべての学習データをクラスタ 1とし、原点のみをクラスタ -1に属するようにカーネルトリックと呼ばれる手法を用いて、高次元空間の特徴空間へデータを写像します。このとき、学習データは原点から遠くに配置されるように写像されるため、もとの学習データと類似していないデータは原点の近くに集まるようになります。この性質を用いて正常および異常データの区別をすることができます。

f:id:hktech:20181011233151p:plain

Python + Scikit-learn を使った実装

PythonでScikit-learn (sklearn) を使えば、One class SVMを数行で実装することができます。

from sklearn.svm import OneClassSVM
clf = OneClassSVM(nu=0.003, kernel='rbf', gamma='auto')
clf.fit(X_train)
pred = clf.predict(X_test)


SVMのパラメータとしてkernelとgamma、One class SVM特有のパラメータとして nu があります。
学習データはすべて綺麗なデータであるとは限らないため、識別境界の決定時に考慮しないデータの割合をnuで定義することができます。

predictの返り値としては 正常: 1、異常: -1のリストが返ってくるため、異常と判定されたサンプルのインデックス番号を確認するには次のコードを実行します。

import numpy as np
np.where(pred < 0)

このあたりはLOFの実装のときと同じですね。このように手法が変わっても返り値が同じ形式で得られるのもScikit-learnパッケージの強みです。

まとめ

異常検知技術のひとつであるOne class SVMについてご紹介しました。One class SVMSupport Vector Machineを1クラス分類に応用することで外れ値検知を実現する手法であるということがわかりました。また、Pythonを使って簡単に実装できることも確認することができました。SVMの中身は理解が難しいことで有名であるため、機会があればスクラッチから実装してみたいと思います。

関連記事
hktech.hatenablog.com



異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

PythonでLocal Outlier Factor (LOF)を実装してみた

目次

はじめに

教師なし学習のひとつとして異常検知という分野があります。その中に含まれる手法として、正常時の状態から外れた点を見つけ出す外れ値検知手法があります。外れ値検知は実アプリケーションにも数多く導入されており、機械学習分野で注目を浴びている技術です。今回はその入門編として Local Outlier Factor (LOF) という手法をPythonで実装してみたいと思います。LOF の理論と仕組みについては次の記事でまとめたので確認してみてください。

hktech.hatenablog.com


Scikit-learnによるLOFの実装

機械学習パッケージであるScikit-learnを使って実装していきます。 今回は、Local Outlier Factor (LOF) のアルゴリズムに基づいてデータXから外れ値検知を行います。

パッケージが入っていなければ、インストールしておきましょう。

pip install scikit-learn
pip install matplotlib
pip install seaborn


早速、Scikit-learnを使って実装していきます。ここでは考慮する近傍点の数を n_neighbors=7 としています。

from sklearn.neighbors import LocalOutlierFactor
clf = LocalOutlierFactor(n_neighbors=7)
pred = clf.fit_predict(X)

Scikit-learnを使うとたった3行で外れ値を検出することができます。簡単ですね。


fit_predictの返り値としては 正常: 1、異常: -1のリストが返ってくるため、異常と判定されたサンプルのインデックス番号を確認するには次のコードを実行します。

import numpy as np
np.where(pred < 0)


試しに実際のデータを使って外れ値検知を行い、検出結果の可視化をしてみたいと思います。今回は、irisデータの一部変数を使い、2次元での可視化を行いました。

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.neighbors import LocalOutlierFactor
from sklearn import datasets
%matplotlib inline
 
iris = datasets.load_iris()
X = iris.data
 
clf = LocalOutlierFactor(n_neighbors=7, contamination=0.005)
pred = clf.fit_predict(X[:, (1, 2)])
 
# 正常データのプロット
plt.scatter(X[:,1][np.where(pred > 0)], X[:,2][np.where(pred > 0)])
# 異常データのプロット
plt.scatter(X[:,1][np.where(pred < 0)], X[:,2][np.where(pred < 0)])

f:id:hktech:20181010230057p:plain


図をみてみると、左上と右下の2つクラスタのいずれにも含まれないオレンジのサンプルが外れ値として検出されていることがわかります。このように、LOFはデータが複数のクラスタに分かれているような場合でも、それらを考慮しつつ外れ値を検出できるモデルであるということが確認できました。

まとめ

Python で Local Outlier Factor (LOF) を実装する方法についてご紹介しました。今回はScikit-learnを使って実装を進めましたが、LOFのアルゴリズム自体はそんなに難しくないため、スクラッチから実装してみるのもいい練習になるかと思います。

git rebase -i コマンドで複数のコミットを1つにまとめる

一度commitしたブランチに対してレビュー修正が入り再度コミットする必要がある場合など、複数のコミットを1つにまとめたい時がありますよね。そんなときに便利なgit rebase -i コマンドをご紹介します。

git rebase -i コマンドを使う場面

具体例を使って手順を確認していきましょう。fix api function というコミットでmerge request を出したものの、レビューでバグを指摘されたために修正コミット fix bug を出したという例を考えます。このようにMerge requestの出すまでの流れについては、次の記事にまとめてありますのでご確認ください。

hktech.hatenablog.com


このような場面でfix api function と fix bug という2つのコミットがログに残したままにしてしまうと、あとでチームメンバーが振り返ったときに何が行われていたのかわからなくなることがあります。また、チームやOSSによっては1 request 1 commitといったルールが採用されている場合もあります。そこで、複数のコミットを1つにまとめてくれる git rebase -iコマンドを使います。この -i とは -interactiveの略となっています。

git rebaseコマンドでコミットをまとめる手順

まずは、git log でgitの歴史を確認します。

git log


fix api function と fix bug というメッセージのコミットが2つあることを確認できます。

commit *****
Author: hktech
Date:   Thu Sep 27 20:58:09 2018 +0900

    fix api function

commit ******
Author: hktech
Date:   Wed Sep 19 14:19:37 2018 +0900

    fix bug


ここからいよいよ git rebase -i コマンドを使っていきます。
上から2つのコミットを1つにまとめたい場合、次のコマンドを打ちます。

git rebase -i HEAD~2 


これは、最新のコミットであるHEADから2つ目までを含めるということを表しています。
するとviなどのエディタで次のようなファイルが開きます。

pick t13rvfp fix api function
pick n2odp4q fix bug

#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#


ファイルの文面には丁寧にコマンドの用法が記載されていますが、今回はこの中のpickとsquashを使っていきたいと思います。これらのコマンドはそれぞれ次のような意味を持ちます。

  • Pick (p): コミットをそのまま残す
  • Squash (s): コミットを前のコミットに統合する

今回はfix bugのコミットをfix api function に統合したいので、fix bug をpick から s(squash) に変更し、fix api functionはpickのまま残します。

pick t13rvfp fix api function
s n2odp4q fix bug


vi の場合は:wqで保存してファイルを抜けます。
ここで、再度git log をして変更を確認します。

git log


コミットが1つにまとまっていることが確認できました。

commit *****
Author: hktech
Date:   Thu Sep 27 20:58:09 2018 +0900

    fix api function
    fix bug


この状態で再度リモート(origin)にpushしてmergeをする準備をします。

git push origin fix-api-function


おそらくここで前コミットと競合してしまうため、前のコミットを上書きする形で強制的にpushを行います。このときに使う-f オプションは -forceを意味します。これはリモートレポジトリを強制的に変更してしまうため、使う際には注意が必要です。

git push -f origin fix-api-function

無事に複数のコミットをまとめることができました。

まとめ

git rebase -iコマンドで複数のコミットをまとめる方法についてご紹介しました。せっかくgitを運用するからにはログをキレイに整理しておきたいですよね。細かいコミットをたくさんしてしまっている方は、この記事を参考にコミットをまとめる習慣をつけてみてはいかがでしょうか。