python-2.7 - 在Python Pandas中训练朴素贝叶斯的不同类型的功能

标签 python-2.7 pandas machine-learning scikit-learn nltk

我想使用许多功能与朴素贝叶斯分类器一起训练,以对“ A”或“非A”进行分类。

我具有三个不同值类型的功能:
1)total_length-以正整数表示
2)元音比-十进制/分数
3)twoLetters_lastName-包含多个两个字母字符串的数组

# coding=utf-8
from nltk.corpus import names
import nltk
import random
import numpy as np
import pandas as pd
from pandas import DataFrame, Series
from sklearn.naive_bayes import GaussianNB
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

# Import data into pandas
data = pd.read_csv('XYZ.csv', header=0, encoding='utf-8', 
    low_memory=False)
df = DataFrame(data)

# Randomize records
df = df.reindex(np.random.permutation(df.index))

# Assign column into label Y
df_Y = df[df.AScan.notnull()][['AScan']].values # Labels are 'A' or 'non-A'
#print df_Y

# Assign column vector into attribute X
df_X = df[df.AScan.notnull()][['total_length', 'vowel_ratio', 'twoLetters_lastName']].values
#print df_X[0:10]

# Incorporate X and Y into ML algorithms
clf = GaussianNB()
clf.fit(df_X, df_Y)


df_Y如下:

[[u'non-A']
 [u'A']
 [u'non-A']
 ..., 
 [u'A']
 [u'non-A']
 [u'non-A']]


df_X如下:

[[9L 0.222222222 u"[u'ke', u'el', u'll', u'ly']"]
 [17L 0.41176470600000004
  u"[u'ma', u'ar', u'rg', u'ga', u'ar', u'ri', u'is']"]
 [11L 0.454545455 u"[u'du', u'ub', u'bu', u'uc']"]
 [11L 0.454545455 u"[u'ma', u'ah', u'he', u'er']"]
 [15L 0.333333333 u"[u'ma', u'ag', u'ge', u'ee']"]
 [13L 0.307692308 u"[u'jo', u'on', u'ne', u'es']"]
 [12L 0.41666666700000005
  u"[u'le', u'ef', u'f\\xe8', u'\\xe8v', u'vr', u're']"]
 [15L 0.26666666699999997 u"[u'ni', u'ib', u'bl', u'le', u'et', u'tt']"]
 [15L 0.333333333 u"[u'ki', u'in', u'ns', u'sa', u'al', u'll', u'la']"]
 [11L 0.363636364 u"[u'mc', u'cn', u'ne', u'ei', u'il']"]]


我收到此错误:

E:\Program Files Extra\Python27\lib\site-packages\sklearn\naive_bayes.py:150: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  y = column_or_1d(y, warn=True)
Traceback (most recent call last):
  File "C:werwer\wer\wer.py", line 32, in <module>
    clf.fit(df_X, df_Y)
  File "E:\Program Files Extra\Python27\lib\site-packages\sklearn\naive_bayes.py", line 163, in fit
    self.theta_[i, :] = np.mean(Xi, axis=0)
  File "E:\Program Files Extra\Python27\lib\site-packages\numpy\core\fromnumeric.py", line 2727, in mean
    out=out, keepdims=keepdims)
  File "E:\Program Files Extra\Python27\lib\site-packages\numpy\core\_methods.py", line 69, in _mean
    ret, rcount, out=ret, casting='unsafe', subok=False)
TypeError: unsupported operand type(s) for /: 'unicode' and 'long'


我的理解是,我需要将特征转换为一个numpy数组作为特征向量,但是我不认为我是否正在准备此X向量,因为它包含非常不同的值类型。

最佳答案

相关问题:Choosing a Classification Algorithm to Classify Mix of Nominal and Numeric Data-Mixing Categorial and Continuous Data in Naive Bayes Classifier Using Scikit-learn

好的,现在发生了一些事情。正如DalekSec指出的那样,最好的做法是在将所有功能输入到GaussianNB这样的模型中时,将所有功能保持为一种类型。追溯表明,在拟合模型时,它将尝试将字符串(大概是u"[u'ke', u'el', u'll', u'ly']"这样的unicode字符串之一)除以整数。因此,我们需要做的就是将训练数据转换为sklearn可以使用的形式。我们可以通过几种方法来做到这一点,其中ogrisel在答案here中雄辩地描述了其中两种。


我们可以将所有连续变量转换为分类变量。在我们的例子中,这意味着转换total_lengthvowel-ratio(在某些情况下,您可以将其视为类别变量,但请不要超越自己)。例如,您基本上可以根据百分比将每个功能中看到的值归类为5个值之一:“非常小”,“很小”,“中等”,“高”,“非常高”。据我所知,在sk-learn中没有真正简单的方法,但是您自己做应该很简单。您唯一要更改的是,您将要使用MultinomialNB而不是GaussianNB,因为您将要处理用多项分布而不是高斯分布更好地描述的特征。
我们可以将分类特征转换为数字特征,以供GaussianNB使用。我个人认为这是更直观的方法。基本上,在处理文本时,您需要弄清楚要从文本中获取什么信息并传递给分类器。在我看来,您想要提取不同的两个字母姓氏的发生率。

通常我会问你数据集中是否有所有姓氏,但是由于每个姓氏只有两个字母,因此我们可以存储所有可能的两个字母名(包括带有重音符号的unicode字符),并且影响最小。在性能上。这就是sklearn的CountVectorizer可能有用的地方。假设您的数据中包含两个字母姓氏的所有可能组合,则可以直接使用它来将twoLetter_lastname列中的一行转换为N维向量,该向量记录该行中每个唯一姓氏的出现次数。然后只需将此新矢量与您的其他两个功能组合到一个numpy数组中。

如果您没有两个字母(包括重音字母)的所有可能组合,则应考虑生成该列表,并将其作为CountVectorizer的“词汇”传递。这样一来,您的分类器便知道如何处理所有可能的姓氏。如果您不处理所有情况,这不是世界末日,但是在此方案中,任何新的看不见的两个字母对都将被忽略。

使用这些工具之前,应确保将姓氏列作为列表而不是作为字符串传递,因为这可能导致意外的行为。

您可以阅读有关常规sklearn预处理here的更多信息,以及有关sklearn here提供的CountVectorizer和其他文本特征提取工具的更多信息。我每天都会使用很多这些工具,并推荐它们用于基本的文本提取任务。在线上也有大量的教程和演示。您可能还会寻找其他类型的表示方法,例如二进制和一键编码。解决此问题的方法有很多,这主要取决于您的特定问题/需求。




在将所有数据转换为一种或另一种形式后,您应该能够使用高斯或多项式NB分类器。至于关于一维矢量的错误,您打印了df_Y,看起来像

[[u'non-A']
 [u'A']
 [u'non-A']
 ..., 
 [u'A']
 [u'non-A']
 [u'non-A']]


基本上,期望它在平面列表中,而不是列向量(一维列表的列表)中。只需使用numpy.reshape()或numpy.ravel()之类的命令对它进行相应的重塑(考虑到您仅处理一列(如所提及的错误),numpy.ravel()可能会更合适)。

关于python-2.7 - 在Python Pandas中训练朴素贝叶斯的不同类型的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32707914/

相关文章:

python - 读取 .txt 文件中的数据(不包括页眉和页脚)

python - 如何在 Pandas 数据框中用 0 填充多个列表?

python - Pandas :使用 .loc 和 MultiIndex 进行条件选择

python - 如何分块迭代两个 Pandas 数据框

machine-learning - 神经网络-Softmax交叉熵损失减少对应准确率下降

python - 如果字符串以 "1"开头,则替换标签之间的字符串

python - 像 -h 一样对待可选参数

python-2.7 - Azure 自动化 : Parse WEBHOOKDATA with a python runbook

python - Xgboost参数调优随机搜索

machine-learning - Keras VGG16 低层特征提取