Data Analysis
先来观察下数据,训练集和测试集分别存储在当前目录下的train.csv和20190520_test.csv中
train_data = pd.read_csv('train.csv', lineterminator='\n') # 行分隔符 = '\n'
test_data = pd.read_csv('20190520_test.csv', lineterminator='\n')
train_data['label'] = train_data['label'].map({'Negative':0, 'Positive':1})
train_data.head()
Data Processing
数据处理差不多花了我1整天的时间,主要还是我太菜,对python的很多用法不太熟
首先我把label
标签离散为0-1
,Negative
为0
,Positive
为1
然后将遍历每一行,对review
这一列的文本进行清洗,很明显的看到,文本里面有各种垃圾信息,比方说有emoji表情,还有各种标点符号、数字等等。过滤掉这些符号以后,再将一行文本全部转换成小写,之后按照空格进行分隔,然后再用一个空格隔开进行拼接,这样做的目的是因为,一行文本里面两个词之间可能不止用一个空格隔开,所以我干脆人为用一个空格隔开,还有一些乱七八糟符号的干扰大家可以用自己的办法过滤
train_data['label'] = train_data['label'].map({'Negative':0, 'Positive':1})
rmSignal = ['.', '?', '!', ':', '-', '+', '/', '"', ',']
def review_to_words(data):
# 正则去除表情
emoji_pattern = re.compile(u'[\U00010000-\U0010ffff]')
data = emoji_pattern.sub(u'', data)
# 正则去除标点
fuhao_pattern = re.compile(u'\.*')
data = fuhao_pattern.sub(u'', data)
# 正则去除数字
digit_pattern = re.compile(u'\d+')
data = digit_pattern.sub(u'', data)
# 空格拆分词语
words = data.lower().split()
# 去掉rmSignal
meaningful_words = [w for w in words if not w in rmSignal]
# 将筛分好的词合成一个字符串,并用空格分开
words = " ".join(meaningful_words)
return words
clean_train_reviews = []
for i in range(0, len(train_data)):
clean_train_reviews.append(review_to_words(train_data['review'][i]))
clean_train_reviews[:5]
输出:
['jo bhi ap se tou behtar hoon',
'ya allah meri sister affia ki madad farma',
'yeh khud chahta a is umar main shadi krna had ogi',
'tc apky mun xe exe alfax achy nae lgty',
'good']
接着使用TF-IDF构建词袋,然后查看一下词频最高的十个词
tfv = TfidfVectorizer()
train_data_features = tfv.fit_transform(clean_train_reviews)
train_data_features = train_data_features.toarray()
cntWords = sorted(tfv.vocabulary_, key=lambda x:x[0])
cntWords[-10:]
输出:
['اے', 'بیٹھی', 'جیڑی', 'سی', 'ناں', 'کردی', 'کر', 'ھاں', '賭easar', '鄭h']
Model Selection
Bayes
在模型选择上,对于这种文本分类问题,贝叶斯是一个简单又好用的分类器,算法思想挺简单的,这里不再介绍原理
利用cross_val_score
对训练集进行交叉训练,这里我设定的是20折,大家可以试试别的参数,包括贝叶斯的参数我也用的默认的,也可以适当调参
model_NB = MNB()
model_NB.fit(train_data_features,train_data["label"])
score = np.mean(cross_val_score(model_NB,train_data_features, train_data["label"], cv=20, scoring='roc_auc'))
print("多项式贝叶斯分类器20折交叉验证得分: ",score) # 0.8614076771593228
Logistic Regression
同时我也顺便建立了一下Logistic Regression模型
model_LR = LR(random_state = 0)
model_LR.fit(train_data_features,train_data["label"])
score = np.mean(cross_val_score(model_LR,train_data_features, train_data["label"], cv=20, scoring='roc_auc'))
print("Logistic Regression20折交叉验证得分: ", score) # 0.844763864535499
Predict
从训练集的结果上来看,贝叶斯更优,因此我就用训练好的贝叶斯分类器对测试集进行预测
首先也要把测试集的数据进行清理,然后通过已经训练好的TF-IDF模型求出词频-逆文件频率矩阵,带入到贝叶斯分类器进行测试即可
clean_test_reviews = []
for i in range(0, len(test_data["review"])):
clean_test_reviews.append(review_to_words(test_data["review"][i]))
clean_test_reviews[:5]
test_data_features = tfv.transform(clean_test_reviews)
test_data_features = test_data_features.toarray()
result = model_NB.predict_proba(test_data_features)
#print(result[:,1])
output = pd.DataFrame(data={"ID":test_data["ID"], "Pred":result[:,1]})
output.to_csv("out_model.csv", index=False, quoting=3)
提交后Score为0.86241116
,咸鱼水平有限,大佬们勿喷
数据集和代码可以访问咸鱼的Github
为什么没用Text'CNN,应该效果会更好
不好意思,因为菜,NN什么的,我现在还不能熟练运用@(狂汗)
学长稳了?@(滑稽)