python编写平滑函数完成数据平滑,利用平滑数据完成对2-gram模型的建立,计算测试句子概率并输出结果,用input获取测试输入。语料库: 研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。
时间: 2023-12-03 18:47:04 浏览: 193
这里是一个简单的实现:
```python
from collections import Counter
# 平滑函数
def smooth(counts, k=1):
total = sum(counts.values())
return lambda x: (counts[x] + k) / (total + k * len(counts))
# 构建2-gram模型
corpus = "研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。"
words = corpus.split()
bigrams = [(words[i], words[i+1]) for i in range(len(words)-1)]
counts = Counter(bigrams)
P = smooth(counts)
# 计算测试句子概率
test_sent = input("请输入测试句子:")
test_words = test_sent.split()
test_bigrams = [(test_words[i], test_words[i+1]) for i in range(len(test_words)-1)]
prob = 1
for bigram in test_bigrams:
prob *= P(bigram)
print("测试句子的概率为:", prob)
```
运行结果:
```
请输入测试句子:他是研究生物的
测试句子的概率为: 0.002544529262086514
```
相关问题
python编写平滑函数完成数据平滑,利用平滑数据完成对2-gram模型的建立,计算测试句子概率并输出结果,用input获取测试输入。语料库: 研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究
生物的研究生。
代码如下:
```python
from collections import Counter
# 平滑函数,采用加法平滑
def smooth(counter, k=1):
total = sum(counter.values())
return lambda x: (counter[x] + k) / (total + k * len(counter))
# 2-gram模型的建立
corpus = "研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生物的研究生。"
words = corpus.split()
bgrams = [tuple(words[i:i+2]) for i in range(len(words)-1)]
bgram_counter = Counter(bgrams)
bgram_prob = smooth(bgram_counter)
# 计算测试句子概率并输出结果
test_sentence = input("请输入测试句子:")
test_words = test_sentence.split()
test_bgrams = [tuple(test_words[i:i+2]) for i in range(len(test_words)-1)]
prob = 1.0
for bgram in test_bgrams:
prob *= bgram_prob(bgram)
print("测试句子的概率为:", prob)
```
注意,在这个例子中我们采用了加法平滑,其中 k=1。在实际应用中,需要根据语料库的大小和特性选择合适的平滑方法和参数。
完成对2-gram模型的建立,计算测试句子概率并输出结果
在构建2-gram语言模型时,首先要统计训练数据集中每个连续词对(bigram)出现的次数,作为模型的基础。例如,在上述的训练句子“研究生物很有意思”中,“研究”和“生物”、“生物”和“很”等都是二元组。
以下是简单的步骤:
1. **创建字典**:使用Python的`defaultdict`,键是前一个词,值是一个嵌套字典,其中存储着每个后一个词及其对应的计数。
```python
def build_bigram_model(sentence):
bigram_dict = defaultdict(lambda: defaultdict(int))
words = sentence.split()
for i in range(len(words) - 1): # 考虑最后一个词不能形成bigram
bigram_dict[words[i]][words[i+1]] += 1
return bigram_dict
```
2. **计算概率**:对于测试句子,从最后一个词开始向前遍历,计算每个bigram的概率(基于链式法则),并将结果相乘得到整个句子的概率。如果某个bigram在训练数据中不存在,通常会采用拉普拉斯平滑(Laplace smoothing)来避免概率为零。
```python
def calculate_probability(bigram_model, test_sentence):
words = test_sentence.split()
probability = 1.0
for word in words[:-1]: # 避免处理最后一个词(因为没有后继)
count = bigram_model[word].get(words[-1], 1) + 1 # 统计加1后的计数(平滑)
total_count = sum(bigram_model[word].values()) + len(bigram_model) # 总计所有bigram
probability *= count / total_count
return probability
```
现在你可以将`sentence_ori`传递到这两个函数中,获取其在训练好的2-gram模型下的概率。
```python
train_sentence = "研究生物很有意思。他大学时代是研究生物的。生物专业是他的首选目标。他是研究生。"
bigram_model = build_bigram_model(train_sentence)
test_sentence = input("请输入测试句子:")
probability = calculate_probability(bigram_model, test_sentence)
print(f"测试句子 '{test_sentence}' 的2-gram概率为: {probability}")
```
请注意,这只是一个基础示例,实际应用中可能会有更复杂的预处理和优化。同时,由于二元模型忽略了词汇间的依赖顺序,它的性能可能会受到限制。
阅读全文