当前位置:   article > 正文

【初学者入门】零基础入门NLP - 新闻文本分类

【初学者入门】零基础入门NLP - 新闻文本分类

序言

从今天开始入门学习NLP,虽然有点晚,但是我觉得任何时候都值得开始,尤其是面对你去感兴趣的事情。今天的任务是 【零基础入门NLP - 新闻文本分类】,这是天池大赛中的入门级算法比赛,入口链接请自取【在这里】。目前正式赛已经结束了,不过赛道同时也开放了长期赛,正好适合我这样的新手练习和学习。

1. 理解题意

  • 简单总结一下。赛题中的文本数据来源于新闻文本,但是所有文本内容已经按照字符集进行匿名处理。总共有14个待分类的类别,包括:科技,股票,体育,娱乐,时政等。所提供的训练数据的数据量是20w,测试数据的数据量是5w。接下来我们利用pandas读取并先初步了解数据的整体情况。
  • 评估指标:类别f1_score的均值
  • 数据
# 1. 读取 查看数据
train_data = pd.read_csv("dataset/train_set.csv", sep='\t')
print(train_data.head(5))
"""
                                         label\ttext
0  2\t2967 6758 339 2021 1854 3731 4109 3792 4149...
1  11\t4464 486 6352 5619 2465 4802 1452 3137 577...
2  3\t7346 4068 5074 3747 5681 6093 1777 2226 735...
3  2\t7159 948 4866 2109 5520 2490 211 3956 5520 ...
4  3\t3646 3055 3055 2490 4659 6065 3370 5814 246...

print(train_data.describe())
"""
"""
               label
count  200000.000000
mean        3.210950
std         3.084955
min         0.000000
25%         1.000000
50%         2.000000
75%         5.000000
max        13.000000
"""
# 其中25%说的是排序之后排在25%位置的数 训练的样本树是20万

# 2. 长度分布情况
#新闻文本句子长度分布情况
train_data['text_len'] = train_data['text'].apply(lambda x : len(x.split(' ')))
print(train_data['text_len'].describe())

"""
count    200000.000000
mean        907.207110
std         996.029036
min           2.000000
25%         374.000000 
50%         676.000000
75%        1131.000000
max       57921.000000
Name: text_len, dtype: float64
"""
# 平均值是907,新闻的长度比较长。最短的是2个。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
# 查看文本长度直方图,看看句子的长度的分布情况

#绘制句子长度的直方图
import matplotlib.pyplot as plt

plt.hist(train_data['text_len'],bins=100)
plt.xlabel('Length')
plt.ylabel('Numbers')
plt.title('Histogram of xinwen length')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

# 查看文本长度直方图,看看句子的长度的分布情况

#绘制句子长度的直方图
train_data['label'].value_counts().plot(kind='bar')
plt.title('Histogram of category')
plt.xlabel("category")
plt.ylabel("Numbers")
plt.show()

"""
{'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}
类别的分布也不是平衡的,甚至可以说差距还是蛮大的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

2. 解决思路

思路一:词频权重 岭回归分类器

def count_rl():
    """
    tfidf + 岭回归分类器
    :return:
    """
    df = pd.read_csv('dataset/train_set.csv', sep='\t')
    CountVec = CountVectorizer(max_features=4000)
    train_text = CountVec.fit_transform(df.text)
    # 这里的train_text实际上保存了一个词频数量的矩阵。
    # print(train_text.toarray())
    words = CountVec.get_feature_names_out()
    print("个数:{} 单词:{}".format(len(words), words))
    # 我们直接获得结果,因此尽可能使用较多的训练数据
    x_train, x_val, y_train, y_val = train_test_split(train_text, df.label, test_size=0.25, random_state=0)

    clf = RidgeClassifier()
    clf.fit(x_train, y_train)

    val_pre = clf.predict(x_val)
    score_f1 = f1_score(y_val, val_pre, average='macro')

    print('CountVectorizer + RidgeClassifier : %.4f' % score_f1)
    # CountVectorizer + RidgeClassifier : 0.8198

    # 预测结果
    test_df = pd.read_csv('dataset/test_a.csv')
    test_count = CountVec.transform(test_df.text)
    test_pre = clf.predict(test_count)
    write_the_result(test_pre, "results/test_result_cv_rl.csv")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
'
运行

测试集上的结果可达0.8165

思路二:词频权重 岭回归分类器

def tfidf_rl():
    """
    tfidf + 岭回归分类器
    :return:
    """
    # 获取训练数据
    df = pd.read_csv('dataset/train_set.csv', sep='\t')

    Tfidf = TfidfVectorizer(max_features=4000)
    train_tfidf = Tfidf.fit_transform(df.text)
    # 这里的train_text实际上保存了一个词频数量的矩阵。
    # print(train_text.toarray())
    x_train, x_val, y_train, y_val = train_test_split(train_tfidf, df.label, test_size=0.25, random_state=0)

    clf = RidgeClassifier()
    clf.fit(x_train, y_train)

    val_pre = clf.predict(x_val)
    score_f1 = f1_score(y_val, val_pre, average='macro')

    print('Tfidf + RidgeClassifier : %.4f' % score_f1)
    # Tfidf + RidgeClassifier : 0.8826

    # 预测结果
    test_df = pd.read_csv('dataset/test_a.csv')
    test_tfidf = Tfidf.transform(test_df.text)
    test_pre = clf.predict(test_tfidf)
    write_the_result(test_pre, "results/test_result_tfidf_rl.csv")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
'
运行

测试集上的结果可达0.8835

3. 完整代码

点击自取,一起学习。【在这里

随后如果有更多的解题思路,我也会持续更新。最后再引用一句蔡元培先生的话作为文章的结尾吧。

“今日所与诸君陈说者只此,以后会晤日长,随时再为商榷可也。”
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/810082
推荐阅读
相关标签
  

闽ICP备14008679号