【Pythonデータサイエンス超入門2-2】機械学習の基本〜教師なし学習編〜【YouTube】
動画で学べるPythonによるデータサイエンスの基礎シリーズ、5本目です。いよいよ機械学習を扱っていきます。
まずは「教師なし学習」の手法と実装方法を会得しましょう。
動画
アジェンダ
時間 | 内容 |
---|---|
0:00 | イントロダクション |
2:17 | 機械学習とは? |
12:40 | 次元削減 |
18:02 | ├ Pythonによる次元削減の実行 |
24:08 | ├ 寄与率の計算 |
26:06 | ├ 結果の図示 |
28:10 | ├ 結果の解釈 |
33:14 | └ PCA以外の手法 |
42:24 | クラスタリング |
45:43 | ├ Pythonによるクラスタリングの実行 |
46:06 | ├ 階層クラスタリング |
50:06 | ├ 非階層クラスタリング(K-means) |
54:43 | ├ 結果の図示 |
58:05 | ├ クラスタ数の推測(エルボー法) |
1:01:39 | └ X-means |
1:09:36 | アソシエーション分析(バスケット分析) |
1:13:47 | ├ Pythonによるアソシエーション分析の実行 |
1:19:46 | └ ネットワーク図の作成 |
1:24:39 | クロージング |
シリーズ一覧
CSVのダウンロード
skill_level.csv
fruits_sales.csv
ソースコード
ライブラリ・データの読み込み
1 2 3 4 5 6 |
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt df_skill = pd.read_csv("skill_level.csv",index_col=0) |
次元削減
PCA(主成分分析)
1 2 3 |
from sklearn.decomposition import PCA model_dim = PCA(n_components=2) vecs_list = model_dim.fit_transform(df_skill) |
SVD(特異値分解)
1 2 3 |
from sklearn.decomposition import TruncatedSVD model_dim = TruncatedSVD(n_components=2) vecs_list = model_dim.fit_transform(df_skill) |
t-SNE
1 2 3 |
from sklearn.manifold import TSNE model_dim = TSNE(n_components=2, perplexity=5) vecs_list = model_dim.fit_transform(df_skill) |
UMAP
1 2 3 4 |
import umap.umap_ as umap from scipy.sparse.csgraph import connected_components model_dim = umap.UMAP(n_components=2, n_neighbors=5) vecs_list = model_dim.fit_transform(df_skill) |
寄与率の計算
1 |
model_dim.explained_variance_ratio_ |
※PCA/SVDのみ
結果の2次元表示
1 2 3 4 5 6 7 8 9 10 11 12 |
# x,yの分離 X = vecs_list[:,0] Y = vecs_list[:,1] # グラフの作成 sns.set(font="Hiragino Maru Gothic Pro",context="talk") plt.figure(figsize=(8, 8)) sns.scatterplot(X,Y) for i,(x_name,y_name) in enumerate(zip(X,Y)): plt.annotate(df_skill.index[i],(x_name,y_name)) plt.show() |
Y軸の意味の推察
1 2 3 4 5 6 7 8 9 10 |
X_comp, Y_comp = model_dim.components_ sns.set(font="Hiragino Maru Gothic Pro",context="talk") plt.figure(figsize=(8, 8)) sns.scatterplot(X_comp,Y_comp) for i,(annot_x,annot_y) in enumerate(zip(X_comp,Y_comp)): plt.annotate(df_skill.columns[i],(annot_x,annot_y)) plt.show() |
※PCA/SVDのみ
クラスタリング
階層クラスタリング
1 2 3 4 5 6 7 |
from scipy.cluster.hierarchy import linkage,dendrogram,fcluster linkage_result = linkage(df_skill, method = "ward") sns.set(font="Hiragino Maru Gothic Pro",context="talk") plt.figure(figsize=(10, 6)) dendrogram(linkage_result, labels = df_skill.index) plt.show() |
・単結合法(最短距離法) (method = “single”)
・完全結合法(最長距離法) (method = “complete”)
・郡平均法 (method = “average”)
・ウォード法 (method = “ward”)
非階層クラスタリング(K-means++)
1 2 3 |
from sklearn.cluster import KMeans vec = KMeans(n_clusters = 3) group_num = vec.fit_predict(df_skill) |
クラスタ別集計
1 2 |
df_skill_2 = df_skill.copy() df_skill_2["グループ名"] = group_num |
クラスタリング結果の確認 (クラスタリング×次元削減)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
model_dim = TruncatedSVD(n_components=2) vecs_list = model_dim.fit_transform(df_skill) X = vecs_list[:,0] Y = vecs_list[:,1] sns.set(font="Hiragino Maru Gothic Pro",context="talk") plt.figure(figsize=(8, 8)) #クラスタ別に色分け color_codes = {0:"red",1:"blue",2:"green",3:"yellow"} colors = [color_codes[x] for x in group_num] plt.scatter(X,Y,color=colors) for i,(x_name,y_name) in enumerate(zip(X,Y)): plt.annotate(df_skill.index[i],(x_name,y_name)) plt.show() |
K-meansの最適なクラスタ数推測(エルボー法)
1 2 3 4 5 6 7 8 9 10 11 |
SSE = [] for i in range(1,11): km = KMeans(n_clusters = i) km.fit(df_skill) SSE.append(km.inertia_) plt.plot(range(1,11),SSE,marker="o") plt.xticks(range(1,11)) plt.xlabel("Number of clusters") plt.ylabel("SSE") plt.show() |
非階層クラスタリング(X-means)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#適当なデータの生成 random_data = np.concatenate(( np.random.uniform(10, -10, (50, 2)), np.random.uniform(20, -20, (100, 2)) + [0, 100], np.random.uniform(30, -30, (150, 2)) + [100, 0], np.random.uniform(40, -40, (200, 2)) + [100, 100], ), axis=0) import pyclustering from pyclustering.cluster.xmeans import xmeans from pyclustering.cluster.center_initializer import kmeans_plusplus_initializer xm_c = kmeans_plusplus_initializer(random_data, 2).initialize() xm_i = xmeans(data=random_data, initial_centers=xm_c, ccore=True) xm_i.process() classes = len(xm_i._xmeans__centers) predict = xm_i.predict(random_data) clusters = xm_i.get_clusters() pyclustering.utils.draw_clusters(random_data, clusters) |
アソシエーション分析(バスケット分析)
分析の実行
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#データの読み込み&整形 df_sales = pd.read_csv("fruits_sales.csv",index_col="名前") #形式変換 df_sales = df_sales.fillna(False).replace("○",True) from mlxtend.frequent_patterns import apriori, association_rules, fpgrowth #aprioriアルゴリズムでsupportが高い単品or組み合わせを選出 freq_items = apriori(df_sales, min_support=0.1, use_colnames=True) #上で選ばれた組み合わせの中でliftが高い組み合わせを選出 freq_items_top = association_rules(freq_items, metric = "confidence",min_threshold = 0.5) |
ネットワーク図の作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import networkx as nx # 親ノードの抽出 ant = freq_items_top['antecedents'].values ant = [tuple(x) for x in ant] # 子ノードの抽出 con = freq_items_top['consequents'].values con = [tuple(x) for x in con] # 全ノードのリストアップ both = list(set(ant + con)) # 関係グラフの初期化 G = nx.DiGraph() # ノードの追加 for n in both: G.add_node(n) # エッジの追加 for i in range(len(freq_items_top)): item = freq_items_top.loc[i] ant = tuple(item['antecedents']) con = tuple(item['consequents']) G.add_edge(ant, con) # グラフの描画 pos = nx.spring_layout(G,seed=0,k=1.0) plt.figure(figsize=(15, 10)) nx.draw_networkx_nodes(G, pos) nx.draw_networkx_edges(G, pos) nx.draw_networkx_labels(G, pos, horizontalalignment='left', verticalalignment='center', font_family='Hiragino Maru Gothic Pro') plt.axis('off') plt.tight_layout() plt.show() |