二、从单词到段落
2、Attemp2:Clustering 聚类
(1)Word2Vec可以创建语义相关单词的集群。首先需要找到单词簇的中心,可以通过使用聚类算法(如K-Means)来完成。
在K-Means中,需要设置一个参数K,即集群的数目。实验表明,小集群(平均只有5个字的)比有很多单词的大集群效果更好。我们用scikit-learn来执行K-means。
设置一个timer,来看看k-means会用多长时间。
from sklearn.clusterimport kMeans
import time
from test2 import model
#开始时间
start= time.time()
#设置K值num_clusters为词汇数量的1/5,或者每个集群平均5个词
word_vectors= model.wv.syn0
num_clusters= word_vectors.shape[0]/5
#初始化一个k-means对象,用它提取图心
kmeans_clustering= KMeans(n_clusters = num_clusters)
idx= kmeans_clustering.fit_predict(word_vectors)
#获取结束时间,并打印用了多长时间
end= time.time()
elapsed= end- start
print("Time taken for K-Means clustering: ", elapsed,"seconds")
(2)model.wv.index2word中为经过最小次数筛选之后的所有单词的名称,将其转为字典dict,即其他语言中的map。每个单词对应一个cluster数字。
word_centroid_map= dict(zip(model.wv.index2word, idx))
dict的前一项是key,后一项是value
看一下cluster中包含了什么。因为Word2Vec依赖于随机数种子,所以每个 程序的cluster可能不同。
#打印0-9簇中的单词
for cluster in range(0,10):
print("\nCluster %d" % cluster)
words= []
for i in range(0,len(word_centroid_map.values())):
if(word_centroid_map.values()[i]== cluster):
words.append(word_centroid_map.keys()[i])
print(words)
循环的意思是:如果word_centroid_map的某一项的value值等于cluster,即,这个单词属于第i=cluster个簇,那么就把这个单词(就是key_i)加到word列表中。
集群的质量各不相同。
(3)不管怎样,现在为每个单词分配了一个簇(质心),我们可以定义一个函数来把评论转换为质心袋,就像词袋那样,但是使用的是语义相关的集群,而不是单个单词。
簇的数量等于单词/质心映射中的最高簇索引。
def create_bag_of_centroids(wordlist,word_centroid_map):
#簇的数目等于质心map中最大的cluster索引值
num_centroids= max(word_centroid_map.values())+1
#预先分配一个质心向量词袋
bag_of_centroids= np.zeros(num_centroids,dtype="float32")
#遍历评论中的单词,如果单词在词表中,并发现属于某个cluster,就把那个couster计数+1
for word in wordlist:
if word in word_centroid_map:
index= word_centroid_map[word]
bag_of_centroids[index]+= 1
return bag_of_centroids
这个函数给每个评论一个数组,每个数组都有一些数量跟集群数相等的特征。
(4)为训练集和测试集创建质心袋,然后训练随机森林并提取结果:
#预先为训练集的质心袋分配一个数组
train_centroids= np.zeros((train["review"].size, num_clusters),dtype="float32")
counter= 0
for review in clean_train_reviews:
train_centroids[counter]= create_bag_of_centroids(review,word_centroid_map)
counter+= 1
test_centroids= np.zeros((test["review"].size, num_clusters),dtype="float32")
counter= 0
for review in clean_test_reviews:
test_centroids[counter]= create_bag_of_centroids(review, word_centroid_map)
counter+= 1
#训练随机森林,并提取预测
forest= RandomForestClassifier(n_estimators=100)
print("Fitting a random forest to labeled training data...")
forest= forest.fit(train_centroids,train["sentiment"])
result= forest.predict(test_centroids)
#将测试集的预测结果写入文件
output= pd.DataFrame(data={"id":test["id"],"sentiment":result})
output.to_csv("C:\\data\\BagofCentroids.csv",index=False,quoting=3)
会发现结果跟3-1
网友评论