Python {Article026}

ようこそ「Python」へ...

Pythonで機械学習 超入門:好みの音楽ジャンルを予測するには【Machine Learning】

ここではPythonの機械学習用のライブラリScikit-Learnを使用した機械学習の超入門を解説します。 機械学習は一般にデータの搬入、データのクリーンナップ、データのスプリット(Training/Test)、モデル作成、学習、予測、評価の手順で行います。 ここでは学習データとして音楽のデータを使用します。音楽データは年齢、性別、年齢別の好みの音楽ジャンルなどから構成されています。 そして、年齢と性別が与えられたときに好みの音楽ジャンルを予測するといったことを学習させます。 今回のPythonによる機械学習超入門ではTensorFlow, Kerasは使用しませんが、これらのライブラリを使用できるように 「記事(Article024:Jupter Notebook)」と「記事(Article025: Visual Studio Code)」を参照して事前に開発環境を準備しておいてください。

ここではVisula Studio Code(VSC)の「Python Interactive window」 を使用してJupter Notebookのような環境で説明します。 VSCを通常の環境からインタラクティブな環境に切り換えるにはコードを記述するときコメント「# %%」を入力します。 詳しい、操作手順については「ここ」 を参照してください。 インタラクティブな環境では、Pythonの「print(), plt.show()」などを使う必要がないので掲載しているコードでは省略しています。 VSCで通常の環境で使用するときは、必要に応じて「print(), plt.show()」等を追加してください。

この記事では、Pandas、Matplotlibのライブラリを使用しますので 「記事(Article001) | 記事(Article002) | 記事(Article003) | 記事(Article004)」 を参照して事前にインストールしておいてください。 Pythonのコードを入力するときにMicrosoftのVisula Studio Codeを使用します。 まだ、インストールしていないときは「記事(Article001)」を参照してインストールしておいてください。

説明文の左側に図の画像が表示されていますが縮小されています。 画像を拡大するにはマウスを画像上に移動してクリックします。 画像が拡大表示されます。拡大された画像を閉じるには右上の[X]をクリックします。 画像の任意の場所をクリックして閉じることもできます。

click image to zoom!
Predict
click image to zoom!
Extensios
click image to zoom!
Model Chart[1]
click image to zoom!
Model Chart[2]

Scikit-Learnを使用した機械学習超入門

  1. ここで使用するPythonのライブラリを取り込む

    行3-11ではPythonのライブラリを取り込んでいます。 行7のように記述してjoblibを取り込むと「cannot import name 'joblib'...」のエラーになるので行9のように直接joblibを取り込みます。 行12ではPythonの警告メッセージを抑止しています。
    # Import the libraries
    # %%
    import pandas as pd
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score
    #from sklearn.externals import joblib 
    #ImportError: cannot import name 'joblib' from 'sklearn.externals'
    import joblib
    from sklearn import tree
    import warnings
    warnings.simplefilter('ignore')
    click image to zoom!
    図1
    図1はVisual Studio Codeの画面です。 ここではVisual Studio Codeを使用していますがJupter NotebookでもOKです。
  2. 21歳男性と22歳女性の好みの音楽ジャンルを予測する

    行2では音楽データが格納されているCSVのURLを定義しています。 このURLは当サイトのドメインです。 行3ではPandasのread_csv()メソッドで当サイトからCSVファイルをダウンロードしてDataFrameに取り込んでいます。 行8ではDataFrameから列名「genre」を削除してDataFrameを変数「x」に格納しています。 つまり、変数「x」には「年齢/age」、「性別/gender」の列から構成されるDataFrameが格納されます。 行9ではDataFrameの列「genre」を取得しています。 この場合、Pandasの列「ジャンル/genre」のSeriesが変数「y」に格納されます。 行12ではモデルのインスタンスを生成しています。 行15ではモデルのfit()メソッドで引数に指定したデータを元に学習しています。 引数1には変数「x(age,genderのDataFrame)」、引数2には変数「y(genreのSeries)」を指定しています。 つまり、年齢と性別が与えられたときの、好みの音楽ジャンルを学習させています。 行18ではモデルのpredict()メソッドで引数で指定したデータを予測しています。 ここでは「21歳男性」と「22歳女性」の好みの音楽ジャンルを予測させています。 行19では予測結果を表示しています。
    # 1) Import the data
    csv_file = 'https://money-or-ikigai.com/Menu/Python/Article/data/article026/music.csv'
    music_data = pd.read_csv(csv_file)
    
    # 2) Clean the data / Prepare the data
    
    # 3) Split the data
    x = music_data.drop(columns=['genre'])  # age, gender
    y = music_data['genre'] # genre
    
    # 4) Create a Model (Sick Learn)
    model = DecisionTreeClassifier()
    
    # 5) Train the Model
    model.fit(x, y)
    
    # 6) Make Predictions
    predections = model.predict([ [21, 1], [22, 0] ]) # predict 21 male, 22 female
    predections
    click image to zoom!
    図2-1
    図2-1はCSVファイル(音楽データ)の内容です。CSVファイルには年齢(age)、性別(gender)、好みの音楽ジャンル(genre)が格納されています。 性別の「0」が女性、「1」が男性です。 今回予測するのは「21歳男性」と「22歳女性」の好みの音楽ジャンルですが、これらの年齢のデータはCSVファイルに格納されていません。

    このようなデータから人間が予測すれば「21歳男性」の好みの音楽ジャンルは「HipHop」になります。 そして「22歳女性」の好みの音楽ジャンルは「Dance」ということになります。
    click image to zoom!
    図2-2
    図2-2は実行結果です。「21歳男性」の好みの音楽ジャンルの予測として「HipPop」、 「22歳女性」の好みの音楽ジャンルの予測として「Dance」が表示されています。 人間が予測したものとAIが予測したものが一致しています。
  3. 機械学習の正確さを測定する

    行5ではsklearn.model_selectionのtrain_test_split()メソッドで元データを学習用(x_train, y_train)とテスト用(x_test, y_test)に分割しています。 引数に「test_size=0.2」を指定しているので学習用に80%、テスト用に20%の比率で元データが分割されます。 行8ではfit()メソッドで引数で指定したデータを元に学習しています。 引数に指定したx_trainとy_trainの内容は図3-1、図3-2を参照してください。 行9ではpredict()メソッドで予測しています。 行10ではaccuracy_score()メソッドで予測のスコアを算出しています。 行11ではスコアを表示しています。
    # Calculating the Accuracy
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre'])  
    y = music_data['genre'] 
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
    #x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.8)
    model = DecisionTreeClassifier()
    model.fit(x_train, y_train)
    predections = model.predict(x_test) 
    score = accuracy_score(y_test, predections)
    score
    click image to zoom!
    図3-1
    図3-1はx_trainとy_trainの内容です。行6で「test_size=0.2」を指定しているので元データの80%が学習用データとして使用されます。
    click image to zoom!
    図3-2
    図3-2はx_testとy_testの内容です。行6で「test_size=0.2」を指定しているので元データの20%がテスト用データとして使用されます。
    click image to zoom!
    図3-3
    図3-3は行10で算出したスコアの結果です。スコアが「1」に近いほど正確だということになります。 5回試行しましたが4回とも「1」、1回だけ「0.75」のスコアでした。なので予測はかなり正確だということになります。

    試しに行6のように「test_size=0.8」に変更するとかなり悪いスコアになります。 これは、「test_size=0.8」にすると元データの20%で学習するからです。
  4. 学習モデルを保存して再使用する

    行7ではjoblibのdump()メソッドで学習モデルをjoblibファイルに保存しています。 行11ではjoblibファイルに保存した学習モデルをロードして予測しています。
    # Persisting Models
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre']) 
    y = music_data['genre'] 
    model = DecisionTreeClassifier()
    model.fit(x, y)
    joblib.dump(model, 'data/joblib/music-recommender.joblib')
    
    # %%
    
    model = joblib.load('data/joblib/music-recommender.joblib')
    predections = model.predict([ [21, 1] ]) # predict 21 male
    predections
    
    # %%
    click image to zoom!
    図4
    図4は学習モデルをjoblibファイルに保存したものをロードして予測した結果です。 「21歳男性」の好みの音楽ジャンルは「HipHop」と表示されています。 このように最適化した学習モデルをjoblibファイルに保存しておくとそれを再ロードして何回でも使用することができます。
  5. 学習モデルをdotファイルに保存して可視化する

    行7-13ではtreeのexport_graphviz()メソッドで学習モデルをdotファイルに保存しています。 dotファイルをVisual Studio Codeにドラッグすると学習モデルを可視化することができます。
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre'])  
    y = music_data['genre'] 
    model = DecisionTreeClassifier()
    model.fit(x, y)
    
    tree.export_graphviz(model, 
        out_file='data/dot/tutorial/music-recommender.dot',
        feature_names=['age', 'gender'],
        class_names=sorted(y.unique()),
        label='all',
        rounded=True,
        filled=True)
    click image to zoom!
    図5-1
    図5-1は学習モデルをdotファイルに保存している画像です。
    click image to zoom!
    図5-2
    図5-2ではVisual Studio Codeから[Extensions]のアイコンをクリックして検索窓に「DOT」を入力して検索しています。 そして検索結果から「Graphviz(dot) language support for Visual Studio Code by Jan Pinto」と 「Graphviz (dot) language support for Visual Studio Code by Stephavs」のライブラリをインストールしています。 画像では既にインストールされているので「歯車」アイコンが表示されています。 インストールされていないときは「Install」が表示されています。「Install」をクリックしてインストールしたら、Visual Studio Codeを再起動します。

    click image to zoom!
    図5-3
    Visual Studio Code(VSC)を再起動したら「DOT」ファイルをVSCのメインウィンドウにドラッグします。 そして右上の[:]をクリックしてドロップダウンリストを表示したら「Open Preview to the Side」をクリックします。
    click image to zoom!
    図5-4
    「Open Preview to the Side」をクリックすると学習モデルのフローチャートが可視化されて表示されます。 このチャートを見るとAIがどのようにして答えを導き出したかが分かります。
    click image to zoom!
    図5-5
    「21歳男性」の好みの音楽ジャンルを問い合わせときは、赤で囲っている経路をたどって答え「HipHop」を見つけます。
  6. ここで解説したコードをまとめて掲載

    最後にここで解説したすべてのコードをまとめて掲載しましたので参考にしてください。
    
    # Article024_Python Machine Learning for Beginners.py
    # %%
    #
    # Steps:
    # 1. Import the Data (csv file)
    # 2. Clean the Data
    # 3. Split the Data into Training/Test Sets
    # 4. Create a Model (Sick Learn)
    # 5. Train the Model
    # 6. Make Predictions
    # 7. Evaluate and Improve
    
    # Libraries:
    # Numpy
    # Pandas
    # Matplotlib
    # Scikit-Learn
    
    # Import the libraries
    import pandas as pd
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score
    #from sklearn.externals import joblib 
    #ImportError: cannot import name 'joblib' from 'sklearn.externals'
    import joblib
    from sklearn import tree
    import warnings
    warnings.simplefilter('ignore')
    
    # %%
    
    # 1) Import the data
    csv_file = 'https://money-or-ikigai.com/Menu/Python/Article/data/article026/music.csv'
    music_data = pd.read_csv(csv_file)
    
    # 2) Clean the data / Prepare the data
    
    # 3) Split the data
    x = music_data.drop(columns=['genre'])  # age, gender
    y = music_data['genre'] # genre
    
    # 4) Create a Model (Sick Learn)
    model = DecisionTreeClassifier()
    
    # 5) Train the Model
    model.fit(x, y)
    
    # 6) Make Predictions
    predections = model.predict([ [21, 1], [22, 0] ]) # predict 21 male, 22 female
    predections
    
    # %%
    
    # Calculating the Accuracy
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre']) 
    y = music_data['genre']
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
    #x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.8)
    model = DecisionTreeClassifier()
    model.fit(x_train, y_train)
    predections = model.predict(x_test) 
    score = accuracy_score(y_test, predections)
    score
    
    # %%
    
    # Persisting Models
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre']) 
    y = music_data['genre'] 
    model = DecisionTreeClassifier()
    model.fit(x, y)
    joblib.dump(model, 'data/joblib/music-recommender.joblib')
    
    # %%
    
    model = joblib.load('data/joblib/music-recommender.joblib')
    predections = model.predict([ [21, 1] ]) # predict 21 male
    predections
    
    # %%
    
    music_data = pd.read_csv(csv_file)
    x = music_data.drop(columns=['genre'])  
    y = music_data['genre'] 
    model = DecisionTreeClassifier()
    model.fit(x, y)
    
    tree.export_graphviz(model, 
        out_file='data/dot/tutorial/music-recommender.dot',
        feature_names=['age', 'gender'],
        class_names=sorted(y.unique()),
        label='all',
        rounded=True,
        filled=True)
    
    # %%