用于新语言的基于 python 的朴素基分类器

Posted

技术标签:

【中文标题】用于新语言的基于 python 的朴素基分类器【英文标题】:python based naive base classifer for new language 【发布时间】:2014-09-19 06:04:26 【问题描述】:

我并不是要构建一个全新的朴素贝叶斯分类器。已经有很多例如scitkit learn 有朴素贝叶斯实现,NLTK 有自己的NaiveBayesClassifier。

我的语言(印度语之一)有 1000 多个句子用于训练,300 多个句子用于测试集。我需要做的就是选择一个分类器(实现朴素贝叶斯),训练它并测试它的准确性。

问题是文本不是英文,而是 Devnagari unicode。

我正在寻求关于哪个分类器非常适合掩盖我目前遇到的主要问题是 unicode 的建议。

【问题讨论】:

你尝试过这些分类器吗?他们可能会处理 unicode 数据。 我使用了这个github.com/codebox/bayesian-classifier@BrenBarn,但没有采用 unicode 训练集。导致“找不到文本”错误。 你试过nltk中的朴素贝叶斯吗? NLTK and language detection的可能重复 尝试将此代码调整为语言 ID,github.com/alvations/bayesline ;) 【参考方案1】:

scikit-learn 中的朴素贝叶斯使用数字向量进行操作,(例如)我们可以在一些向量化器之后得到。 对于文本分类我经常使用 TfidfVectorizer:http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html

在构造函数 TfidfVectorizer 的参数中存在下一个参数: 编码:字符串,默认为“utf-8”。 如果给出字节或文件进行分析,则使用此编码进行解码。

你可以使用这个参数并使用你的编码,也可以指定你自己的预处理函数和分析函数(它也很有用)

【讨论】:

【参考方案2】:

我最好使用 scikit-learn 来构建一个语言 ID 系统,就像我之前所做的那样,请参阅 https://github.com/alvations/bayesline。

话虽如此,使用来自NLTK 的简单分类模块和 unicode 数据构建语言 ID 系统是完全可能的。

不需要对 NLTK 代码做任何特别的事情,它们可以按原样使用。(这可能对您如何在 NLTK 中构建分类器有用:@987654322 @)

现在表明完全可以使用开箱即用的 NLTK 来获取带有 unicode 数据的语言 ID,见下文

首先对于语言ID,在特征提取中使用unicode字符特征和字节码存在细微差别:

from nltk.corpus import indian

# NLTK reads the corpus as bytecodes.
hindi = " ".join(indian.words('hindi.pos'))
bangla = " ".join(indian.words('bangla.pos'))
marathi = " ".join(indian.words('marathi.pos'))
telugu = " ".join(indian.words('telugu.pos'))

# Prints out first 10 bytes (including spaces).
print 'hindi:', hindi[:10]
print 'bangla:', bangla[:10]
print 'marathi:', marathi[:10]
print 'telugu:', telugu[:10]
print

# Converts bytecodes to utf8.
hindi = hindi.decode('utf8')
bangla = bangla.decode('utf8')
marathi = marathi.decode('utf8')
telugu = telugu.decode('utf8')

# Prints out first 10 unicode char (including spaces).
print 'hindi:', hindi[:10]
print 'bangla:', bangla[:10]
print 'marathi:', marathi[:10]
print 'telugu:', telugu[:10]
print

[出]:

hindi: पूर
bangla: মহি
marathi: '' सन
telugu: 4 . ఆడ

hindi: पूर्ण प्रत
bangla: মহিষের সন্
marathi: '' सनातनवा
telugu: 4 . ఆడిట్ 

现在您看到了使用字节码和 unicode 的区别,让我们训练一个 taggaer。

from nltk import NaiveBayesClassifier as nbc

# Allocate some sort of labels for the data.
training = [(hindi, 'hi'), (bangla, 'ba'), (marathi, 'ma'), (telugu, 'te')]
# This is how you can extract ngrams
print ngrams(telugu[:10], 2)
print
print ngrams(hindi[:10], 3)
print

vocabulary = set(chain(*[ngrams(txt, 2) for txt,tag in training]))

feature_set = [(i:(i in ngrams(sentence, 2)) for i in vocabulary,tag) for sentence, tag in training]

classifer = nbc.train(feature_set)

test1 = u'पूर्ण प्रत' # hindi
test2 = u'মহিষের সন্' # bangla
test3 = u'सनातनवा' # marathi
test4 = u'ఆడిట్ ' # telugu

for testdoc in [test1, test2, test3, test4]:
    featurized_test_sent =  i:(i in ngrams(testdoc,2)) for i in vocabulary
    print "test sent:", testdoc
    print "tag:", classifer.classify(featurized_test_sent)
    print

[出]:

[(u'4', u' '), (u' ', u'.'), (u'.', u' '), (u' ', u'\u0c06'), (u'\u0c06', u'\u0c21'), (u'\u0c21', u'\u0c3f'), (u'\u0c3f', u'\u0c1f'), (u'\u0c1f', u'\u0c4d'), (u'\u0c4d', u' ')]

[(u'\u092a', u'\u0942', u'\u0930'), (u'\u0942', u'\u0930', u'\u094d'), (u'\u0930', u'\u094d', u'\u0923'), (u'\u094d', u'\u0923', u' '), (u'\u0923', u' ', u'\u092a'), (u' ', u'\u092a', u'\u094d'), (u'\u092a', u'\u094d', u'\u0930'), (u'\u094d', u'\u0930', u'\u0924')]

test sent: पूर्ण प्रत
tag: hi

test sent: মহিষের সন্
tag: ba

test sent: सनातनवा
tag: ma

test sent: ఆడిట్ 
tag: te

这是完整的代码:

# -*- coding: utf-8 -*-

from itertools import chain
from nltk.corpus import indian
from nltk.util import ngrams
from nltk import NaiveBayesClassifier as nbc


# NLTK reads the corpus as bytecodes.
hindi = " ".join(indian.words('hindi.pos'))
bangla = " ".join(indian.words('bangla.pos'))
marathi = " ".join(indian.words('marathi.pos'))
telugu = " ".join(indian.words('telugu.pos'))

# Prints out first 10 bytes (including spaces).
print 'hindi:', hindi[:10]
print 'bangla:', bangla[:10]
print 'marathi:', marathi[:10]
print 'telugu:', telugu[:10]
print

# Converts bytecodes to utf8.
hindi = hindi.decode('utf8')
bangla = bangla.decode('utf8')
marathi = marathi.decode('utf8')
telugu = telugu.decode('utf8')

# Prints out first 10 unicode char (including spaces).
print 'hindi:', hindi[:10]
print 'bangla:', bangla[:10]
print 'marathi:', marathi[:10]
print 'telugu:', telugu[:10]
print

# Allocate some sort of labels for the data.
training = [(hindi, 'hi'), (bangla, 'ba'), (marathi, 'ma'), (telugu, 'te')]
# This is how you can extract ngrams
print ngrams(telugu[:10], 2)
print
print ngrams(hindi[:10], 3)
print

vocabulary = set(chain(*[ngrams(txt, 2) for txt,tag in training]))

feature_set = [(i:(i in ngrams(sentence, 2)) for i in vocabulary,tag) for sentence, tag in training]

classifer = nbc.train(feature_set)

test1 = u'पूर्ण प्रत' # hindi
test2 = u'মহিষের সন্' # bangla
test3 = u'सनातनवा' # marathi
test4 = u'ఆడిట్ ' # telugu

for testdoc in [test1, test2, test3, test4]:
    featurized_test_sent =  i:(i in ngrams(testdoc,2)) for i in vocabulary
    print "test sent:", testdoc
    print "tag:", classifer.classify(featurized_test_sent)
    print

【讨论】:

虽然它正是我想要的。我可以从这里把它向前推进。【参考方案3】:

这个问题的表述很糟糕,但有可能是关于语言识别而不是句子分类

如果是这种情况,那么在应用朴素贝叶斯或其他分类器之类的方法之前还有很长的路要走。看看Damir Cavar's LID 使用的字符语法方法,用 Python 实现。

【讨论】:

是的,这与句子分类无关。它是关于可用机器学习模块进行语言识别的。 好的,那么我的建议是阅读这个问题:***.com/questions/3182268/nltk-and-language-detection 基本上,您将在其他地方进行识别,而不是在 NLTK 或 Scikit-learn 中。在处理完 Unicode 和字符图之后,您可以将这些库中的各种统计模型插入到任何识别解决方案的决策函数中。 将查看它并返回这里。

以上是关于用于新语言的基于 python 的朴素基分类器的主要内容,如果未能解决你的问题,请参考以下文章

《机器学习实战》基于朴素贝叶斯分类算法构建文本分类器的Python实现

从Scratch在Python中的朴素贝叶斯分类

如何在 python 的朴素贝叶斯分类器中对用户输入测试集进行分类?

基于Naive Bayes算法的文本分类

用于文本分类的朴素贝叶斯 - Python 2.7 数据结构问题

将朴素贝叶斯分类器保存在内存中