精华内容
下载资源
问答
  • 其中包含10个类别:automobile、culture、dressing、entertainment、finance、life、medical、military、social、sports,每类包含十万篇文本左右,对训练集和测试集以 3:7 的比例划分进行文本分类。 文本格式如下所...
  • GitHub项目链接地址:text-classification-cnn-rnn 分别使用采用CNN、RNN两种网络实现 ...该项目中CNN表现的效果更加好一点,这种基本不是原意的字符级别的特征,也能从统计意义上表征文本从而作为特征 ...

    大佬的GitHub项目链接地址:text-classification-cnn-rnn

    分别使用采用CNN、RNN两种网络实现

    该项目中CNN表现的效果更加好一点,这种基本不是原意的字符级别的特征,也能从统计意义上表征文本从而作为特征

    展开全文
  • 本文主要是针对入门级别的Bert使用,包括英文文本分类和中文文本分类。这部分主要使用Bert进行情感分析,属于中文文本分类,同样使用BertForSequenceClassification数据集中包括三个情感分类等级[-1,0,...

    想了解更多好玩的人工智能应用,请关注公众号“机器AI学习 数据AI挖掘”,”智能应用"菜单中包括:颜值检测、植物花卉识别、文字识别、人脸美妆等有趣的智能应用。。

    521c65471a6388869a69e7dabaec860c.png

    本文主要是针对入门级别的Bert使用,包括英文文本分类和中文文本分类。
    这部分主要使用Bert进行情感分析,属于中文文本分类,同样使用BertForSequenceClassification
    数据集中包括三个情感分类等级[-1,0,1]1ad82948cf731ed0247b12041568e663.png
    流程和第一部分一致,主要修改地方是在Bert的config文件中将类别设置成3,并将数据集中的[-1,0,1],变化成[0,1,2]的形式,bert的预训练模型使用
    bert-base-uncased-cn

    这个数据集包括俩列:[‘label’, ‘txt’]
    首先读入数据:

    df = pd.read_csv(os.path.join(data_path,"train.tsv"), delimiter='\t')
    df_dev=pd.read_csv(os.path.join(data_path,"dev.tsv"), delimiter='\t')
    print("train:",df.head())
    print("dev:",df_dev.head())
    • 1

    • 2

    • 3

    • 4

    15fe28e64c2b582581656722de2f3564.png
    提取句子并进行处理

    #提取语句并处理
    sentencses=['[CLS] ' + sent + ' [SEP]' for sent in df.txt.values]
    labels=df.label.values
    #这里中性还是使用0表示1表示积极2表示不积极
    labels=list(map(lambda x:0 if x == 0 else 1 if x == 1 else 2,[x for x in labels]))
    print("train label:",labels[100:110])
    print("第一句话:",sentencses[0])
    tokenizer=BertTokenizer.from_pretrained(bert_pre_tokenizer,do_lower_case=True)
    tokenized_sents=[tokenizer.tokenize(sent) for sent in sentencses]
    print("tokenized的第一句话:",tokenized_sents[0])
    • 1

    • 2

    • 3

    • 4

    • 5

    • 6

    • 7

    • 8

    • 9

    • 10

    定义Bert的输入格式

    1. 处理后的句子

    2. 同样这里还是一句话[0,0,0,0,…]默认即可不需要传入

    3. mask

    MAX_LEN=80
    #训练集部分
    #将分割后的句子转化成数字 word-->idx
    input_ids=[tokenizer.convert_tokens_to_ids(sent) for sent in tokenized_sents]
    print("转化后的第一个句子:",input_ids[0])
    #做PADDING
    #大于128做截断,小于128做PADDING
    input_ids=pad_sequences(input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
    print("Padding 第一个句子:",input_ids[0])
    #建立mask
    attention_masks = []
    for seq in input_ids:
    seq_mask = [float(i>0) for i in seq]
    attention_masks.append(seq_mask)
    print("第一个attention mask:",attention_masks[0])

    #验证集部分
    #构建验证集
    dev_sentencses=['[CLS] ' + sent + ' [SEP]' for sent in df_dev.txt.values]
    dev_labels=df_dev.label.values
    print("dev_label:",dev_labels[100:110])
    dev_labels=list(map(lambda x:0 if x == 0 else 1 if x == 1 else 2,[x for x in dev_labels]))
    # dev_labels=[to_categorical(i, num_classes=3) for i in dev_labels]
    dev_tokenized_sents=[tokenizer.tokenize(sent) for sent in dev_sentencses]
    dev_input_ids=[tokenizer.convert_tokens_to_ids(sent) for sent in dev_tokenized_sents]
    dev_input_ids=pad_sequences(dev_input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
    dev_attention_masks = []
    for seq in dev_input_ids:
    dev_seq_mask = [float(i>0) for i in seq]
    dev_attention_masks.append(dev_seq_mask)
    • 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

    构建训练集和验证集的dataloader

    train_inputs = torch.tensor(input_ids)
    validation_inputs = torch.tensor(dev_input_ids)
    train_labels = torch.tensor(labels)
    validation_labels = torch.tensor(dev_labels)
    train_masks = torch.tensor(attention_masks)
    validation_masks = torch.tensor(dev_attention_masks)

    batch_size = 32
    train_data = TensorDataset(train_inputs, train_masks, train_labels)
    train_sampler = RandomSampler(train_data)
    train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=batch_size)
    validation_data = TensorDataset(validation_inputs, validation_masks, validation_labels)
    validation_sampler = SequentialSampler(validation_data)
    validation_dataloader = DataLoader(validation_data, sampler=validation_sampler, batch_size=batch_size)
    • 1

    • 2

    • 3

    • 4

    • 5

    • 6

    • 7

    • 8

    • 9

    • 10

    • 11

    • 12

    • 13

    • 14

    装载预训练模型,这里是bert的中文模型

    #装载预训练bert模型
    modelConfig = BertConfig.from_pretrained(bert_config)
    model = BertForSequenceClassification.from_pretrained(bert_pre_model, config=modelConfig)
    print(model.cuda())
    • 1

    • 2

    • 3

    • 4

    定义优化器

    param_optimizer = list(model.named_parameters())
    no_decay = ['bias', 'gamma', 'beta']
    optimizer_grouped_parameters = [
    {'params': [p for n, p in param_optimizer if not any(nd in n for nd in no_decay)],
    'weight_decay_rate': 0.01},
    {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)],
    'weight_decay_rate': 0.0}
    ]

    optimizer = BertAdam(optimizer_grouped_parameters,
    lr=2e-5,
    warmup=.1)
    • 1

    • 2

    • 3

    • 4

    • 5

    • 6

    • 7

    • 8

    • 9

    • 10

    • 11

    • 12

    训练部分

    def flat_accuracy(preds, labels):
    pred_flat = np.argmax(preds, axis=1).flatten()
    labels_flat = labels.flatten()
    return np.sum(pred_flat == labels_flat) / len(labels_flat)
    train_loss_set = []
    epochs = 4
    for _ in trange(epochs, desc="Epoch"):
    model.train()
    tr_loss = 0
    nb_tr_examples, nb_tr_steps = 0, 0
    for step, batch in enumerate(train_dataloader):
    batch = tuple(t.to(device) for t in batch)#将数据放置在GPU上
    b_input_ids, b_input_mask, b_labels = batch
    optimizer.zero_grad()
    loss = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels)[0]
    # print("loss:",loss)
    train_loss_set.append(loss.item())
    loss.backward()
    optimizer.step()
    tr_loss += loss.item()
    nb_tr_examples += b_input_ids.size(0)
    nb_tr_steps += 1
    print("Train loss: {}".format(tr_loss / nb_tr_steps))

    #验证集
    model.eval()
    eval_loss, eval_accuracy = 0, 0
    nb_eval_steps, nb_eval_examples = 0, 0
    for batch in validation_dataloader:
    batch = tuple(t.to(device) for t in batch)
    b_input_ids, b_input_mask, b_labels = batch
    with torch.no_grad():
    logits = model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask)[0]
    logits = logits.detach().cpu().numpy()
    label_ids = b_labels.to('cpu').numpy()
    tmp_eval_accuracy = flat_accuracy(logits, label_ids)
    eval_accuracy += tmp_eval_accuracy
    nb_eval_steps += 1
    print("Validation Accuracy: {}".format(eval_accuracy / nb_eval_steps))
    • 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

    测试一下效果

    #str
    st="真的好吗?"
    str='[CLS] ' + st + ' [SEP]'
    str_tokenized_sents = tokenizer.tokenize(str)
    print(str_tokenized_sents)
    # Use the BERT tokenizer to convert the tokens to their index numbers in the BERT vocabulary
    str_input_ids = [tokenizer.convert_tokens_to_ids(str_tokenized_sents)]
    str_input_ids = pad_sequences(str_input_ids, maxlen=MAX_LEN, dtype="long", truncating="post", padding="post")
    print(str_input_ids)
    str_mask = [[float(i > 0) for i in str_input_ids[0]]]
    str_label=[0]

    str_input_ids = torch.tensor(str_input_ids).cuda()
    str_mask = torch.tensor(str_mask).cuda()
    str_label = torch.tensor(str_label).cuda()
    print("size:",str_input_ids.size(),str_mask.size(),str_label.size())
    logits_str = model(str_input_ids, token_type_ids=None, attention_mask=str_mask)[0]
    print(np.argmax(logits_str.detach().cpu().numpy(), axis=1))
    • 1

    • 2

    • 3

    • 4

    • 5

    • 6

    • 7

    • 8

    • 9

    • 10

    • 11

    • 12

    • 13

    • 14

    • 15

    • 16

    • 17

    • 18

    结果是个中性,再看看夸张点的270ef546a64306e3beaae7292a3a6ca5.png
    这里是负面的

    展开全文
  • 逻辑回归实现文本分类

    千次阅读 2018-05-01 14:56:29
    基于sklearn的文本分类—逻辑回归本文是文本分类的第一篇,记录使用逻辑回归进行文本分类任务,数据集下载地址:http://thuctc.thunlp.org/文本分类的主要内容如下: - 1.基于逻辑回归的文本分类 - 2.基于朴素贝叶斯...

    基于sklearn的文本分类—逻辑回归

    本文是文本分类的第一篇,记录使用逻辑回归进行文本分类任务,数据集下载地址:http://thuctc.thunlp.org/

    文本分类的主要内容如下: 
    - 1.基于逻辑回归的文本分类 
    - 2.基于朴素贝叶斯的文本分类 
    - 3.使用LDA进行文档降维以及特征选择 
    - 4.基于SVM的文本分类 
    - 5.基于多层感知机MLPC的文本分类 
    - 6.基于卷积神经网络词级别的文本分类以及调参 
    - 7.基于卷积神经网络的句子级别的文本分类以及调参 
    - 8.基于Facebook fastText的快速高效文本分类 
    - 9.基于RNN的文本分类 
    - 10.基于LSTM的文本分类 

    - 11.总结

    1 数据预处理

    其中使用的训练数据来自清华大学开源的文本分类数据集,原始数据集比较大,提供下载的是提取的小数据,thu_data_500 表示每个类提取500篇文章,thu_data_3000 表示每个类提取3000篇文章,一共14个类别,数据处理的代码如下:

    import os
    import codecs
    import jieba
    import re
    
    from sklearn.utils import shuffle
    category = ['星座', '股票', '房产', '时尚', '体育', '社会', '家居', '游戏', '彩票', '科技', '教育', '时政', '娱乐', '财经']
    



    # 每篇文档保留的文档数量
    #per_class_max_docs = 1000
    
    def load_data_to_mini(path, to_path, per_class_max_docs=1000):
        """
        处理清华大学语料库,将类别和文档处理成fasttext 所需要的格式
        :param path: 
        :param to_path: 
        :return: 
        """
        # 抽取后的语料库
        corpus = []
        if not os.path.isdir(path):
            print('path error')
        # 列举当前目录下的所有子列别目录
        with codecs.open(to_path, 'w') as f:
            for files in os.listdir(path):
                curr_path = os.path.join(path, files)
                print(curr_path)
                if os.path.isdir(curr_path):
                    count = 0
                    docs = []
                    for file in os.listdir(curr_path):
                        count += 1
                        if count > per_class_max_docs:
                            break
                        file_path = os.path.join(curr_path, file)
                        # 读取文件中的内容
                        with codecs.open(file_path, 'r', encoding='utf-8') as fd:
                            docs.append('__label__' + files + ' ' + ' '.join(jieba.cut(re.sub('[  \n\r\t]+', '', fd.read()))))
                            f.write('__label__' + files + ' ' + ' '.join(jieba.cut(re.sub('[  \n\r\t]+', '', fd.read()))))
                corpus.append(docs)
    
        # 将数据写到一个新的文件中
        with codecs.open(to_path, 'a') as f:
            for docs in corpus:
                for doc in docs:
                    f.write(doc + '\n')
    
        return corpus

    通过调用下面的代码,执行小数据集的提取

    corpus = load_data_to_mini('/root/git/data/THUCNews', 'thu_data_all', 1000)


    /root/git/data/THUCNews/娱乐
    /root/git/data/THUCNews/星座
    /root/git/data/THUCNews/时尚
    /root/git/data/THUCNews/股票
    /root/git/data/THUCNews/彩票
    /root/git/data/THUCNews/体育
    /root/git/data/THUCNews/房产
    /root/git/data/THUCNews/社会
    /root/git/data/THUCNews/财经
    /root/git/data/THUCNews/家居
    /root/git/data/THUCNews/游戏
    /root/git/data/THUCNews/科技
    /root/git/data/THUCNews/教育
    /root/git/data/THUCNews/时政

    我们看下提取的结果

    print('corpus size(%d,%d)' %(len(corpus), len(corpus[0])))
    corpus size(14,1000)

    可以看到,结果一共是14个类,每个类1000篇文档,下面看下corpus里面的具体内容

    corpus[0][1]
    '__label__股票 世基 投资 : 紧缩 压力 骤然 增加 沪 指 再失 2800 \u3000 \u3000 余炜 \u3000 \u3000 周二 大盘 在 半年线 处 止跌 后 , 连续 3 日 展开 反弹 , 昨日 一度 站上 过 2830 点 , 但 最终 还是 未能 收复 , 显示 出 20 日线 和 年线 从技术上 对 市场 的 压力 比 想象 中 更加 大 。 弱势 格局 下 , 利空 传言 纷至沓来 , 周末 效应 再次 显现 , 周五 大盘 给 我们 呈现出 的 是 一幕 疲软 下滑 走势 , 使得 前三天 的 反弹 基本 化为乌有 , 2800 点 再 一次 失守 , 股指 重新 来到 半年线 附近 求 支撑 。 \u3000 \u3000 盘面 热点 比较 稀少 , 其中 资产重组 、 业绩 增长 和 预增 题材 的 几只 品种 涨势 不错 , 昨日 提到 过 的 广电 信息 、 银鸽投资 连续 涨停 , 计划 高送 转 的 精诚 铜业 也 受大单 推动 涨停 。 此外 , 高铁 概念 逆势 重新 活跃 , 晋亿 实业 最高 逼近 涨停 , 带动 晋西 车轴 、 中国 北车 、 天马 股份 等 快速 上攻 , 其中 北车 和 晋 亿 实业 已经 率先 创出 阶段 新高 。 部分 具备 病菌 概念 的 医药 股 也 表现 较 好 , 自早 盘起 就 展现 强势 , 莱茵 生物 涨停 , 紫鑫 药业 、 海王 生物 、 联环 药业 大涨 7% 左右 。 \u3000 \u3000 从 目前 公开 消息 来看 , 相信 是 货币政策 面 的 利空 预期 在 对 市场 形成 压力 , 随着 韩国 央行 的 昨日 加息 , 新兴 经济体 紧缩 预期 骤然 升温 , 之前 秘鲁 和 泰国 已经 有过 连续 加息 的 动作 , 与此同时 , 虽然 西方 主要 国家 仍 在 维持 宽松 , 但 随着 发达 经济体 复苏 步伐 的 加快 , 通胀 也 有 抬头 迹象 。 国内 方面 , 下周 可能 将 公布 2010 年 全年 和 12 月份 的 经济运行 数据 , 形势 摆在 这里 , 投资者 有所 担忧 也 是 情理之中 。 欢迎 发表 评论 \xa0 \xa0 我要 评论'
    可以看到,开头时label的本文标签,后面接着的是新闻正文,正文已经使用jieba进行了分词,词之间使用空格键分开。 

    下面进行数据的切分,将数据划分为样本和标签,因为读取的数据是按照类别来分块的,在后面采用训练数据和测试数据的时候,会出现问题,所以这里也需要进行数据的随机打乱,数据打乱最好不要使用numpy.random.shuffle(),这个效率很低,而且非常容易出现内存溢出问题,推荐使用的是pandas或者是sklearn中的shuffle,我使用的是后者。切分的代码如下:

    def split_data_with_label(corpus):
        """
        将数据划分为训练数据和样本标签
        :param corpus: 
        :return: 
        """
        input_x = []
        input_y = []
    
        tag = []
        if os.path.isfile(corpus):
            with codecs.open(corpus, 'r') as f:
                for line in f:
                    tag.append(line)
    
        else:
            for docs in corpus:
                for doc in docs:
                    tag.append(doc)
        tag = shuffle(tag)
        for doc in tag:
            index = doc.find(' ')
            input_y.append(doc[:index])
            input_x.append(doc[index + 1 :])
    
        # 打乱数据,避免在采样的时候出现类别不均衡现象
        # datasets = np.column_stack([input_x, input_y])
        # np.random.shuffle(datasets)
        # input_x = []
        # input_y = []
        # for i in datasets:
        #     input_x.append(i[:-1])
        #     input_y.append(i[-1:])
        return [input_x, input_y]

    这个函数返回两个值,其中第一个返回值input_x是样本数据,一共14*1000行,第二个参数input_y和input_x有着相同的行数,每行对应着input_x中新闻样本的类别标签.

    2.特征选择

    下面将进行特征提取,特征选择的方法有基本的bag-of-words, tf-idf,n-gran等,我们主要使用TF-IDF进行这些方法进行实验,下面是代码:

    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.cross_validation import train_test_split
    from sklearn.metrics.scorer import make_scorer
    from sklearn import linear_model
    from sklearn import metrics
    
    from time import time

    /usr/local/lib/python3.5/dist-packages/sklearn/cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
      "This module will be removed in 0.20.", DeprecationWarning)
    def feature_extractor(input_x, case='tfidf', max_df=1.0, min_df=0.0):
        """
        特征抽取
        :param corpus: 
        :param case: 不同的特征抽取方法
        :return: 
        """
        return TfidfVectorizer(token_pattern='\w', ngram_range=(1,2), max_df=max_df, min_df=min_df).fit_transform(input_x)

    接下来将进行训练数据和测试数据的切分,现在不进行更好的交叉验证等技术,仅仅简单的以一定的比例划分训练数据和测试数据。使用sklearn中提供的工具,具体代码如下:

    def split_data_to_train_and_test(corpus, indices=0.2, random_state=10, shuffle=True):
        """
        将数据划分为训练数据和测试数据
        :param corpus: [input_x]
        :param indices: 划分比例
        :random_state: 随机种子
        :param shuffle: 是否打乱数据
        :return: 
        """
        input_x, y = corpus
    
        # 切分数据集
        x_train, x_dev, y_train, y_dev = train_test_split(input_x, y, test_size=indices, random_state=10)
        print("Vocabulary Size: {:d}".format(input_x.shape[1]))
        print("Train/Dev split: {:d}/{:d}".format(len(y_train), len(y_dev)))
        return x_train, x_dev, y_train, y_dev

    函数返回四个值,分别是训练数据的样本,训练数据的标签,测试数据样本,测试数据真实标签,下面调用朴素贝叶斯进行分类。

    逻辑回归是一种判别式模型,在线性回归的基础上,套用了一个sigmod函数,这个函数讲线性结果映射到一个概率区间,并且概率在0.5周围是光滑的,这就使得数据的分类结果都趋向于在0,1这两端。

    LogisticRegression()主要有的参数: 
    - penalty: 表示正则项为L1或者L2,默认是L2 
    - C 正则项的参数C,也就是惩罚系数 
    - fit_intercept 表示线性模型中的bias,也就是模型中的参数b 是一个布尔值,表示带或者不带bias,一般都是带的! 
    - solver 表示的是参数学习的方法,有{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}这几种情况,在小数据集下liblinear是相对好的选择,在数据集大的时候,选择saga,sag会是一个更好的选择,但是liblinear在多分类情况下受限制与ovr,所以其他的选择在多分类下更明智

    这里主要是进行相关的实验,不在理论上展开太多,下面采用逻辑回归进行文档分类,具体代码如下:

    def fit_and_predicted(train_x, train_y, test_x, test_y, penalty='l2', C=1.0, solver='lbfgs'):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.LogisticRegression(penalty=penalty, C=C, solver=solver, n_jobs=-1).fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))

    上面函数调用LogisticRegression(),基于线性分类器的变种模型有很多,我们将会在后面的试验中使用添加了L1范式的lasso回归,添加了L2范式的岭回归回归

    下面将进行实际的代码运行阶段了。

    # 1. 加载语料
    corpus = split_data_with_label('thu_data_1000')

    2.1 TF-IDF (max_df, min_df)=dafault (1.0,0.0)

    input_x, y = corpus
    # 2. 特征选择
    input_x = feature_extractor(input_x, 'tfidf')
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    Vocabulary Size: 942969
    Train/Dev split: 11200/2800
    # 4. 训练以及测试
    t0 = time()
    print('\t\t使用 max_df,min_df=(1.0,0.0) 进行特征选择的逻辑回归文本分类\t\t')
    fit_and_predicted(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))
     使用 max_df,min_df=(1.0,0.0) 进行特征选择的逻辑回归文本分类      
                 precision    recall  f1-score   support
    
    __label__体育       0.93      0.97      0.95       186
    __label__娱乐       0.87      0.88      0.88       233
    __label__家居       0.88      0.90      0.89       203
    __label__彩票       0.98      0.96      0.97       207
    __label__房产       0.90      0.90      0.90       178
    __label__教育       0.92      0.91      0.92       208
    __label__时尚       0.92      0.92      0.92       197
    __label__时政       0.83      0.87      0.85       211
    __label__星座       0.94      0.97      0.95       202
    __label__游戏       0.96      0.91      0.94       202
    __label__社会       0.85      0.92      0.88       210
    __label__科技       0.88      0.80      0.84       173
    __label__股票       0.87      0.82      0.84       196
    __label__财经       0.93      0.90      0.91       194
    
    avg / total       0.90      0.90      0.90      2800
    
    accuracy_score: 0.90321s
    time uesed: 44.1572s

    可以看出逻辑回归的文本分类方法在该数据集上表现良好,综合得分都有91%以上,下面我们将对tf-idf做文章,看看不同的tf-idf参数对特征产生影响

    2.2 TF-IDF 不同的max_df对结果参数的影响


    # 2. 特征选择
    max_df = [0.2, 0.4, 0.5, 0.8, 1.0, 1.5, 5]
    for i in max_df:
        input_x, y = corpus
        input_x = feature_extractor(input_x, 'tfidf', max_df=i)
        # 3.切分训练数据和测试数据
        train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
        # 4. 训练以及测试
        t0 = time()
        print('\t 使用 max_df,min_df=(%.1f,0.0) 进行特征选择的逻辑回归文本分类\t\t\n' %(i))
        fit_and_predicted(train_x, train_y, test_x, test_y)
        print('time uesed: %0.4fs' %(time() - t0))
    Vocabulary Size: 670795
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(0.2,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.95      0.95      0.95       109
           _娱乐_       0.73      0.88      0.80        92
           _家居_       0.98      0.88      0.93       109
           _彩票_       0.99      0.96      0.97        97
           _房产_       0.94      0.94      0.94        97
           _教育_       0.94      0.89      0.92       104
           _时尚_       0.87      0.87      0.87       110
           _时政_       0.86      0.89      0.87        93
           _星座_       0.96      0.93      0.95       105
           _游戏_       0.97      0.91      0.94       103
           _社会_       0.84      0.88      0.86        99
           _科技_       0.85      0.86      0.86        93
           _股票_       0.82      0.88      0.85        78
           _财经_       0.97      0.91      0.94       111
    
    avg / total       0.91      0.90      0.91      1400
    
    accuracy_score: 0.90429s
    time uesed: 63.8214s
    Vocabulary Size: 671113
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(0.4,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.97      0.94      0.96       109
           _娱乐_       0.78      0.89      0.83        92
           _家居_       0.94      0.87      0.90       109
           _彩票_       0.98      0.97      0.97        97
           _房产_       0.93      0.92      0.92        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.90      0.86      0.88       110
           _时政_       0.83      0.90      0.87        93
           _星座_       0.94      0.95      0.95       105
           _游戏_       0.95      0.90      0.93       103
           _社会_       0.86      0.90      0.88        99
           _科技_       0.88      0.87      0.88        93
           _股票_       0.80      0.91      0.85        78
           _财经_       0.95      0.89      0.92       111
    
    avg / total       0.91      0.91      0.91      1400
    
    accuracy_score: 0.90500s
    time uesed: 62.6203s
    Vocabulary Size: 671183
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(0.5,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.97      0.94      0.96       109
           _娱乐_       0.79      0.89      0.84        92
           _家居_       0.93      0.87      0.90       109
           _彩票_       0.98      0.97      0.97        97
           _房产_       0.93      0.91      0.92        97
           _教育_       0.94      0.88      0.91       104
           _时尚_       0.91      0.87      0.89       110
           _时政_       0.83      0.89      0.86        93
           _星座_       0.94      0.96      0.95       105
           _游戏_       0.95      0.89      0.92       103
           _社会_       0.85      0.90      0.87        99
           _科技_       0.88      0.87      0.88        93
           _股票_       0.80      0.91      0.85        78
           _财经_       0.94      0.88      0.91       111
    
    avg / total       0.91      0.90      0.90      1400
    
    accuracy_score: 0.90357s
    time uesed: 63.2442s
    Vocabulary Size: 671261
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(0.8,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.96      0.94      0.95       109
           _娱乐_       0.79      0.88      0.83        92
           _家居_       0.92      0.89      0.91       109
           _彩票_       0.98      0.97      0.97        97
           _房产_       0.93      0.91      0.92        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.91      0.87      0.89       110
           _时政_       0.83      0.88      0.85        93
           _星座_       0.94      0.97      0.96       105
           _游戏_       0.95      0.89      0.92       103
           _社会_       0.85      0.89      0.87        99
           _科技_       0.88      0.85      0.86        93
           _股票_       0.77      0.91      0.84        78
           _财经_       0.95      0.88      0.92       111
    
    avg / total       0.91      0.90      0.90      1400
    
    accuracy_score: 0.90143s
    time uesed: 64.9945s
    Vocabulary Size: 671267
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.95      0.94      0.94       109
           _娱乐_       0.80      0.88      0.84        92
           _家居_       0.95      0.89      0.92       109
           _彩票_       0.98      0.95      0.96        97
           _房产_       0.93      0.92      0.92        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.91      0.87      0.89       110
           _时政_       0.81      0.90      0.85        93
           _星座_       0.94      0.98      0.96       105
           _游戏_       0.95      0.90      0.93       103
           _社会_       0.84      0.89      0.86        99
           _科技_       0.89      0.84      0.86        93
           _股票_       0.76      0.91      0.83        78
           _财经_       0.96      0.87      0.92       111
    
    avg / total       0.91      0.90      0.90      1400
    
    accuracy_score: 0.90214s
    time uesed: 67.9015s
    Vocabulary Size: 671267
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.5,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.95      0.94      0.94       109
           _娱乐_       0.80      0.88      0.84        92
           _家居_       0.95      0.89      0.92       109
           _彩票_       0.98      0.95      0.96        97
           _房产_       0.93      0.92      0.92        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.91      0.87      0.89       110
           _时政_       0.81      0.90      0.85        93
           _星座_       0.94      0.98      0.96       105
           _游戏_       0.95      0.90      0.93       103
           _社会_       0.84      0.89      0.86        99
           _科技_       0.89      0.84      0.86        93
           _股票_       0.76      0.91      0.83        78
           _财经_       0.96      0.87      0.92       111
    
    avg / total       0.91      0.90      0.90      1400
    
    accuracy_score: 0.90214s
    time uesed: 66.4803s
    Vocabulary Size: 562057
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(5.0,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.94      0.83      0.88       109
           _娱乐_       0.61      0.75      0.67        92
           _家居_       0.91      0.55      0.69       109
           _彩票_       0.95      0.84      0.89        97
           _房产_       0.94      0.81      0.87        97
           _教育_       0.92      0.80      0.86       104
           _时尚_       0.82      0.72      0.77       110
           _时政_       0.77      0.78      0.78        93
           _星座_       0.86      0.75      0.80       105
           _游戏_       0.96      0.72      0.82       103
           _社会_       0.77      0.78      0.77        99
           _科技_       0.64      0.81      0.71        93
           _股票_       0.33      0.88      0.48        78
           _财经_       0.97      0.67      0.79       111
    
    avg / total       0.83      0.76      0.78      1400
    
    accuracy_score: 0.75929s
    time uesed: 22.6883s

    从实验结果可以看出,最好的max_df是在0.4-0.5之间,这也就是为什么很多demo中设置TF-IDF阈值进行特征的筛选,下面设置在max_df为1.0的目标下测试min_df;

    2.2 TF-IDF 不同的min_df对结果参数的影响


    # 2. 特征选择
    min_df = [0., 0.1, 0.2, 0.3, 0.4]
    for i in min_df:
        input_x, y = corpus
        input_x = feature_extractor(input_x, 'tfidf', max_df=1.0, min_df=i)
        # 3.切分训练数据和测试数据
        train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
        # 4. 训练以及测试
        t0 = time()
        print('\t 使用 max_df,min_df=(1.0,%.1f) 进行特征选择的逻辑回归文本分类\t\t\n' %(i))
        fit_and_predicted(train_x, train_y, test_x, test_y)
        print('time uesed: %0.4fs' %(time() - t0))
    Vocabulary Size: 671267
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.0) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.95      0.94      0.94       109
           _娱乐_       0.80      0.88      0.84        92
           _家居_       0.95      0.89      0.92       109
           _彩票_       0.98      0.95      0.96        97
           _房产_       0.93      0.92      0.92        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.91      0.87      0.89       110
           _时政_       0.81      0.90      0.85        93
           _星座_       0.94      0.98      0.96       105
           _游戏_       0.95      0.90      0.93       103
           _社会_       0.84      0.89      0.86        99
           _科技_       0.89      0.84      0.86        93
           _股票_       0.76      0.91      0.83        78
           _财经_       0.96      0.87      0.92       111
    
    avg / total       0.91      0.90      0.90      1400
    
    accuracy_score: 0.90214s
    time uesed: 67.8985s
    Vocabulary Size: 1052
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.1) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.93      0.94      0.94       109
           _娱乐_       0.75      0.75      0.75        92
           _家居_       0.87      0.85      0.86       109
           _彩票_       0.97      0.97      0.97        97
           _房产_       0.91      0.88      0.89        97
           _教育_       0.95      0.88      0.92       104
           _时尚_       0.88      0.84      0.86       110
           _时政_       0.82      0.89      0.86        93
           _星座_       0.93      0.96      0.94       105
           _游戏_       0.95      0.88      0.91       103
           _社会_       0.84      0.88      0.86        99
           _科技_       0.79      0.78      0.79        93
           _股票_       0.73      0.90      0.80        78
           _财经_       0.94      0.86      0.90       111
    
    avg / total       0.88      0.88      0.88      1400
    
    accuracy_score: 0.87786s
    time uesed: 1.8236s
    Vocabulary Size: 472
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.2) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.89      0.92      0.90       109
           _娱乐_       0.71      0.79      0.75        92
           _家居_       0.80      0.79      0.79       109
           _彩票_       0.97      0.86      0.91        97
           _房产_       0.92      0.80      0.86        97
           _教育_       0.96      0.84      0.89       104
           _时尚_       0.86      0.82      0.84       110
           _时政_       0.77      0.84      0.80        93
           _星座_       0.85      0.90      0.88       105
           _游戏_       0.78      0.66      0.72       103
           _社会_       0.77      0.87      0.82        99
           _科技_       0.71      0.73      0.72        93
           _股票_       0.65      0.83      0.73        78
           _财经_       0.92      0.85      0.88       111
    
    avg / total       0.83      0.82      0.82      1400
    
    accuracy_score: 0.82214s
    time uesed: 1.4046s
    Vocabulary Size: 244
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.3) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.87      0.89      0.88       109
           _娱乐_       0.73      0.66      0.70        92
           _家居_       0.81      0.74      0.78       109
           _彩票_       0.90      0.84      0.87        97
           _房产_       0.90      0.80      0.85        97
           _教育_       0.84      0.78      0.81       104
           _时尚_       0.78      0.83      0.81       110
           _时政_       0.68      0.78      0.73        93
           _星座_       0.83      0.86      0.84       105
           _游戏_       0.75      0.61      0.67       103
           _社会_       0.70      0.84      0.76        99
           _科技_       0.69      0.72      0.71        93
           _股票_       0.60      0.78      0.68        78
           _财经_       0.87      0.78      0.82       111
    
    avg / total       0.79      0.78      0.78      1400
    
    accuracy_score: 0.78143s
    time uesed: 1.1189s
    Vocabulary Size: 154
    Train/Dev split: 5600/1400
         使用 max_df,min_df=(1.0,0.4) 进行特征选择的逻辑回归文本分类     
    
                 precision    recall  f1-score   support
    
           _体育_       0.82      0.83      0.82       109
           _娱乐_       0.66      0.63      0.64        92
           _家居_       0.75      0.60      0.66       109
           _彩票_       0.91      0.85      0.88        97
           _房产_       0.82      0.75      0.78        97
           _教育_       0.77      0.72      0.74       104
           _时尚_       0.70      0.75      0.73       110
           _时政_       0.65      0.78      0.71        93
           _星座_       0.85      0.86      0.85       105
           _游戏_       0.63      0.57      0.60       103
           _社会_       0.70      0.76      0.73        99
           _科技_       0.61      0.67      0.64        93
           _股票_       0.54      0.67      0.60        78
           _财经_       0.78      0.72      0.75       111
    
    avg / total       0.73      0.73      0.73      1400
    
    accuracy_score: 0.72643s
    time uesed: 1.0229s

    从上面的实验可以看出,min_df或许取0.0是一个不错的选择,那就默认吧。

    不得不说,总感觉上面的控制变量进行参数的寻找是有毛病的,暂且就这么做吧。在后面的试验中,我们将选取max_df=0.5,min_df=0.0进行相关实验。

    3 逻辑回归的调参

    3.1 交叉验证

    在进行最优参数的调整之前,我们先看一下sklearn提供的另外一个函数LogisticRegressionCV(),它提供了标准的k-fold-cross-validator

    def fit_and_predicted_use_CV(train_x, train_y, test_x, test_y, penalty='l2', C=1.0, solver='lbfgs', cv=10):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.LogisticRegressionCV(penalty=penalty, C=C, solver=solver, n_jobs=-1, cv=cv).fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=i)
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    # 4. 训练以及测试
    t0 = time()
    print('\t 使用 max_df,min_df=(%.1f,0.0) 进行特征选择的逻辑回归文本分类\t\t\n' %(i))
    fit_and_predicted_use_CV(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))

    可以看到使用交叉验证的结果往往比我们直接划分数据集的效果要好一些。

    3.2 逻辑回归的最佳参数寻找

    现在将采用sklearn中提供的网格查找方法进行最优参数的寻找,网格查找其实是一种暴力查找方法。

    import numpy as np
    from sklearn.grid_search import GridSearchCV
    def train_and_predicted_with_graid(corpus, param_grid, cv=5):
        input_x, y = corpus
    
        scoring = ['precision_macro', 'recall_macro', 'f1_macro']
        clf = linear_model.LogisticRegression(n_jobs=-1)
        grid = GridSearchCV(clf, param_grid, cv=cv, scoring='accuracy')
    
        scores = grid.fit(input_x, y)
    
        print('parameters:')
        best_parameters = grid.best_estimator_.get_params()
        for param_name in sorted(best_parameters):
            print('\t%s: %r' %(param_name, best_parameters[param_name]))
        return scores
    C= [0.1, 0.2, 0.5, 0.8, 1.5, 3, 5]
    fit_intercept=[True, False]
    penalty=['l1', 'l2']
    solver=['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']
    solver = ['saga']
    param_grid=dict(C=C, fit_intercept=fit_intercept, penalty=penalty, solver=solver)
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=0.5, min_df=0.0)
    scores = train_and_predicted_with_graid([input_x, y], cv=5, param_grid=param_grid)
    parameters:
        C: 5
        class_weight: None
        dual: False
        fit_intercept: True
        intercept_scaling: 1
        max_iter: 100
        multi_class: 'ovr'
        n_jobs: -1
        penalty: 'l2'
        random_state: None
        solver: 'saga'
        tol: 0.0001
        verbose: 0
        warm_start: False

    4. 其他线性分类器

    4.1 简单的线性回归

    def fit_and_predicted_with_linerCV(train_x, train_y, test_x, test_y, alpha=1.0, cv=10):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.LogisticRegressionCV(penalty=penalty, C=C, solver=solver, n_jobs=-1, cv=cv).fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=i)
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    # 4. 训练以及测试
    t0 = time()
    print('\t 使用线性回归的文本分类\t\t\n' %(i))
    fit_and_predicted_with_linerCV(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))
    {'fit_time': array([ 0.69856882,  0.6891861 ,  0.68457079,  0.68122745,  0.68401599]),
     'score_time': array([ 0.24055672,  0.25055385,  0.24642444,  0.24583435,  0.25062966]),
     'test_f1_macro': array([ 0.93190598,  0.93358814,  0.92900074,  0.93620104,  0.93139325]),
     'test_precision_macro': array([ 0.93411186,  0.93509947,  0.93082131,  0.93790787,  0.93312355]),
     'test_recall_macro': array([ 0.93178571,  0.93357143,  0.92892857,  0.93607143,  0.93142857]),
     'train_f1_macro': array([ 0.95534592,  0.95516529,  0.95665886,  0.95573948,  0.95629695]),
     'train_precision_macro': array([ 0.95629235,  0.95618146,  0.95767379,  0.9566414 ,  0.95725075]),
     'train_recall_macro': array([ 0.95526786,  0.95508929,  0.95660714,  0.95571429,  0.95625   ])}

    4.2 使用L1范式的Lasso

    def fit_and_predicted_with_LassoCV(train_x, train_y, test_x, test_y):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.LassoCV().fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=i)
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    # 4. 训练以及测试
    t0 = time()
    print('\t 使用线性回归的文本分类\t\t\n' %(i))
    fit_and_predicted_with_LassoCV(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))
    {'fit_time': array([ 0.69856882,  0.6891861 ,  0.68457079,  0.68122745,  0.68401599]),
     'score_time': array([ 0.24055672,  0.25055385,  0.24642444,  0.24583435,  0.25062966]),
     'test_f1_macro': array([ 0.93190598,  0.93358814,  0.92900074,  0.93620104,  0.93139325]),
     'test_precision_macro': array([ 0.93411186,  0.93509947,  0.93082131,  0.93790787,  0.93312355]),
     'test_recall_macro': array([ 0.93178571,  0.93357143,  0.92892857,  0.93607143,  0.93142857]),
     'train_f1_macro': array([ 0.95534592,  0.95516529,  0.95665886,  0.95573948,  0.95629695]),
     'train_precision_macro': array([ 0.95629235,  0.95618146,  0.95767379,  0.9566414 ,  0.95725075]),
     'train_recall_macro': array([ 0.95526786,  0.95508929,  0.95660714,  0.95571429,  0.95625   ])}

    4.3 使用L2范式的岭回归

    def fit_and_predicted_with_RidgeCV(train_x, train_y, test_x, test_y):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.RidgeClassifierCV().fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=i)
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    # 4. 训练以及测试
    t0 = time()
    print('\t 使用线性回归的文本分类\t\t\n' %(i))
    fit_and_predicted_with_RidgeCV(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))
    {'fit_time': array([ 0.69856882,  0.6891861 ,  0.68457079,  0.68122745,  0.68401599]),
     'score_time': array([ 0.24055672,  0.25055385,  0.24642444,  0.24583435,  0.25062966]),
     'test_f1_macro': array([ 0.93190598,  0.93358814,  0.92900074,  0.93620104,  0.93139325]),
     'test_precision_macro': array([ 0.93411186,  0.93509947,  0.93082131,  0.93790787,  0.93312355]),
     'test_recall_macro': array([ 0.93178571,  0.93357143,  0.92892857,  0.93607143,  0.93142857]),
     'train_f1_macro': array([ 0.95534592,  0.95516529,  0.95665886,  0.95573948,  0.95629695]),
     'train_precision_macro': array([ 0.95629235,  0.95618146,  0.95767379,  0.9566414 ,  0.95725075]),
     'train_recall_macro': array([ 0.95526786,  0.95508929,  0.95660714,  0.95571429,  0.95625   ])}

    4.4 使用elastic net正则项的的线性回归

    def fit_and_predicted_with_ElasticNetCV(train_x, train_y, test_x, test_y):
        """
        训练与预测
        :param train_x: 
        :param train_y: 
        :param test_x: 
        :param test_y: 
        :return: 
        """
        clf = linear_model.MultiTaskElasticNetCV().fit(train_x, train_y)
        predicted = clf.predict(test_x)
        print(metrics.classification_report(test_y, predicted))
        print('accuracy_score: %0.5fs' %(metrics.accuracy_score(test_y, predicted)))
    input_x, y = corpus
    input_x = feature_extractor(input_x, 'tfidf', max_df=i)
    # 3.切分训练数据和测试数据
    train_x, test_x, train_y, test_y = split_data_to_train_and_test([input_x, y])
    # 4. 训练以及测试
    t0 = time()
    print('\t 使用线性回归的文本分类\t\t\n' %(i))
    fit_and_predicted_with_ElasticNetCV(train_x, train_y, test_x, test_y)
    print('time uesed: %0.4fs' %(time() - t0))
    {'fit_time': array([ 0.69856882,  0.6891861 ,  0.68457079,  0.68122745,  0.68401599]),
     'score_time': array([ 0.24055672,  0.25055385,  0.24642444,  0.24583435,  0.25062966]),
     'test_f1_macro': array([ 0.93190598,  0.93358814,  0.92900074,  0.93620104,  0.93139325]),
     'test_precision_macro': array([ 0.93411186,  0.93509947,  0.93082131,  0.93790787,  0.93312355]),
     'test_recall_macro': array([ 0.93178571,  0.93357143,  0.92892857,  0.93607143,  0.93142857]),
     'train_f1_macro': array([ 0.95534592,  0.95516529,  0.95665886,  0.95573948,  0.95629695]),
     'train_precision_macro': array([ 0.95629235,  0.95618146,  0.95767379,  0.9566414 ,  0.95725075]),
     'train_recall_macro': array([ 0.95526786,  0.95508929,  0.95660714,  0.95571429,  0.95625   ])}

    线性模型有很多的变种,其的简单高效并且可解释性强等特点在机器学习领域有很广泛的应用,这里不作进一步展开,大家自己科普吧~~

    5. 总结

    本文记录了使用sklearn,采用线性回归进行文本分类任务,在特征选择哪里,进行TF-IDF的参数验证部分,找到相对较好的max_df=0.5左右;

    在选取好了特征后,我们对数据集进行交叉验证,发现交叉验证的方式能提高模型的效果,推荐在后面划分数据集的时候使用交叉验证。

    我以逻辑回归为例,进行了线性回归分类器的参数搜索部分,然后利用最佳的参数,训练了最佳的逻辑回归文本分类模型,模型性能的acc值能达到:91%以上

    最后,我们利用其它具有代表性的线性分类器进行相关实验,但是没有进行调参工作,其中L1产生比较离散的数值,elasticNet结合了L1,L2的优缺点,其在集合上的图像介于两者之间,效果在论文中比L1,L2都要好。


    展开全文
  • DataWhale新闻文本分类

    2020-07-21 17:50:35
    零基础入门NLP之新闻文本分类 赛题理解 赛题名称:零基础入门NLP之新闻文本分类 赛题目标:通过这道赛题可以引导大家走入自然语言处理的世界,带大家接触NLP的预处理、模型构建和模型训练等知识点。 赛题任务:...

    零基础入门NLP之新闻文本分类

    赛题理解

    • 赛题名称:零基础入门NLP之新闻文本分类
    • 赛题目标:通过这道赛题可以引导大家走入自然语言处理的世界,带大家接触NLP的预处理、模型构建和模型训练等知识点。
    • 赛题任务:赛题以自然语言处理为背景,要求选手对新闻文本进行分类,这是一个典型的字符识别问题。

     

    赛题数据

    赛题以匿名处理后的新闻数据为赛题数据,数据集报名后可见并可下载。赛题数据为新闻文本,并按照字符级别进行匿名处理。整合划分出14个候选分类类别:财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐的文本数据。

    赛题数据由以下几个部分构成:训练集20w条样本,测试集A包括5w条样本,测试集B包括5w条样本。为了预防选手人工标注测试集的情况,我们将比赛数据的文本按照字符级别进行了匿名处理。

    数据标签

    处理后的赛题训练数据如下:

    Image

    在数据集中标签的对应的关系如下:{'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}

     

    评测指标

    评价标准为类别f1_score的均值,选手提交结果与实际测试集的类别进行对比,结果越大越好。

     

    解题思路

    赛题思路分析:赛题本质是一个文本分类问题,需要根据每句的字符进行分类。但赛题给出的数据是匿名化的,不能直接使用中文分词等操作,这个是赛题的难点。

    因此本次赛题的难点是需要对匿名字符进行建模,进而完成文本分类的过程。由于文本数据是一种典型的非结构化数据,因此可能涉及到特征提取分类模型两个部分。为了减低参赛难度,我们提供了一些解题思路供大家参考:

    • 思路1:TF-IDF + 机器学习分类器

    直接使用TF-IDF对文本提取特征,并使用分类器进行分类。在分类器的选择上,可以使用SVM、LR、或者XGBoost。

    • 思路2:FastText

    FastText是入门款的词向量,利用Facebook提供的FastText工具,可以快速构建出分类器。

    • 思路3:WordVec + 深度学习分类器

    WordVec是进阶款的词向量,并通过构建深度学习分类完成分类。深度学习分类的网络结构可以选择TextCNN、TextRNN或者BiLSTM。

    • 思路4:Bert词向量

    Bert是高配款的词向量,具有强大的建模学习能力

    展开全文
  • 文章目录前言第一课 论文导读文本分类简介文本分类文本分类发展历史机器学习文本分类相关方法前期知识储备 前言 本课程来自深度之眼deepshare.net,部分截图来自课程视频。 文章标题:Character-level Convolutional...
  • ​ 和对比模型的相对错误率比较 论文总结 关键点 : 卷积神经网络能够有效地提取关键的特征 字符级别的特征对于自然语言处理的有效性 CharTextCNN模型 创新点 : 提出了一种新的文本分类模型—CharTextCNN 提出了多个...
  • 在上一章节,介绍了使用传统机器学习算法来解决了文本分类问题,从本章开始将尝试使用深度学习方法,与传统机器学习不同,深度学习既提供特征提取功能,也可以完成分类的功能。 FastText是Facebook于2016年开源的一...
  • 文本分类的总结

    万次阅读 2018-08-28 08:43:17
    笨妞很少做文本分类,因为工作中文本分类确实不怎么用得到,唯一一个项目用到短文本分类,验证集acc和f1都到90%以上,所以在笨妞印象中文本分类应该是很简单的分类问题,都不属于NLP问题。偶然碰到DC竞赛中“达观杯...
  • 新闻文本分类Task1

    2020-07-21 19:37:17
    新闻文本分类Task1 赛题理解 赛题名称:零基础入门NLP之新闻文本分类 赛题目标:通过这道赛题可以引导大家走入自然语言处理的世界,带大家接触NLP的预处理、模型构建和模型训练等知识点。 赛题任务:赛题以自然语言...
  • 文本分类---逻辑回归(1)

    万次阅读 多人点赞 2018-01-03 17:40:04
    基于sklearn的文本分类—逻辑回归(1) 本文是文本分类的第一篇,记录使用逻辑回归进行文本分类任务,数据集下载地址:http://thuctc.thunlp.org/ 文本分类的主要内容如下: - 1.基于逻辑回归的文本分类 - 2....
  • 一、概述 上一篇文章中简单介绍了文本...值得一提的是,文档级别的情感分析也可以视作文本分类任务。此时情感分析的目的就是判断一段文本是否属于“正面”、“负面”等情感。 每篇文章一般只属于一个类别,这是最常见
  • Datawhale零基础入门NLP赛事-Task4文本表示方法FastText 本笔记是参加Datawhale零...FastText是facebook开源的一款集word2vec、文本分类等一体的机器学习训练工具。 字符级别的n-gram fastText使用了字符级别的n-gr
  • 新闻文本分类 - 赛题理解 赛题介绍 赛题名称 :零基础入门新闻文本分类 赛题任务:赛题以自然语言处理为背景,要求选手对新闻文本进行分类,这是一个典型的字符识别问题。 赛题数据 赛题以匿名处理后的新闻数据为...
  • 本文是对阿里云新人竞赛中的“零基础入门NLP - 新闻文本分类”解体过程进行的记录,目前仅使用了textCNN模型进行预测,后续还会考虑使用LSTM进行对比。 赛题数据 赛题以新闻数据为赛题数据,数据集报名后可见并可...
  • 在前面,使用了word embedding去实现了toy级别文本情感分类,那么现在在这个模型中添加上LSTM层,观察分类效果。 为了达到更好的效果,对之前的模型做如下修改 MAX_LEN = 200 构建dataset的过程,把数据...
  • HAN文本分类与tensorflow实现

    千次阅读 2019-02-15 16:47:49
     前面介绍了LSTM_CNN、RCNN等文本分类方法,这几种方法都是将整个文本进行encoder,但是我们知道,RNN对于长句子或长文档其实编码能力是有限的,会丢失掉句子中的信息,因此,为了克服这个问题,Nikolaos等人在2017...
  • 要求选手根据新闻文本字符对新闻的类别进行分类 带大家接触NLP的预处理、模型构建和模型训练等知识点。 为本赛题定制了系列学习方案,其中包括数据科学库、通用流程和 baseline方案学习三部分。 赛题数据: 赛题...
  • 摘要 论文提出了针对字符级文本分类器的白盒对抗样本生成器。该方法基于单词中字符的原子翻转操作,且效率很高,可以生成对抗样本以进行对抗训练,使模型更具有鲁棒性。再使用一些保持语义的约束,对单词级别分类器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 394
精华内容 157
关键字:

文本分类级别