支持向量机 - 使用字数和上下文构建功能

时间:2015-04-12 22:06:25

标签: python svm

此python代码创建的功能可反映给定的推文中是否存在给定的关键字。

#get feature list stored in a file (for reuse)
featureList = getFeatureList('data/sampleTweetFeatureList.txt')

#start extract_features
def extract_features(tweet):
    tweet_words = set(tweet)
    features = {}
    for word in featureList:
        features['contains(%s)' % word] = (word in tweet_words)
    return features
#end

输出看起来像这样:

{
    'contains(arm)': True,             #notice this
    'contains(articles)': False,
    'contains(attended)': False,
    'contains(australian)': False,
    'contains(awfully)': False,
    'contains(bloodwork)': True,       #notice this
    'contains(bombs)': False,
    'contains(cici)': False,
    .....
    'contains(head)': False,
    'contains(heard)': False,
    'contains(hey)': False,
    'contains(hurts)': True,           #notice this
    .....
    'contains(irish)': False,
    'contains(jokes)': False,
    .....
    'contains(women)': False
}

现在,如果功能集还包括(除了上面显示的关键字之外),我该如何构建特征向量:

  1. 给定推文中的字数
  2. 像“地震”这样的特殊关键字的上下文。对于例如现在“日本地震”中的“地震”左右词是“日本”和“现在”。
  3. 编辑:我想弄清楚的是,如何以我获得SVM算法所需的向量的方式捕获这些信息(字数和上下文)?到目前为止,我所拥有的是| featureList |中的向量维度空间。如何扩展它以包括字数和上下文?

1 个答案:

答案 0 :(得分:0)

使用split()获取单词列表,使用len()查找列表中find the number of words in a sentence的项目数量:

word_count = len(tweet.split())

当你需要存储多个值时,例如你的上下文,你可以使用元组,有点像这样:

features['contains(%s)' % word] = (word in tweet_words, previous_word, next_word)

这样地图看起来像这样:

{
    'contains(arm)': (True, 'broken', 'was'),
    'contains(articles)': (False, '', ''),
    ...
}

可以这样枚举:

for feature in features:
    for word, previous, next in features[feature]:
        if word:
            print previous
            print next

原始解决方案中有一个问题:您没有考虑重复的字词。 set()的使用意味着独特的元素。如果您想要保留重复项或地图{},请使用列表[],以便更快地进行查找。

使用类可以让您更轻松地操作数据。我们可以通过使用单词映射到其上下文列表来获得额外的灵活性,而不是单词列表。为什么不在推文中输入单词的位置?

class Tweet(object):
    def __init__(self, tweet):
        self.text= tweet
        self.words = tweet.split()
        self.word_count = len(words)

        # dictionary comprehension - preliminary map of 'word' to empty list
        self.contexts = {word: [] for word in words}

        for idx, word in enumerate(self.words):
            self.contexts[word].append(
                idx,                                                 # idx
                self.words[idx] if idx > 0 else '',                  # previous word
                self.words[idx+1] if idx < self.word_count else '')  # next word

然后你可以用这种方式重写你的功能,虽然重复仍然没有得到处理:

def extract_features(tweet_str):
    tweet = Tweet(tweet_str)
    features = {}
    for word in featureList:
        features['contains(%s)' % word] = (word in tweet.words)
    return features

现在你可以用它做更多的事情:

# enumerate each word, their location and context:
for word in tweet.words:
    location, previous, next = tweet.contexts[word]

# get the word count:
print tweet.word_count

# how many apples?
print len(word.lower() for word in tweet.words if word.startswith('apple'))

# how many apples, again?
print len(tweet.contexts['apples'])  # of course you will miss 'apple' and 'Apples', etc

# did he used the word 'where'?
print 'where' in tweet.words  # note: 'Where' will not match because of capital W