数据预处理
#encoding=utf-8
import pandas as pd
train_data=pd.read_csv('/ai_work/hotel_data/train.tsv',header=None,sep='\t').drop([0])
with open("/ai_work/train.txt",'w') as fi:
for file in train_data.values:
if file[1]=='1':
file[1]='积极'
elif file[1]=='0':
file[1]='消极'
new_file='__label__'+file[1]+'\t'+file[0]+'\n'
fi.write(new_file)
输出结果
分词
with open("/ai_work/stopwords.txt",'r',encoding='utf-8') as f_t:
stopwords=list(set(f_t.read().strip().split()))
f_writer=open("/ai_work/result_train.txt",'w',encoding='utf-8')
# jieba分词
with open('/ai_work/train.txt','r',encoding='utf-8') as ff:
while True:
file=ff.readline().strip()
if len(file)!=0:
files = file.split()
set_list=jieba.cut(files[1])
print()
word_list=[]
for word in set_list:
if word not in stopwords:
word_list.append(word)
linee=" ".join(word_list)
linee=files[0]+'\t'+linee+'\n'
f_writer.write(linee)
else:
break
输出符合fasttext的数据格式
模型训练
model = fasttext.train_supervised(input="result_train.txt")
Read 0M words
Number of words: 11278
Number of labels: 2
Progress: 100.0% words/sec/thread: 4501068 lr: 0.000000 avg.loss: 0.561774 ETA: 0h 0m 0s
模型预测
result=model.predict("环境不好")
print(result)
预测结果
(('__label__消极',), array([0.79927993]))
模型调优:
- 重新对数据集的处理
- 增加训练轮数:
model = fasttext.train_supervised(input="result_train.txt",epoch=100)
Number of words: 11278
Number of labels: 2
Progress: 100.0% words/sec/thread: 4915578 lr: 0.000000 avg.loss: 0.093837 ETA: 0h 0m 0s
预测结果
(('__label__消极',), array([1.00000989]))
- 调整学习率:
设置train_supervised方法中的参数lr来调整学习率, 默认的学习率大小是0.1
增大学习率意味着增大了梯度下降的步长使其在有限的迭代步骤下更接近最优点
model = fasttext.train_supervised(input="result_train.txt",lr=0.5,epoch=100)
Number of words: 11278
Number of labels: 2
Progress: 100.0% words/sec/thread: 4904629 lr: 0.000000 avg.loss: 0.083081 ETA: 0h 0m 0s
(('__label__消极',), array([1.00001001]))
- 增加n-gram特征:
设置train_supervised方法中的参数wordNgrams来添加n-gram特征, 默认是1, 也就是没有n-gram特征
我们这里将其设置为2意味着添加2-gram特征, 这些特征帮助模型捕捉前后词汇之间的关联, 更好的提取分类规则用于模型分类, 当然这也会增加模型训时练占用的资源和时间
model = fasttext.train_supervised(input="result_train.txt",lr=0.5,epoch=100,wordNgrams=2)
Read 0M words
Number of words: 11278
Number of labels: 2
Progress: 100.0% words/sec/thread: 2394375 lr: 0.000000 avg.loss: 0.054989 ETA: 0h 0m 0s
(('__label__消极',), array([0.99603701]))```
- 修改损失计算方式:
实际生产中多标签多分类问题的损失计算方式:
# 针对多标签多分类问题, 使用'softmax'或者'hs'有时并不是最佳选择, 因为我们最终得到的应该是多个标签, 而softmax却只能最大化一个标签.
# 所以我们往往会选择为每个标签使用独立的二分类器作为输出层结构,
# 对应的损失计算方式为'ova'表示one vs all.
# 这种输出层的改变意味着我们在统一语料下同时训练多个二分类模型,
# 对于二分类模型来讲, lr不宜过大, 这里我们设置为0.2
>>> model = fasttext.train_supervised(input="cooking.train", lr=0.2, epoch=25, wordNgrams=2, loss='ova')
Read 0M words
Number of words: 8952
Number of labels: 735
Progress: 100.0% words/sec/thread: 65044 lr: 0.000000 avg.loss: 7.713312 ETA: 0h 0m 0s
# 我们使用模型进行单条样本的预测, 来看一下它的输出结果.
# 参数k代表指定模型输出多少个标签, 默认为1, 这里设置为-1, 意味着尽可能多的输出.
# 参数threshold代表显示的标签概率阈值, 设置为0.5, 意味着显示概率大于0.5的标签
>>> model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.5)
# 我看到根据输入文本, 输出了它的三个最有可能的标签
((u'__label__baking', u'__label__bananas', u'__label__bread'), array([1.00000, 0.939923, 0.592677]))
自动超参数调优:
手动调节和寻找超参数是非常困难的, 因为参数之间可能相关, 并且不同数据集需要的超参数也不同,
# 因此可以使用fasttext的autotuneValidationFile参数进行自动超参数调优.
# autotuneValidationFile参数需要指定验证数据集所在路径, 它将在验证集上使用随机搜
索方法寻找可能最优的超参数.
# 使用autotuneDuration参数可以控制随机搜索的时间, 默认是300s, 根据不同的需求, 我
们可以延长或缩短时间.
第六步: 模型保存与重加载
保存
model.save_model('/ai_work/fasttext_model.bin')
加载
model2=fasttext.load_model('/ai_work/fasttext_model.bin')
使用保存的模型进行预测
model2=fasttext.load_model('/ai_work/fasttext_model.bin')
result=model2.predict("环境非常好")
print(result)