@Perfect-Demo
2018-12-18T06:36:32.000000Z
字数 5483
阅读 1437
机器学习深度学习
包括下面几项内容:
由于从搜狗实验室下载的语料,属于原始数据,还包含各种HTML标签,所以需要进行处理,用下面的shell语句就可以解决:
(另外文件名字是news_tensite_xml.dat)
cat news_tensite_xml.dat | iconv -f gbk -t utf-8 -c | grep "<content>" > corpus.txt
保存为corpus.txt
(但是这里面内容仍然包含了一个标签,之后可以通过re库来去除)
需要引入jieba库
并且需要re库来去除"标签"
下面这一段代码将文本进行分词并且保存
import jieba
import re
def reTest(content):
reContent = re.sub('<content>|</content>', '', content)
return reContent
space = " "
i = 0
content_S = []
finput = open("corpus.txt")
foutput = open("corpus_seg.txt", 'w')
for line in finput:
line_seg = jieba.lcut(reTest(line))
foutput.write(space.join(line_seg))
content_S.append(line_seg)
i = i + 1
if (i % 10000 == 0):
print("Saved " + str(i) + " articles_seg")
finput.close()
foutput.close()
print("Finished Saved " + str(i) + " articles")
我们发下分词之后还有很多的标点符号出现了很多次,这样会影响我们之后用TF-IDF进行关键词提取.所以我们需要将这些(停用词)进行去除
对于停词表,可以直接在百度里搜索,然后建立一个txt文件储存即可
我的停词表名字叫 "stopwords.txt"
下面可以先读入它然后显示出来看看
#停词表
stopwords = pd.read_csv("stopwords.txt", index_col=False, sep = "\n", quoting=3,names=['stopword'], encoding='utf-8')
stopwords.head(50)
下面的代码是去除停用词
#去掉停用词
def drop_stopwords(contents, stopwords):
contents_clean = []
all_words = []
for line in contents:
line_clean = []
for word in line:
if word in stopwords:
continue
line_clean.append(word)
all_words.append(str(word))
contents_clean.append(line_clean)
return contents_clean, all_words
contents = df_content.content_s.values.tolist()
stopwords = stopwords.stopword.values.tolist()
contents_clean, all_words = drop_stopwords(contents, stopwords)
df_content = pd.DataFrame({'contents_clean':contents_clean})
df_content.head()
通过上面的代码,我们已经去除了停用词,然后我们现在可以将所有词的出现频率做一个排序,然后通过词云显示出来(我们需要用到wordcloud库)
首先我们将字符出现的频率进行排序,然后保存在一个DataFrame里
import numpy as np
#统计字符出现的次数
words_count=df_all_words.groupby(by=['all_words'])['all_words'].agg({"count":np.size})
#进行排序,将出现次数多的排在前面
words_count=words_count.reset_index().sort_values(by=["count"],ascending=False)
words_count.head()
注意:这里中文字符的显示需要我们另外设置字体,我们可以直接用电脑中的字体
# 制作词云
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['figure.figsize'] = (10.0, 5.0)
# wordcloud=WordCloud(font_path="/usr/share/fonts/opentype/noto/NotoSansCJK-Medium.ttc",background_color="white",max_font_size=80)
wordcloud = WordCloud(
# 设置背景颜色
background_color="white",
# 设置最大显示的词云数
max_words=100,
# 这种字体都在电脑字体中,一般路径
font_path="/usr/share/fonts/opentype/noto/NotoSansCJK-Medium.ttc",
# height= 600,
# width= 800,
# 设置字体最大值
max_font_size=80,
# 设置有多少种随机生成状态,即有多少种配色方案
random_state=50,
)
word_frequence = {x[0]:x[1] for x in words_count.head(100).values}
wordcloud=wordcloud.fit_words(word_frequence)
plt.imshow(wordcloud)
wordcloud.to_file('py_book.png') # 把词云保存下
我们这里要用到一个公式如下:
然后对于与我们可以分别由如下公式得到:
对于实现我们可以用jieba.analyse进行统计输出,代码如下:
import jieba.analyse
index= 112
news = []
finput = open("corpus.txt")
for line in finput:
news.append(reTest(line))
finput.close()
df_news = pd.DataFrame({'content':news})
print(df_news['content'][index])
content_S_str = "".join(content_S[index])
#提取前五个作为关键词
print(" ".join(jieba.analyse.extract_tags(content_S_str, topK=5, withWeight=False)))
然后我们可以得到五个词,可以看出来,这五个词差不多可以作为新闻摘要了
用了word2vec库然后将之前获得的分词文件放入得到结果后保存该模型即可.代码如下:
import word2vec as wv
wv.word2vec("corpus_seg.txt", "word2vec_segm.bin", size = 300, verbose=True)
然后我得到了如下结果:
Starting training using file corpus_seg.txt
Vocab size: 190705
Words in train file: 67084609
Alpha: 0.000012 Progress: 99.96% Words/thread/sec: 140.97k
每次使用时可以将模型导入然后使用
model = wv.load("word2vec_segm.bin")
然后我们就可以通过model变量来调用这个模型了
比如我们可以输出一下整个model的词向量(我这个算是比较巨大)
print(model.vectors)
我们也可以输出指定词的词向量
print(model["美食"])
这样会输出一个300的词向量(因为我们之前做word2vec的时候用的维度是300)
我们可以将指定位置的词输出
index= 100000
print(model.vocab[index])
之后我们还可以看看指定词的有联系的词,用下面的语句:
indexs = model.cosine("美食")
for index in indexs[0]:
print(model.vocab[index])
首先我们用sklearn库中的PCA模型进行降维
然后用matplotlib进行绘图显示
先导入库
import matplotlib
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
然后用一个变量先提取model中的词向量,再进行PCA降维
raw_word2vec = model.vectors
X_reduced = PCA(n_components=2).fit_transform(raw_word2vec)
这样X_reduced就变成了一个降维的词向量集合了,对于每个词,只有两个坐标(x和y)
然后我们提取几个词的联系紧密的词记录他们的index,然后显示在坐标轴上
(注意,这里因为要显示中文字,所以需要加入字体文件,加入字体和之前的词云那是一样的)
下面是降维后进行可视化的过程
#下面来展示几个降维后的例子
#首先是添加下面这几个(中心)词的联系紧密的词
index1, metrics1 = model.cosine("中国")
index2, metrics2 = model.cosine("北京")
index3, metrics3 = model.cosine("国家")
index4, metrics4 = model.cosine("美食")
#然后添加上面这几个(中心)词
index01 = np.where(model.vocab == "中国")
index02 = np.where(model.vocab == "北京")
index03 = np.where(model.vocab == "国家")
index04 = np.where(model.vocab == "美食")
index1 = np.append(index1, index01)
index2 = np.append(index2, index02)
index3 = np.append(index3, index03)
index4 = np.append(index4, index04)
#下面开始绘图
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
#注意中文显示需要做特殊处理,就像词云图里一样要选择字体
Cfont = matplotlib.font_manager.FontProperties(fname="/usr/share/fonts/opentype/noto/NotoSansCJK-Medium.ttc")
for i in index1:
ax.text(X_reduced[i][0], X_reduced[i][1], model.vocab[i], fontproperties = Cfont, color = 'r')
# print(model.vocab[i])
for i in index2:
ax.text(X_reduced[i][0], X_reduced[i][1], model.vocab[i], fontproperties = Cfont, color = 'b')
# print(model.vocab[i])
for i in index3:
ax.text(X_reduced[i][0], X_reduced[i][1], model.vocab[i], fontproperties = Cfont, color = 'g')
# print(model.vocab[i])
for i in index4:
ax.text(X_reduced[i][0], X_reduced[i][1], model.vocab[i], fontproperties = Cfont, color = 'y')
ax.axis([0, 0.8, -0.5, 0.5])
plt.show()
效果如下: