StandforCorenlp解析依存关系
·
1.下载StandforCorenlp
Overview - CoreNLP 下载并解压。

根据语言进行选择,我这里选择的是English。下载并解压

解压完成后,将这两个文件放入到 ./stanford-corenlp-4.5.9文件夹下面。
2.安装StandforCornlp
配置虚拟环境,安装StandforCornlp,直接pip install,或者使用镜像‘
pip install stanfordcorenlp
pip install stanfordcorenlp -i http://pypi.mirrors.ustc.edu.cn/simple/ --trusted-host pypi.mirrors.ustc.edu.cn
3.数据集
4.测试
文件测试
file = './datasets/raw/semeval14/restaurant_test.raw'
with open(file, 'r') as file:
data = file.readlines()
print(data[0].split('\t'))
print(data[1].split('\t'))
print(data[2].split('\t'))
依存关系解析测试
from stanfordcorenlp import StanfordCoreNLP
import re
# 初始化CoreNLP(确保路径正确)
nlp = StanfordCoreNLP(r'./stanford-corenlp-4.5.9')
# 原始句子和方面词信息(模拟raw格式输入)
raw_sentence = 'the entire staff was extremely accomodating and tended to my every need .'
aspect_terms = [{"term": "staff", "polarity": "postive"}] # 从raw解析得到
# 获取基础数据
tokens = nlp.word_tokenize(raw_sentence)
pos_tags = [tag for _, tag in nlp.pos_tag(raw_sentence)]
# 获取依存关系并转换为目标格式
dependencies = nlp.dependency_parse(raw_sentence)
# 初始化head和deprel数组(长度=token数)
head = [0] * len(tokens) # 默认父节点为0
deprel = ["root"] * len(tokens) # 默认依存关系
# 转换依存关系到目标格式
for dep in dependencies:
relation, gov_idx, dep_idx = dep
current_idx = dep_idx - 1 # 转换为0-based索引
# StanfordCoreNLP的根节点特殊处理
if relation == "ROOT":
head[current_idx] = 0
deprel[current_idx] = "ROOT"
else:
# 父节点索引保持1-based(符合JSON格式)
head[current_idx] = gov_idx
deprel[current_idx] = relation.lower()
# 处理方面词位置
aspects_list = []
for aspect in aspect_terms:
term = aspect["term"]
polarity = aspect["polarity"]
# 对方面词进行分词(确保与句子分词一致)
term_tokens = nlp.word_tokenize(term)
term_len = len(term_tokens)
# 在tokens中查找匹配位置
start_index = -1
for i in range(len(tokens) - term_len + 1):
# 比较token序列(不区分大小写)
if tokens[i:i + term_len] == term_tokens:
start_index = i
break
# 添加到aspects列表
if start_index != -1:
aspects_list.append({
"term": term_tokens,
"from": start_index,
"to": start_index + term_len, # 左闭右开区间
"polarity": polarity
})
# 构建最终JSON对象
json_data = {
"token": tokens,
"pos": pos_tags,
"head": head,
"deprel": deprel,
"aspects": aspects_list
}
nlp.close()
# 打印验证结果
print("Tokens:", json_data["token"])
print("Head:", json_data["head"])
print("Deprel:", json_data["deprel"])
print("Aspects:", json_data["aspects"])
# 完整JSON输出(用于保存)
import json
print("\nComplete JSON:")
print(json.dumps(json_data, indent=2))
5.实现
import os
import json
from stanfordcorenlp import StanfordCoreNLP
# 初始化Stanford CoreNLP
nlp = StanfordCoreNLP(r'./stanford-corenlp-4.5.9')
def convert_polarity(polarity_str):
"""将数字极性转换为字符串标签"""
polarity_map = {
'1': 'positive',
'0': 'neutral',
'-1': 'negative'
}
return polarity_map.get(polarity_str.strip(), 'neutral')
def find_aspect_position(tokens, aspect_term):
"""在分词后的句子中查找方面词的位置"""
term_tokens = nlp.word_tokenize(aspect_term)
term_len = len(term_tokens)
# 尝试精确匹配
for i in range(len(tokens) - term_len + 1):
if tokens[i:i + term_len] == term_tokens:
return i, i + term_len
# 尝试小写匹配(处理大小写不一致)
lower_tokens = [t.lower() for t in tokens]
lower_term = [t.lower() for t in term_tokens]
for i in range(len(tokens) - term_len + 1):
if lower_tokens[i:i + term_len] == lower_term:
return i, i + term_len
# 尝试去除标点匹配
clean_tokens = [t.strip(".,!?;:'\"") for t in tokens]
clean_term = [t.strip(".,!?;:'\"") for t in term_tokens]
for i in range(len(tokens) - term_len + 1):
if clean_tokens[i:i + term_len] == clean_term:
return i, i + term_len
# 如果仍然找不到,返回None
return None, None
def process_line(line):
"""处理单行数据(包含三行信息)"""
parts = line.strip().split('\t')
if len(parts) != 3:
return None
raw_sentence, aspect_term, polarity = parts
# 构建完整句子(替换$T$)
full_sentence = raw_sentence.replace('$T$', aspect_term)
# 获取基础数据
tokens = nlp.word_tokenize(full_sentence)
pos_tags = [tag for _, tag in nlp.pos_tag(full_sentence)]
# 获取依存关系并转换为目标格式
dependencies = nlp.dependency_parse(full_sentence)
# 初始化head和deprel数组
head = [0] * len(tokens)
deprel = ["root"] * len(tokens) # 默认值
# 转换依存关系
for dep in dependencies:
relation, gov_idx, dep_idx = dep
current_idx = dep_idx - 1 # 转换为0-based索引
if relation == "ROOT":
head[current_idx] = 0
deprel[current_idx] = "ROOT"
else:
head[current_idx] = gov_idx
deprel[current_idx] = relation.lower()
# 处理方面词位置
start_index, end_index = find_aspect_position(tokens, aspect_term)
if start_index is None:
print(f"Warning: Could not find aspect term '{aspect_term}' in sentence: {full_sentence}")
return None
# 构建JSON对象
return {
"token": tokens,
"pos": pos_tags,
"head": head,
"deprel": deprel,
"aspects": [{
"term": nlp.word_tokenize(aspect_term),
"from": start_index,
"to": end_index,
"polarity": convert_polarity(polarity)
}]
}
def convert_raw_to_json(input_path, output_path):
"""将原始数据文件转换为JSON格式"""
if not os.path.exists(input_path):
print(f"Error: Input file {input_path} not found")
return
# 修复编码问题:显式指定UTF-8编码
with open(input_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 每三行处理为一个样本
json_data = []
for i in range(0, len(lines), 3):
if i + 2 >= len(lines):
break
# 合并三行数据为一个字符串表示
combined_line = f"{lines[i].strip()}\t{lines[i + 1].strip()}\t{lines[i + 2].strip()}"
result = process_line(combined_line)
if result:
json_data.append(result)
print(result)
# 保存结果,同样使用UTF-8编码
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(json_data, f, indent=2, ensure_ascii=False) # ensure_ascii=False保留非ASCII字符
print(f"Successfully converted {len(json_data)} samples to {output_path}")
# 执行转换
convert_raw_to_json('./datasets/raw/semeval16/restaurant_test.raw', './Restaurant16/test.json')
# 关闭CoreNLP连接
nlp.close()
更多推荐

所有评论(0)