LoginSignup
1
0

More than 5 years have passed since last update.

素人の言語処理100本ノック:97

Last updated at Posted at 2017-04-29

言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。

第10章: ベクトル空間法 (II)

第10章では,前章に引き続き単語ベクトルの学習に取り組む.

97. k-meansクラスタリング

96の単語ベクトルに対して,k-meansクラスタリングをクラスタ数$ k=5 $として実行せよ.

出来上がったコード:

main.py
# coding: utf-8
import pickle
from collections import OrderedDict
from scipy import io
import numpy as np
from sklearn.cluster import KMeans

fname_dict_index_t = 'dict_index_country'
fname_matrix_x300 = 'matrix_x300_country'

# 辞書読み込み
with open(fname_dict_index_t, 'rb') as data_file:
        dict_index_t = pickle.load(data_file)

# 行列読み込み
matrix_x300 = io.loadmat(fname_matrix_x300)['matrix_x300']

# KMeansクラスタリング
predicts = KMeans(n_clusters=5).fit_predict(matrix_x300)

# (国,分類番号)のリスト作成
result = zip(dict_index_t.keys(), predicts)

# 分類番号でソートして表示
for country, category in sorted(result, key=lambda x: x[1]):
    print('{}\t{}'.format(category, country))

実行結果:

0〜4の分類番号と国名をタブ区切りで出力しています。

実行結果
0   Andorra
0   Antarctica
0   Antigua_and_Barbuda
0   Bahamas
0   Bahrain
0   Barbados
0   Belarus
0   Belize
0   Benin
0   Bermuda
0   Bhutan
0   Bosnia_and_Herzegovina
0   Botswana
0   Burkina_Faso
0   Burundi
0   Cameroon
0   Central_African_Republic
0   Chad
0   Commonwealth_of_Australia
0   Comoros
0   Congo
0   Cook_Islands
0   Democratic_Republic_of_the_Congo
0   Djibouti
0   Dominica
0   Dominican_Republic
0   Ecuador
0   Eritrea
0   Estonia
0   Federal_Republic_of_Germany
0   Federated_States_of_Micronesia
0   French_Republic
0   Gabon
0   Gambia
0   Gibraltar
0   Greenland
0   Grenada
0   Guadeloupe
0   Guam
0   Guatemala
0   Guinea-Bissau
0   Guyana
0   Haiti
0   Honduras
0   Jamaica
0   Jordan
0   Kazakhstan
0   Kingdom_of_the_Netherlands
0   Kiribati
0   Kuwait
0   Kyrgyzstan
0   Lao
0   Latvia
0   Lesotho
0   Liberia
0   Liechtenstein
0   Luxembourg
0   Macau
0   Madagascar
0   Malawi
0   Maldives
0   Mali
0   Martinique
0   Mauritania
0   Mauritius
0   Mayotte
0   Micronesia
0   Moldova
0   Monaco
0   Mongolia
0   Montenegro
0   Mozambique
0   Myanmar
0   Namibia
0   Nauru
0   Nicaragua
0   Niger
0   Niue
0   Oman
0   Palau
0   Paraguay
0   Qatar
0   Republic_of_Albania
0   Republic_of_Armenia
0   Republic_of_Austria
0   Republic_of_Congo
0   Republic_of_Croatia
0   Republic_of_Estonia
0   Republic_of_Korea
0   Republic_of_Poland
0   Republic_of_Singapore
0   Republic_of_South_Africa
0   Republic_of_Turkey
0   Republic_of_the_Philippines
0   Russian_Federation
0   Rwanda
0   Saint_Lucia
0   Senegal
0   Seychelles
0   Slovenia
0   Solomon_Islands
0   Somalia
0   State_of_Israel
0   Suriname
0   Swaziland
0   Tajikistan
0   Tibet
0   Timor-Leste
0   Togo
0   Tokelau
0   Tonga
0   Tunisia
0   Turkmenistan
0   Tuvalu
0   United_Arab_Emirates
0   United_States_of_America
0   Uzbekistan
0   Vanuatu
0   Vatican
0   Yemen
0   Zambia
0   Zimbabwe
1   Austria
1   Belgium
1   Bulgaria
1   Denmark
1   Egypt
1   France
1   Germany
1   Greece
1   Hungary
1   Ireland
1   Italy
1   Macedonia
1   Netherlands
1   Norway
1   Poland
1   Portugal
1   Romania
1   Spain
1   Sweden
2   Afghanistan
2   China
2   India
2   Iraq
2   Israel
2   Korea
2   Pakistan
2   Taiwan
2   United_States
2   Vietnam
3   Argentina
3   Australia
3   Brazil
3   Canada
3   Japan
3   Mexico
3   New_Zealand
3   Switzerland
4   Albania
4   Algeria
4   Angola
4   Armenia
4   Azerbaijan
4   Bangladesh
4   Bolivia
4   Cambodia
4   Chile
4   Colombia
4   Croatia
4   Cuba
4   Cyprus
4   Czech_Republic
4   Ethiopia
4   Fiji
4   Finland
4   Georgia
4   Ghana
4   Guinea
4   Iceland
4   Indonesia
4   Iran
4   Kenya
4   Kosovo
4   Lebanon
4   Libya
4   Lithuania
4   Malaysia
4   Malta
4   Morocco
4   Nepal
4   Nigeria
4   Panama
4   People's_Republic_of_China
4   Peru
4   Philippines
4   Samoa
4   Serbia
4   Singapore
4   Slovakia
4   Sudan
4   Syria
4   Tanzania
4   Thailand
4   Turkey
4   Uganda
4   Ukraine
4   Uruguay
4   Venezuela

データを分類する手法

データの分類には、大きくクラシフィケーション(classification、クラス分類)とクラスタリング(clustering)という2つの手法があります。

クラシフィケーション(classification、クラス分類)

クラシフィケーションは、事前にグループ(class)を定義しておく方法で、例えばニュースを「政治」、「経済」、「スポーツ」などの事前定義のグループに振り分ける時に使います。クラス分類とも呼ばれます。

クラスタリング(clustering)

クラスタリングは、事前のグループの定義はせず、似た者同士の塊(cluster、クラスター)を抽出する手法です。大量のデータを分析する時に、1つ1つは見ていられないのでざっくり似たような塊にまとめさせて、その塊ごとに性質や傾向を見てみよう、みたいな使い方をします。
今回の問題は5つに分けろというだけで、どのようなグループに?という定義はありません。そのためクラスタリングを使います。

クラスタリングの手法は、今回使うK-Meansのような非階層的クラスタリングと、次の問題98で使うWard法のような階層的クラスタリングに分かれます。

K-Meansクラスタリング

K-Meansの基本アルゴリズムは単純です。

まず最初に指定された数のクラスターの中心をベクトル空間上に適当に選びます。そして、各データに対して各クラスターの中心までの距離を調べ、中心が一番近いクラスターに振り分けます。これで1回目の振り分けが完了です。
振り分け終わったら、今度はクラスターごとに所属するデータの平均点を調べて、そのクラスターの新たな中心点とします。
ここでデータの振り分けを一度リセットし、再び各データに対して、各クラスターの新しい中心までの距離を調べ、中心が一番近いクラスターに振り分け直します。これで2回目の振り分けが完了です。
これを中心がほとんど移動しなくなるまで繰り返せば完了です。

K-Meansの解説はググるとたくさん出てきますので、詳細は割愛します。CourseraのMachine LearningではWeek8で学べます。

K-Meansの実装

K-Meansによるクラスタリングは、問題85で使い始めたscikit-learnを使うと簡単です。
sklearn.cluster.KMeansクラスでクラスターの数を指定し、fit_predict()で行列を渡せばクラスタリングが実行されて、各行に対する分類番号の配列(値の範囲は0からクラスター数-1)を取得できます。

なお、最初に選ばれるクラスターの中心点はランダムです。そのため、実行の度に微妙に結果が変わることがあります。変えたくない場合は、sklearn.cluster.KMeansrandom_stateを指定することで乱数のシード値を指定できます。

今回のプログラムでは、分類番号でソートして表示してみました。ただ、結果を見ても、どんな切り口で分類されたのかイマイチ分かりません。なんとなく分類番号1はヨーロッパの国が集まっているようですが「Republic_of_Austria」などの正式名では分類番号0になってしまっています。「United_States_of_America」と「United_States」も別の分類ですね。問題96の国の抽出がイマイチだったかも...

 
98本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。


実行結果には、100本ノックで用いるコーパス・データで配布されているデータの一部が含まれます。この第10章で用いているコーパス・データのライセンスはクリエイティブ・コモンズ 表示-継承 3.0 非移植日本語訳)です。また、国名の一覧は、「KIDS外務省 - 世界の国々」(外務省)(http://www.mofa.go.jp/mofaj/kids/ichiran/index.html)と、nationsonline.orgCountries and Regions of the World from A to Zを加工して作成しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0