【机器学习】使用朴素贝叶斯和其他文本分类器预测Reddit新闻情绪
发布日期:2021-09-18 21:55:46 浏览次数:1 分类:技术文章

本文共 15795 字,大约阅读时间需要 52 分钟。

了解如何预测Reddit开采的新闻标题的情绪

在我们之前的文章中,我们介绍了一些的,我们收集并分类政治头条。现在,我们可以使用该数据来训练二元分类器,以预测标题是正还是负。

文章资源

     笔记本: 

     库:熊猫,numpy,scikit-learn,matplotlib,seaborn,nltk,imblearn


目录


 

简要介绍分类及我们面临的一些问题

分类是基于训练数据集识别新的,看不见的观察的类别的过程,其具有已知的类别。

在我们的例子中,我们的头条新闻是观察,正面/负面情绪是类别。这是一个二元分类问题 - 我们试图预测标题是正面还是负面。

第一个问题:不平衡的数据集

机器学习中最常见的问题之一是使用不平衡的数据集。正如我们将在下面看到的,我们有一个略微不平衡的数据集,其中负数多于正数。

与欺诈检测等问题相比,我们的数据集不是超级不平衡的。有时你会有数据集,其中正类只有训练数据的1%,其余为负数。

我们要小心解释不平衡数据的结果。使用我们的分类器生成分数时,您可能会达到高达90%的,这通常被称为。

我们可能具有90%准确度的原因是由于我们的模型检查数据并决定始终预测为,从而导致高精度。

有很多方法可以解决这个问题,例如::

  • 收集更多数据:可以通过添加更多次要类示例来帮助平衡数据集。
  • 更改指标:使用混淆矩阵,精确度,召回或F1分数(精确度和召回的组合)。
  • 对数据进行过采样:从少数类中的示例中随机抽样属性以创建更多“假”数据。
  • 惩罚模式:在模型上实施额外成本,以便在培训期间对少数群体类别进行分类错误。这些惩罚使模型偏向于少数群体。

在我们的数据集中,我们的正面例子比负面例子少,我们将探索不同的指标并利用称为SMOTE的过采样技术。

让我们建立一些基本的导入:

import mathimport randomfrom collections import defaultdictfrom pprint import pprint# 防止将来/弃用警告显示在输出import warningswarnings.filterwarnings(action='ignore')import seaborn as snsimport matplotlib.pyplot as pltimport numpy as npimport pandas as pd# 设置绘图的全局样式sns.set_style(style='white')sns.set_context(context='notebook', font_scale=1.3, rc={'figure.figsize': (16,9)})

这些是整个笔记本中使用的基本导入,通常在每个数据科学项目中导入。当我们使用sklearn和其他库时,将会提出更具体的导入。

 

加载数据集

首先让我们加载我们在上一篇文章中创建的数据集:

df = pd.read_csv('reddit_headlines_labels.csv', encoding='utf-8')df.head()

现在我们在数据框中有数据集,让我们删除中性(0)标题标签,这样我们就可以专注于只对正面或负面进行分类:

df = df[df.label != 0]df.label.value_counts()
-1    758 1    496Name: label, dtype: int64

我们的数据框现在只包含正面和负面的例子,我们再次确认我们有更多的负面而不是正面。

让我们进入头条新闻的特色化。

 

将标题转换为特征

为了训练我们的分类器,我们需要将单词的标题转换为数字,因为算法只知道如何使用数字。

要进行这种转换,我们将使用CountVectorizersklearn。这是将单词转换为要素的非常简单的类。

与我们手动标记化和小写文本的上一个教程不同,CountVectorizer将为我们处理此步骤。我们需要做的只是将其作为头条新闻。

让我们使用一个小例子来展示如何将单词向量化为数字:

from sklearn.feature_extraction.text import CountVectorizers1 = "Senate panel moving ahead with Mueller bill despite McConnell opposition"s2 = "Bill protecting Robert Mueller to get vote despite McConnell opposition"vect = CountVectorizer(binary=True)X = vect.fit_transform([s1, s2])X.toarray()
array([[1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1],       [0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0]], dtype=int64)

我们在这里做的是关于类似主题的两个标题并将它们矢量化。

vect使用默认参数设置标记化和小写字。最重要的是,我们设置了binary=True这样我们得到的输出为0(该句子中不存在单词)或1(该句子中存在单词)。

vect根据它在你给出的所有文本中看到的所有单词构建词汇表,然后在当前句子中存在该单词时指定0或1。为了更清楚地看到这一点,让我们看一下映射到第一句的特征名称:

list(zip(X.toarray()[0], vect.get_feature_names()))
[(1, 'ahead'), (1, 'bill'), (1, 'despite'), (0, 'get'), (1, 'mcconnell'), (1, 'moving'), (1, 'mueller'), (1, 'opposition'), (1, 'panel'), (0, 'protecting'), (0, 'robert'), (1, 'senate'), (0, 'to'), (0, 'vote'), (1, 'with')]

这是第一句的矢量化映射。你可以看到有一个1映射到'前面'因为'前面'出现了s1。但是如果我们看一下s2

list(zip(X.toarray()[1], vect.get_feature_names()))
[(0, 'ahead'), (1, 'bill'), (1, 'despite'), (1, 'get'), (1, 'mcconnell'), (0, 'moving'), (1, 'mueller'), (1, 'opposition'), (0, 'panel'), (1, 'protecting'), (1, 'robert'), (0, 'senate'), (1, 'to'), (1, 'vote'), (0, 'with')]

因为那个词没有出现在'前方',所以有一个0 s2。但请注意,每行包含到目前为止看到的每个单词。

当我们将其扩展到数据集中的所有标题时,这个词汇量将会增长很多。像上面打印的那样的每个映射最终将成为矢量化器遇到的所有单词的长度。

现在让我们将矢量化器应用到我们的所有标题中:

vect = CountVectorizer(max_features=1000, binary=True)X = vect.fit_transform(df.headline)X.toarray()
array([[0, 0, 0, ..., 0, 1, 0],       [0, 0, 0, ..., 0, 0, 0],       [0, 0, 0, ..., 0, 0, 0],       ...,       [0, 0, 0, ..., 0, 0, 0],       [0, 0, 0, ..., 0, 0, 0],       [0, 0, 0, ..., 0, 0, 0]], dtype=int64)

请注意,矢量图默认情况下将所有内容存储在稀疏数组中,并使用X.toarray()向我们显示密集版本。稀疏数组的效率要高得多,因为每行中的大多数值都是0.换句话说,大多数标题只有十几个字,每行包含所见过的每个字,稀疏数组只存储非零值索引。

您还会注意到我们有一个新的关键字参数; max_features。这基本上是按频率排列的要考虑的单词数。所以1000值意味着我们只想看1000个最常见的单词作为特征。

现在我们知道矢量化是如何工作的,让我们在行动中使用它。

 

准备训练

在训练,甚至矢量化之前,让我们将数据分成训练和测试集。在对数据进行任何操作之前执行此操作非常重要,因此我们有一个新的测试集。

from sklearn.model_selection import train_test_splitX = df.headliney = df.labelX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

我们的测试尺寸为0.2或20%。这意味着,X_testy_test包含我们的数据,我们保留对测试的20%。

现在让我们只在训练集上拟合矢量化器并执行矢量化。

重申一下,重要的是不要将矢量化器放在所有数据上,因为我们需要一个干净的测试集来评估性能。在一切上拟合矢量化器会导致数据泄漏,导致不可靠的结果,因为矢量化器不应该知道未来的数据。

我们可以适应矢量化器并X_train一步变换:

from sklearn.feature_extraction.text import CountVectorizervect = CountVectorizer(max_features=1000, binary=True)X_train_vect = vect.fit_transform(X_train)

X_train_vect 现在转换为正确的格式以提供Naive Bayes模型,但我们首先考虑平衡数据。

 

平衡数据

似乎可能有比正面标题(hmm)更多的负面标题,因此我们有更多的负面标签而不是正面标签。

counts = df.label.value_counts()print(counts)print("\nPredicting only -1 = {:.2f}% accuracy".format(counts[-1] / sum(counts) * 100))
-1    758 1    496Name: label, dtype: int64Predicting only -1 = 60.45% accuracy

我们可以从上面看到,我们的负数略多于正数,使得我们的数据集略有不平衡。

通过计算我们的模型是否仅选择预测-1,更大的类,我们将获得约60%的准确度。这意味着在我们的二元分类模型中,随机几率为50%,60%的准确度不会告诉我们太多。我们肯定希望看到精度和召回而不是准确性。

我们可以通过使用称为SMOTE 的过采样形式来平衡我们的数据。SMOTE着眼于小班,在我们的案例中肯定,并创建新的综合训练样例。了解更多关于该算法。

注意:我们必须确保我们只对列车数据进行过采样,这样我们就不会将任何信息泄露给测试集。

让我们用imblearn库来执行SMOTE :

from imblearn.over_sampling import SMOTEsm = SMOTE()X_train_res, y_train_res = sm.fit_sample(X_train_vect, y_train)
unique, counts = np.unique(y_train_res, return_counts=True)print(list(zip(unique, counts)))
[(-1, 601), (1, 601)]

这些班级现在已经为火车组平衡了。我们可以继续训练朴素贝叶斯模型。

 

朴素贝叶斯

对于我们的第一个算法,我们将使用极其快速和多功能的朴素贝叶斯模型。

让我们从sklearn中实例化一个并将其与我们的训练数据相匹配:

from sklearn.naive_bayes import MultinomialNBnb = MultinomialNB()nb.fit(X_train_res, y_train_res)nb.score(X_train_res, y_train_res)
0.9201331114808652

Naive Bayes已经成功完成了我们所有的训练数据,并准备进行预测。你会发现我们得分为92%。这是合适的分数,而不是实际的准确度分数。接下来您将看到我们需要使用我们的测试集来获得准确性的良好估计。

让我们对测试集进行矢量化,然后使用该测试集来预测每个测试标题是正面还是负面。由于我们避免任何数据泄漏,我们只是改造而不是改装。我们也不会使用SMOTE进行过采样。

X_test_vect = vect.transform(X_test)y_pred = nb.predict(X_test_vect)y_pred
array([-1, -1, -1, -1, -1, -1,  1,  1,  1,  1,  1, -1,  1, -1,  1,  1,  1,        1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1,  1, -1,  1,  1,       -1, -1,  1,  1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1,  1, -1,  1,        1,  1,  1,  1, -1, -1,  1,  1, -1, -1, -1,  1,  1,  1,  1, -1, -1,       -1, -1,  1, -1,  1, -1, -1, -1, -1,  1, -1,  1,  1, -1, -1, -1, -1,       -1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1, -1, -1, -1, -1,  1,        1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1,  1,       -1, -1, -1, -1, -1,  1, -1,  1, -1,  1,  1, -1,  1,  1,  1, -1, -1,       -1, -1,  1, -1, -1, -1,  1,  1,  1, -1, -1, -1, -1,  1, -1,  1, -1,       -1,  1, -1,  1, -1, -1, -1, -1, -1,  1,  1,  1,  1,  1, -1,  1, -1,        1, -1, -1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1, -1,  1, -1, -1,       -1,  1, -1, -1, -1, -1, -1, -1, -1,  1,  1, -1,  1, -1, -1, -1,  1,       -1,  1, -1, -1,  1, -1, -1,  1, -1, -1,  1, -1,  1, -1, -1, -1, -1,       -1,  1,  1, -1,  1, -1, -1,  1,  1,  1, -1, -1,  1, -1,  1,  1, -1,       -1, -1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1, -1], dtype=int64)

y_pred现在包含测试集的每一行的预测。使用此预测结果,我们可以将其传递给具有真实标签的sklearn指标,以获得准确度分数,F1分数,并生成混淆矩阵:

from sklearn.metrics import accuracy_score, f1_score, confusion_matrixprint("Accuracy: {:.2f}%".format(accuracy_score(y_test, y_pred) * 100))print("\nF1 Score: {:.2f}".format(f1_score(y_test, y_pred) * 100))print("\nCOnfusion Matrix:\n", confusion_matrix(y_test, y_pred))
Accuracy: 74.50%F1 Score: 68.93COnfusion Matrix: [[116  41] [ 23  71]]

我们可以看到我们的模型已经以75%的准确度预测了标题的情绪,但是看看混淆矩阵,我们可以看到它没有做出那么好的工作分类。

对于混淆矩阵的细分,我们有:

  • 116预测为负(-1),为负(-1)。真正的否定
  • 71预测为阳性(+1),为阳性(+1)。真实的
  • 23预测为负(-1),但为正(+1)。假阴性
  • 41预测为阳性(+1),但为阴性(-1)。误报

所以我们的分类器正在得到很多负面因素,但是有大量的错误预测。我们将看看我们是否可以使用下面的其他分类器来改进这些指标。

 

交叉验证

现在让我们使用交叉验证,我们在不同位置对相同数据生成10次不同的训练和测试集。

现在,我们建立了通常80%的数据作为培训,20%作为测试。单个测试集上的预测准确性并没有说明泛化。为了更好地了解我们的分类器的泛化能力,我们可以使用两种不同的技术:

1)K折交叉验证:将这些例子随机分成kk等大小的子集(通常为10)。在kk子集中,单个子样本用于测试模型,剩余的k-1k-1子集用作训练数据。然后将交叉验证技术重复kk次,从而产生这样的过程,其中每个子集仅使用一次作为测试集的一部分。最后,计算kk运行的平均值。这种方法的优点是每个例子都用于训练和测试集。

2)蒙特卡罗交叉验证:随机将数据集拆分为训练和测试数据,运行模型,然后对结果取平均值。该方法的优点是列车/测试分裂的比例不依赖于迭代次数,这对于非常大的数据集是有用的。另一方面,如果您没有经历足够的迭代,则此方法的缺点是可能永远不会在测试子集中选择某些示例,而其他示例可能被选择多次。

 

有关这两种方法之间差异的更好解释,请查看以下答案::

来自sklearn图书馆的相关课程是ShuffleSplit。这首先执行shuffle,然后将数据拆分为train / test。由于它是一个迭代器,它将执行随机shuffle并为每次迭代分割。这是上面提到的蒙特卡罗方法的一个例子。

通常情况下,我们可以使用sklearn.model_selection.cross_val_score自动计算每个折叠的分数,但我们将展示手动分割ShuffleSplit

此外,如果你熟悉cross_val_score你,你会注意到它的ShuffleSplit工作方式不同。所述n_splits参数ShuffleSplit是时间随机化数据的数量,然后把它分解80/20,而cv在参数cross_val_score是折叠的数量。通过使用n_splits较大的数据集,我们可以很好地逼近较大数据集的真实性能,但绘制起来更难。

from sklearn.model_selection import ShuffleSplitX = df.headliney = df.labelss = ShuffleSplit(n_splits=10, test_size=0.2)sm = SMOTE()accs = []f1s = []cms = []for train_index, test_index in ss.split(X):        X_train, X_test = X.iloc[train_index], X.iloc[test_index]    y_train, y_test = y.iloc[train_index], y.iloc[test_index]        # Fit vectorizer and transform X train, then transform X test    X_train_vect = vect.fit_transform(X_train)    X_test_vect = vect.transform(X_test)        # Oversample    X_train_res, y_train_res = sm.fit_sample(X_train_vect, y_train)        # Fit Naive Bayes on the vectorized X with y train labels,     # then predict new y labels using X test    nb.fit(X_train_res, y_train_res)    y_pred = nb.predict(X_test_vect)        # Determine test set accuracy and f1 score on this fold using the true y labels and predicted y labels    accs.append(accuracy_score(y_test, y_pred))    f1s.append(f1_score(y_test, y_pred))    cms.append(confusion_matrix(y_test, y_pred))    print("\nAverage accuracy across folds: {:.2f}%".format(sum(accs) / len(accs) * 100))print("\nAverage F1 score across folds: {:.2f}%".format(sum(f1s) / len(f1s) * 100))print("\nAverage Confusion Matrix across folds: \n {}".format(sum(cms) / len(cms)))
Average accuracy across folds: 72.95%Average F1 score across folds: 66.43%Average Confusion Matrix across folds:  [[115.6  39. ] [ 28.9  67.5]]

看起来平均准确度和F1分数都与我们在上面的单个折叠上看到的相似。

 

让我们绘制我们的结果

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(16,9))acc_scores = [round(a * 100, 1) for a in accs]f1_scores = [round(f * 100, 2) for f in f1s]x1 = np.arange(len(acc_scores))x2 = np.arange(len(f1_scores))ax1.bar(x1, acc_scores)ax2.bar(x2, f1_scores, color='#559ebf')# Place values on top of barsfor i, v in enumerate(list(zip(acc_scores, f1_scores))):    ax1.text(i - 0.25, v[0] + 2, str(v[0]) + '%')    ax2.text(i - 0.25, v[1] + 2, str(v[1]))ax1.set_ylabel('Accuracy (%)')ax1.set_title('Naive Bayes')ax1.set_ylim([0, 100])ax2.set_ylabel('F1 Score')ax2.set_xlabel('Runs')ax2.set_ylim([0, 100])sns.despine(bottom=True, left=True)  # Remove the ticks on axes for cleaner presentationplt.show()

Naive Bayes runs F1 and Accuracy Scores

在一些运行之间,F1得分波动超过15个点,这可以用更大的数据集来补救。让我们看看其他算法是如何做的。

 

SCIKIT-LEARN中的其他分类算法

正如你所看到的Naive Bayes表现得相当不错,所以让我们试试其他分类器吧。

我们将使用与之前相同的shuffle分割,但现在我们将在每个循环中运行几种类型的模型:

from sklearn.naive_bayes import BernoulliNBfrom sklearn.linear_model import LogisticRegression, SGDClassifierfrom sklearn.svm import LinearSVCfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.neural_network import MLPClassifierX = df.headliney = df.labelcv = ShuffleSplit(n_splits=20, test_size=0.2)models = [    MultinomialNB(),    BernoulliNB(),    LogisticRegression(),    SGDClassifier(),    LinearSVC(),    RandomForestClassifier(),    MLPClassifier()]sm = SMOTE()# Init a dictionary for storing results of each run for each modelresults = {    model.__class__.__name__: {        'accuracy': [],         'f1_score': [],        'confusion_matrix': []    } for model in models}for train_index, test_index in cv.split(X):    X_train, X_test  = X.iloc[train_index], X.iloc[test_index]    y_train, y_test = y.iloc[train_index], y.iloc[test_index]        X_train_vect = vect.fit_transform(X_train)        X_test_vect = vect.transform(X_test)        X_train_res, y_train_res = sm.fit_sample(X_train_vect, y_train)        for model in models:        model.fit(X_train_res, y_train_res)        y_pred = model.predict(X_test_vect)                acc = accuracy_score(y_test, y_pred)        f1 = f1_score(y_test, y_pred)        cm = confusion_matrix(y_test, y_pred)                results[model.__class__.__name__]['accuracy'].append(acc)        results[model.__class__.__name__]['f1_score'].append(f1)        results[model.__class__.__name__]['confusion_matrix'].append(cm)

我们现在为每个模型存储了一堆准确度分数,f1分数和混淆矩阵。让我们一起平均这些以获得模型和折叠的平均分数:

for model, d in results.items():    avg_acc = sum(d['accuracy']) / len(d['accuracy']) * 100    avg_f1 = sum(d['f1_score']) / len(d['f1_score']) * 100    avg_cm = sum(d['confusion_matrix']) / len(d['confusion_matrix'])        slashes = '-' * 30        s = f"""{model}\n{slashes}        Avg. Accuracy: {avg_acc:.2f}%        Avg. F1 Score: {avg_f1:.2f}        Avg. Confusion Matrix:         \n{avg_cm}        """    print(s)
MultinomialNB------------------------------        Avg. Accuracy: 74.70%        Avg. F1 Score: 69.63        Avg. Confusion Matrix:         [[114.05  36.4 ] [ 27.1   73.45]]        BernoulliNB------------------------------        Avg. Accuracy: 75.32%        Avg. F1 Score: 67.96        Avg. Confusion Matrix:         [[122.75  27.7 ] [ 34.25  66.3 ]]        LogisticRegression------------------------------        Avg. Accuracy: 74.80%        Avg. F1 Score: 68.31        Avg. Confusion Matrix:         [[119.2   31.25] [ 32.    68.55]]        SGDClassifier------------------------------        Avg. Accuracy: 71.75%        Avg. F1 Score: 65.31        Avg. Confusion Matrix:         [[112.6   37.85] [ 33.05  67.5 ]]        LinearSVC------------------------------        Avg. Accuracy: 73.01%        Avg. F1 Score: 66.61        Avg. Confusion Matrix:         [[115.55  34.9 ] [ 32.85  67.7 ]]        RandomForestClassifier------------------------------        Avg. Accuracy: 69.64%        Avg. F1 Score: 52.74        Avg. Confusion Matrix:         [[132.    18.45] [ 57.75  42.8 ]]        MLPClassifier------------------------------        Avg. Accuracy: 74.14%        Avg. F1 Score: 67.43        Avg. Confusion Matrix:         [[118.75  31.7 ] [ 33.2   67.35]]

 

我们得到了一些相当不错的结果,但总的来说,我们需要更多的数据来确定哪一个表现最好。

由于我们仅在大约300个示例的测试集大小上运行度量标准,因此精度的0.5%差异意味着只有大约2个示例与其他模型正确分类。如果我们的测试集合为10,000,那么准确度的0.5%差异将等于50个正确分类的标题,这更令人放心。

随机森林和多项式朴素贝叶斯之间的区别非常明显,但多项式和伯努利朴素贝叶斯之间的区别并非如此。为了进一步比较这两者,我们需要更多数据。

让我们看看合奏是否可以带来更好的效果。

 

集合分类器

在我们单独评估每个分类器之后,让我们看看集成是否有助于改进我们的指标。

我们将使用VotingClassifier默认为多数规则投票的sklearn 。

from sklearn.ensemble import VotingClassifierX = df.headliney = df.labelcv = ShuffleSplit(n_splits=10, test_size=0.2)models = [    MultinomialNB(),    BernoulliNB(),    LogisticRegression(),    SGDClassifier(),    LinearSVC(),    RandomForestClassifier(),    MLPClassifier()]m_names = [m.__class__.__name__ for m in models]models = list(zip(m_names, models))vc = VotingClassifier(estimators=models)sm = SMOTE()# No need for dictionary nowaccs = []f1s = []cms = []for train_index, test_index in cv.split(X):    X_train, X_test  = X.iloc[train_index], X.iloc[test_index]    y_train, y_test = y.iloc[train_index], y.iloc[test_index]        X_train_vect = vect.fit_transform(X_train)        X_test_vect = vect.transform(X_test)        X_train_res, y_train_res = sm.fit_sample(X_train_vect, y_train)        vc.fit(X_train_res, y_train_res)        y_pred = vc.predict(X_test_vect)        accs.append(accuracy_score(y_test, y_pred))    f1s.append(f1_score(y_test, y_pred))    cms.append(confusion_matrix(y_test, y_pred))
print("Voting Classifier")print("-" * 30)print("Avg. Accuracy: {:.2f}%".format(sum(accs) / len(accs) * 100))print("Avg. F1 Score: {:.2f}".format(sum(f1s) / len(f1s) * 100))print("Confusion Matrix:\n", sum(cms) / len(cms))
Voting Classifier------------------------------Avg. Accuracy: 75.78%Avg. F1 Score: 68.51Confusion Matrix: [[123.7  28.7] [ 32.1  66.5]]

 

尽管我们的大多数分类器都表现出色,但它与我们从Multinomial Naive Bayes得到的结果没有多大差别,这可能是令人惊讶的。肯定将一堆混合在一起会产生更好的结果,但这种性能差异的缺乏证明仍有许多领域需要探索。例如:

  • 更多数据如何影响性能(由于我们的小数据集,最佳起点)
  • 网格搜索每个模型的不同参数
  • 通过查看模型相关性来调试集合
  • 尝试不同风格的

 

最后的话

到目前为止我们已经

  • 来自Reddit / r / politics的挖掘数据
  • 获得头条新闻的情绪评分
  • 矢量化数据
  • 通过几种类型的模型运行数据
  • 合奏模型在一起

不幸的是,没有明显的获胜模式。有一对我们已经看到它肯定表现不佳,但有一些徘徊在相同的准确性。此外,混淆矩阵显示大约一半的正面标题被错误分类,因此还有很多工作要做。

既然您已经了解了这个管道的工作原理,那么代码和建模的架构还有很大的改进空间。我鼓励您在提供的笔记本中尝试所有这些。看看你可以利用什么其他的subreddits情绪,如股票,公司,产品等..有很多有价值的数据!

 

帮助我们改进这篇文章和系列

如果您对将本文和系列文章扩展到某些探索领域感兴趣,请在下面发表评论,我们会将其添加到内容管道中。

谢谢阅读!

 

原文:

 

转载地址:https://blog.csdn.net/ChenVast/article/details/82992500 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【机器学习】使用Python的自然语言工具包(NLTK)对Reddit新闻标题进行情感分析
下一篇:【机器学习】使用Python中的局部敏感哈希(LSH)构建推荐引擎

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月09日 13时41分53秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

oracle12c order by,oracle 数据库中order by 的一些高级用法 2019-04-21
oracle8i substr,Oracle中的INSTR,NVL和SUBSTR函数的用法详解 2019-04-21
导出oracle11g的空表,轻松解决oracle11g 空表不能 exp 导出 的问题。 2019-04-21
php把整数拆分成数组,数组拆分处理(整数时的处理),该怎么处理 2019-04-21
oracle numlist,oracle sql str2numlist numtabletype 2019-04-21
php红包平均分配,红包平均分配算法 2019-04-21
linux磁盘的命令是,linux磁盘相关的命令 2019-04-21
linux服务器 缓存,Linux服务器内存使用分析及内存缓存 2019-04-21
linux查进程内存问题,关于linux 查看服务进程内存,cpu,内存占用的一些基础命令... 2019-04-21
linux英文包安装教程视频,Linux源码包安装过程讲解 2019-04-21
linux 关闭rsync服务器,linux下配置rsync服务器和实时同步 2019-04-21
linux初始化TCP服务失败,深入Linux系统追踪TCP初始化 2019-04-21
arch Linux添加源,在Arch Linux系统中使用Archlinuxcn源(清华源)的方法 2019-04-21
私人linux远程连接,Linux远程连接 - osc_5g1gl9wp的个人空间 - OSCHINA - 中文开源技术交流社区... 2019-04-21
windows文件迁移到linux,从Windows到Linux迁移之文件服务器(Samba和AD完美结合) 2019-04-21
linux下vi编辑器的命令大全,linux下VI编辑器命令大全(超级完整版) 2019-04-21
linux结构体数组的定义数组,task_struct结构体中的run_list和array域 2019-04-21
C语言极坐标转直角坐标,C语言实现直角坐标转换为极坐标的方法 2019-04-21
16F877A和24C02通信汇编语言,PIC16f877A读写24c02程序 2019-04-21
用c语言编写小于n的所有素数,关于求N以内素数的一点小问题(N小于一亿) 2019-04-21