0.数据集以及运行环境
数据集的地址:情绪分析的数据集,能稍微看懂英文就应该知道如何下载了
运行环境:Windows10,IDE:pycharm或者是Linux
0.数据预处理
"0","1467810369","Mon Apr 06 22:19:45 PDT 2009","NO_QUERY","_TheSpecialOne_","@switchfoot http://twitpic.com/2y1zl - Awww, that's a bummer. You shoulda got David Carr of Third Day to do it. ;D"
上图是原始数据的情况,总共有6个字段,主要是第一个字段(情感评价的结果)以及最后一个字段(tweet内容)是有用的。针对csv文件,我们使用pandas进行读取然后进行处理。处理的代码如下:
# 提取文件中的有用的字段
def userfull_filed(org_file, outuput_file):
data = pd.read_csv(os.path.join(data_dir, org_file), header=None, encoding='latin-1')
clf = data.values[:, 0]
content = data.values[:, -1]
new_clf = []
for temp in clf:
# 这个处理就是将情感评论结果进行所谓的one_hot编码
if temp == 0:
new_clf.append([1, 0]) # 消极评论
# elif temp == 2:
# new_clf.append([0, 1, 0]) # 中性评论
else:
new_clf.append([0, 1]) # 积极评论
df = pd.DataFrame(np.c_[new_clf, content], columns=['emotion0', 'emotion1', 'content'])
df.to_csv(os.path.join(data_dir, outuput_file), index=False)
这样处理的原因是,将情感评论值变成一个one-hot编码形式,这样我们进行nn或者是cnn处理的最后一层的输出单元为2(但有个巨大的bug那就是实际上训练集没有中性评论)
接下来利用nltk(这个简直是英语文本的自然语言的神奇呀)来生成单词集合,代码如下:
def sentence_english_manage(line):
# 英文句子的预处理
pattern = re.compile(r"[!#$%&'()*+,-./:;<=>?@[\]^_`{|}~0123456789]")
line = re.sub(pattern, '', line)
# line = [word for word in line.split() if word not in stopwords]
return line
def create_lexicon(train_file):
lemmatizer = WordNetLemmatizer()
df = pd.read_csv(os.path.join(data_dir, train_file))
count_word = {} # 统计单词的数量
all_word = []
for content in df.values[:, 2]:
words = word_tokenize(sentence_english_manage(content.lower())) # word_tokenize就是一个分词处理的过程
for word in words:
word = lemmatizer.lemmatize(word) # 提取该单词的原型
all_word.append(word) # 存储所有的单词
count_word = Counter(all_word)
# count_word = OrderetodDict(sorted(count_word.items(), key=lambda t: t[1]))
lex = []
for word in count_word.keys():
if count_word[word] < 100000 and count_word[word] > 100: # 过滤掉一些单词
lex.append(word)
with open('lexcion.pkl', 'wb') as file_write:
pickle.dump(lex, file_write)
return lex, count_word
最后生成一个只含有有用信息的文本内容
1.利用NN进行文本情感分类
1.1神经网络结构的搭建
在这里我设计了两层的隐藏层,单元数分别为1500/1500。神经网络的整个结构代码如下:
with open('lexcion.pkl', 'rb') as file_read:
lex = pickle.load(file_read)
n_input_layer = len(lex) # 输入层的长度
n_layer_1 = 1500 # 有两个隐藏层
n_layer_2 = 1500
n_output_layer = 2 # 输出层的大小
X = tf.placeholder(shape=(None, len(lex)), dtype=tf.float32, name="X")
Y = tf.placeholder(shape=(None, 2), dtype=tf.float32, name="Y")
batch_size = 500
dropout_keep_prob = tf.placeholder(tf.float32)
def neural_network(data):
layer_1_w_b = {
'w_': tf.Variable(tf.random_normal([n_input_layer, n_layer_1])),
'b_': tf.Variable(tf.random_normal([n_layer_1]))
}
layer_2_w_b = {
'w_': tf.Variable(tf.random_normal([n_layer_1, n_layer_2])),
'b_': tf.Variable(tf.random_normal([n_layer_2]))
}
layer_output_w_b = {
'w_': tf.Variable(tf.random_normal([n_layer_2, n_output_layer])),
'b_': tf.Variable(tf.random_normal([n_output_layer]))
}
# wx+b
# 这里有点需要注意那就是最后输出层不需要加激活函数
# 同时加入