Python 在pandas中编码多个列

Python 在pandas中编码多个列,python,encoding,scikit-learn,text-classification,Python,Encoding,Scikit Learn,Text Classification,我对分类变量的编码(我不熟悉这样的任务)有一些疑问,以便将它们用作logistic回归或SVM等模型中的参数。我的数据集如下所示: Text Symbol Note Account Age Label There is a red car ! red John 24 1 My bag was very expensive

我对分类变量的编码(我不熟悉这样的任务)有一些疑问,以便将它们用作logistic回归或SVM等模型中的参数。我的数据集如下所示:

Text                                  Symbol    Note    Account    Age   Label 
There is a red car                      !        red      John    24   1
My bag was very expensive               ?       orange    Luke    36  0
Where are my keys?                      @        red      Red     58  1
I promise: I will never let you go!    ...       green    Aoife   28  0
在“文本”中,存储了来自社区用户的评论符号“包括用户使用最多的符号。”注‘代表其级别(绿色代表更有经验;红色代表新加入者)’‘帐户’代表用户名。’标签'提供有关用户可信度的信息(如果0,则用户不是假的;如果1,则用户可能是一个可能的机器人。)

我想根据当前信息对新用户进行分类(参见上面的专栏)。我的数据集包含1000多行和400多个用户。 由于要使用分类器,我需要对分类字段和文本字段进行编码,因此我在sklearn中使用
multi-columnlabelencoder
,尝试如下操作:

MultiColumnLabelEncoder(columns = ['Text', 'Symbol', 'Note', 'Account']).fit_transform(df)
其中df是我的数据帧。然而,我明白,OneHotEncoder也应该更可取。我还包括了“帐户”,因为同一帐户可能有更多的评论,所以如果我将一个帐户归类为假帐户,并且我收到同一帐户的新评论,那么这个帐户很容易被检测为假帐户

正如我所提到的,目的是根据给定的信息(符号、注释、年龄、文本)以一定的准确性对测试集中的新元素进行分类,即寻找这些变量之间可能的相关性,这可以让我说新的帐户是假的(1)还是假的(0)

正如您所看到的,这个问题与分类器有关,其中的参数不仅是数值的,而且是分类的

对于数据预处理(删除停止字和清理数据),我使用了NLTK的Python包;关于特征提取(这应该是一个关键点,因为它与下一步相关,即使用分类器预测类别1或0),我发现很难理解编码的输出,以便能够将上述信息用作模型中的输入(其中目标称为标签,它是一个二进制值)。 我用logistic回归作为分类器,也用SVM

对于用户X(16岁,符号#,note Wonderful,note red-anew joiner),我的预期输出将以一定的百分比被分类为fake


如果有人能一步一步地向我解释如何在数据集中转换我的数据集,我可以在逻辑回归中使用其变量来确定标签(假或假),我将不胜感激新用户。

我这样做是基于我的一些旧代码,它本身就是基于。让我也参考一下,并注意到这将是特别有趣的,因为它包含了您想要对OneHotEncoder和更多进行的操作。来自CountVectorizer文档:

CountVectorizer实现标记化和出现计数 在单个类中:

在您提供的示例中,您总共有95个单词,其中包括22个独特的单词——假设您使用了所有可能不是您想要的单词。换言之,像“there,is,a,my,was,I,where and which”这样的单词可能无法帮助您区分好的帐户和伪造的帐户,但是“尼日利亚、王子、转账、银行、阴茎或阴茎增大”可能表示垃圾邮件

因此,在转到其他列(如年龄、符号等)之前,您将有22个维度(减去任何排除的维度)的数据。这是大量无用的数据(所有这些0都是免费的)因此,人们要么将其存储为稀疏矩阵,要么使用某种降维方法,如套索法或岭法。你可能认为这正是你现在想要做的,并且你走在了正确的轨道上。这与你要求的有点不同。你有点像,只是还有几点需要处理

首先,我认为这是重要的一点,您的一些字段应该是可疑的,因为它们是用户报告的(如年龄),或者是无用/冗余的(如名称)。没有孩子在色情网站或酿酒厂网站上说自己15岁。没有一个变态的老家伙说他65岁想和未成年的孩子聊天。即使是你认为人们最终会发现的约会网站。人们谎报自己的年龄。名字也是如此。如果你想,你可以包括他们,但记住那句老话:垃圾进来,垃圾出去

第二,Lasso回归和Ridge回归都指定了成本函数来帮助过度拟合模型。因此,基于平方英尺和邮政编码的房价是有意义的。但是,当你回到上一次房产税评估或最近图书馆的距离时,你可能会想“真的吗?“但这并不是你真正拥有的东西

把这两个放在一起,在你的例子中,你有文本(绝对有用)、符号(文本的派生)、帐户和年龄(见上面的注释)、注释(可能对它们打开和激活的时间有用),和标签——您的评估。因此,在五个字段中,只有两个字段可能有助于预测评估。所有这一切都是说,虽然您可以使用套索或岭,但您可能会更好地使用贝叶斯来完成此任务。如果您愿意,有多个页面将显示它们在特定条件下是等效的。但原因不是o认为Bayes是这个例子的计算负载。< /P> 符号(第四部分)我一直不愿意这么说,但根据经验,标点符号并不是一个好的指标。我之所以不愿意这么说,是因为你可能会想出一些新颖的实现方法。但很多人都尝试过,所以几率很小。部分原因与齐夫定律有关,它与单词有关,而不是标点符号。然而,如果你让标点符号承载某种附加语义,本质上是另一个词。记住,目标不是发现某个符号在垃圾邮件中,而是发现该符号是否是垃圾邮件的可靠指示器,是否足够独特

但是
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer(lowercase=True, tokenizer=None, stop_words='english',
   analyzer='word', max_df=1.0, min_df=1, max_features=None)
count_vect.fit(your training data)

# uncomment if you'd like to know the mapping of the columns to the words.
# count_vect.vocabulary_
# for key in sorted(count_vect.vocabulary_.keys()):
#     print("{0:<20s} {1}".format(key, count_vect.vocabulary_[key]))
X_train_counts = count_vect.transform(your training data)
print("The type of X_train_counts is {0}.".format(type(X_train_counts)))
print("The X matrix has {0} rows (documents) and {1} columns (words).".format(
        X_train_counts.shape[0], X_train_counts.shape[1]))
The type of X_train_counts is <class 'scipy.sparse.csr.csr_matrix'>.
The X matrix has 2257 rows (documents) and 35482 columns (words).
feature_words = count_vect.get_feature_names()
n = 7 #number of top words associated with the category that we wish to see

for cat in range(len(categories)):
    print(f"\nTarget: {cat}, name: {target_names[cat]}")
    log_prob = nb_model.feature_log_prob_[cat]
    i_topn = np.argsort(log_prob)[::-1][:n]
    features_topn = [feature_words[i] for i in i_topn]
    print(f"Top {n} tokens: ", features_topn)
X_new_counts = count_vect.transform(docs_new)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)
predictions = nb_model.predict(X_new_tfidf)
print('Predictions')
for doc, category in zip(docs_new, predictions):
    print("{0} => {1}".format(doc, twenty_train.target_names[category]))