MENU

科赛——【文本情感分类模型搭建 | 预选赛】(Score:0.8624)

May 25, 2019 • Read: 8770 • 数据挖掘与机器学习阅读设置

预选赛题——文本情感分类模型

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-1Negative0Positive1

然后将遍历每一行,对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

Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment

3 Comments
  1. 青青草 青青草

    为什么没用Text'CNN,应该效果会更好

    1. mathor mathor

      @青青草不好意思,因为菜,NN什么的,我现在还不能熟练运用@(狂汗)

  2. ash-bin ash-bin

    学长稳了?@(滑稽)