言語処理100本ノック 2015年版 (96-99)
96. 国名に関するベクトルの抽出
word2vecの学習結果から,国名に関するベクトルのみを抜き出せ.
国名って以前やりましたよね。
81で作った国名リストがあるのでそれを使います。
問題はU.Sみたいな前のリストに入れていない国名をどうするか。
後の設問を見る限り今回は考えなくていいかな……。
#!/usr/bin/env python import codecs import re import numpy as np import copy def getallvec(): #全ベクトル読み込み npxdict = {} fin = codecs.open('90vec.txt', 'r', 'utf_8') for line in fin: #読み込み string = re.split(" ",line[:-1]) a = [float(x) for x in string[1:301] ] npxdict[string[0]] = copy.deepcopy(np.array(a)) return npxdict if __name__ == "__main__": worddict = getallvec() fin = codecs.open('96c.txt', 'r', 'utf_8') for line in fin: #読み込み country = line[:-1] if country in worddict: npa = worddict[country] print(country,end=" ") for y in npa: print(y,end=" ") print("")
97. k-meansクラスタリング
k-meansを使ったクラスタリングもRでは経験あるんですがPythonではやったことないなあ。
scikit-learnにはあると思うな……。KMeansというそのままの名前のモジュールがありました。
今までは単語ベクトルを辞書にして持たせていましたが、KMeansで使うにはnumpyのarrayにしなくてはなりません。
getallvec関数を少々変更していきます。
#!/usr/bin/env python import codecs import re import copy import numpy as np from sklearn.cluster import KMeans def getallvec(): #全ベクトル読み込み namelist = [] npxlist = [] fin = codecs.open('96.txt', 'r', 'utf_8') for line in fin: #読み込み string = re.split(" ",line[:-1]) a = [float(x) for x in string[1:301] ] namelist.append(string[0]) npxlist.append(copy.deepcopy(np.array(a))) npxarray = np.array(npxlist) return namelist,npxarray if __name__ == "__main__": namelist,npxarray = getallvec() #k-meansクラスタリング kmeans_model = KMeans(n_clusters=5, random_state=10).fit(npxarray) labels = kmeans_model.labels_ n=0 for label in labels: print(label, namelist[n]) n += 1
結果
1 Afghanistan 0 Albania 0 Algeria 4 American_Samoa 4 Andorra 0 Angola 4 Antarctica 4 Antigua_and_Barbuda 1 Argentina (略)
98. Ward法によるクラスタリング
96の単語ベクトルに対して,Ward法による階層型クラスタリングを実行せよ.さらに,クラスタリング結果をデンドログラムとして可視化せよ.
どうやらPythonでは階層型クラスタリングは scikit-learnを使うのではなく scipy.cluster.hierarchyを使う模様。デンドログラムも一発で書いてくれます。
#!/usr/bin/env python import codecs import re import copy import numpy as np import scipy from matplotlib.pyplot import show from scipy.cluster.hierarchy import ward, dendrogram def getallvec(): #全ベクトル読み込み namelist = [] npxlist = [] fin = codecs.open('96.txt', 'r', 'utf_8') for line in fin: #読み込み string = re.split(" ",line[:-1]) a = [float(x) for x in string[1:301] ] namelist.append(string[0]) npxlist.append(copy.deepcopy(np.array(a))) npxarray = np.array(npxlist) return namelist,npxarray if __name__ == "__main__": namelist,npxarray = getallvec() #Ward法で階層クラスタリング result_w = scipy.cluster.hierarchy.ward(npxarray) #描画 dendrogram(result_w) show()
結果
99. t-SNEによる可視化
96の単語ベクトルに対して,ベクトル空間をt-SNEで可視化せよ.
t-SNEはscikit-learnにあります(sklearn.manifold.TSNE)。
#!/usr/bin/env python import codecs import re import copy import numpy as np from sklearn.manifold import TSNE from matplotlib import pyplot as plt def getallvec(): #全ベクトル読み込み namelist = [] npxlist = [] fin = codecs.open('96.txt', 'r', 'utf_8') for line in fin: #読み込み string = re.split(" ",line[:-1]) a = [float(x) for x in string[1:301] ] namelist.append(string[0]) npxlist.append(copy.deepcopy(np.array(a))) npxarray = np.array(npxlist) return namelist,npxarray if __name__ == "__main__": namelist,npxarray = getallvec() #t-SNE model = TSNE(n_components=2) tsne_result = model.fit_transform(npxarray) #表示 plt.plot(tsne_result[:,0], tsne_result[:,1], ".") plt.show()