ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

機械学習・クラスタリングを理解するまで6日目

前回

aipacommander.hatenablog.jp

とりあえずいい感じのプロットできました。

それでは!いよいよクラスタリング

本の通りに進めます。

ライトユーザーを除外

書籍(P46)によると、「ビジネスのデータは自然じゃないので、セグメントを別けて、とあるセグメントは分析からはずしちゃえ!」ってことをしたい

セグメントは「ライト」「ミドル」「ヘビー」で別けます。

ちなみに上位5000のクリックユーザー。恐らくこれが「ヘビー」にクラスタリングされるかと。

# grouping は前回CSVを読み込んで、昇順ソートまで終わった変数
>>> grouping_rank_5000 = grouping.head(5000)
>>> plt.plot(grouping_rank_5000, 'o')
>>> plt.show()

f:id:aipacommander:20151215235731p:plain

うむ!慣れれば楽だね。

んで、クラスタリングします。

scikit-learnimportして実行します。

>>> from sklearn.cluster import KMeans

# init
>>> kmeans = KMeans(n_clusters=3, random_state=10)

# 学習(クラスタリング)
>>> kmeans.fit(grouping)

...
ValueError: n_samples=1 should be >= n_clusters=3

なんかめっちゃエラーでた!?

なんだろうこれ・・・?

お前のサンプルは1だけど、3つより多くしろ・・・? 適当に翻訳したけど意味わからん。

色々試す。

# 参考サイトみたら numpyを使っていたからそれにする
>>> grouping2 = np.array(grouping)
>>> grouping2
array([916, 767, 761, ...,   1,   1,   1])

# どうよ!
>>> kmeans.fit(grouping2)
...
ValueError: n_samples=1 should be >= n_clusters=3 # (´Д`)

成功している例はこんな配列を渡している

features = np.array([
        [  80,  85, 100 ],
        [  96, 100, 100 ],
        [  54,  83,  98 ],
        [  80,  98,  98 ],
        [  90,  92,  91 ],
...
        [  10,  10,  10 ]
        ])

そもそも多次元の3列以外はどうなんだろう?

こうしてみる。

features = np.array([
        [ 100 ],
        [ 100 ],
        [  98 ],
        [  98 ],
        [  91 ],
...
        [  10 ]
        ])

すると

>>> kmeans.fit(features)
KMeans(copy_x=True, init='k-means++', max_iter=300, n_clusters=2, n_init=10,
    n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001,
    verbose=0)

え。。。動いた

なんでやー!!(#^ω^)

よくわからなくなりました。

で。困ったときのstackoverflow

stackoverflow.com

You are passing a 1D array while scikit expects a 2D array with a samples and a features axis.

どうやら1次元のデータはダメで2次元で渡しなさいとのことらしい。

さっきのデータは

features = np.array([ # 1次元
        [ 100 ], # 2次元
        [ 100 ],
        [  98 ],
        [  98 ],
        [  91 ],
...
        [  10 ]

2次元!(多分)

ということで、groupingのデータを2次元にすればいい。

いい感じの関数ないかなって探したけど見つからなかったので自分で実装する(つってもただのループだけど)

>>> grouping_list = []
>>> for i in grouping:
...     grouping_list.append([i])
... 
>>> grouping_np_array = np.array(grouping_list)
>>> grouping_np_array
array([[916],
       [767],
       [761],
       ..., 
       [  1],
       [  1],
       [  1]])

さて、これでどうだ!!!

>>> kmeans.fit(grouping_np_array)
KMeans(copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10,
    n_jobs=1, precompute_distances='auto', random_state=10, tol=0.0001,
    verbose=0)

よっしゃぁあ!!!!!

俺たちの戦いはここカラダ!!!

気づいたら24時前なので、続きはまた明日。