objectivist-ner 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/index.ts +38 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,6 +148,39 @@ ner --relations "Dr. Chen works at MIT and collaborates with Prof. Wright"
|
|
|
148
148
|
|
|
149
149
|
Relations show how entities connect — extracting the "connective tissue" between concepts.
|
|
150
150
|
|
|
151
|
+
You can also categorize relations by class:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
ner --relations --relation-classes "employment,location,causal,professional" \
|
|
155
|
+
"Dr. Chen works at MIT and collaborates with Prof. Wright"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"entities": [
|
|
161
|
+
{ "class": "person", "text": "Dr. Chen" },
|
|
162
|
+
{ "class": "organization", "text": "MIT" },
|
|
163
|
+
{ "class": "person", "text": "Prof. Wright" }
|
|
164
|
+
],
|
|
165
|
+
"relations": [
|
|
166
|
+
{
|
|
167
|
+
"source": "Dr. Chen",
|
|
168
|
+
"target": "MIT",
|
|
169
|
+
"relation": "works at",
|
|
170
|
+
"class": "employment"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"source": "Dr. Chen",
|
|
174
|
+
"target": "Prof. Wright",
|
|
175
|
+
"relation": "collaborates with",
|
|
176
|
+
"class": "professional"
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The `class` field categorizes the relation type (e.g., employment, causal, spatial), allowing you to group and analyze connections by category.
|
|
183
|
+
|
|
151
184
|
## Installation
|
|
152
185
|
|
|
153
186
|
```bash
|
|
@@ -274,6 +307,7 @@ cat article.txt | ner --detect-negation
|
|
|
274
307
|
| `--attr-values <json>` | Enum map for attribute values |
|
|
275
308
|
| `--taxonomy <json>` | Class hierarchy (parent → children) |
|
|
276
309
|
| `--relations` | Extract relations between entities |
|
|
310
|
+
| `--relation-classes <list>` | Allowed relation classes (e.g. employment,causal) |
|
|
277
311
|
| `--resolve` | Resolve coreferences (adds entity_id) |
|
|
278
312
|
| `--detect-negation` | Add assertion field (present/negated/hypothetical) |
|
|
279
313
|
| `--include-confidence` | Add confidence field (low/medium/high) |
|
package/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ interface SchemaFile {
|
|
|
44
44
|
attributes?: string[];
|
|
45
45
|
attrValues?: Record<string, string[]>;
|
|
46
46
|
relations?: string[];
|
|
47
|
+
relationClasses?: string[];
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
// === TAXONOMY HELPERS ===
|
|
@@ -178,6 +179,10 @@ program
|
|
|
178
179
|
'Class hierarchy JSON e.g. {"organism":["animal","plant"]}',
|
|
179
180
|
)
|
|
180
181
|
.option("--relations", "Extract relations between entities")
|
|
182
|
+
.option(
|
|
183
|
+
"--relation-classes <list>",
|
|
184
|
+
"Comma-separated allowed relation classes (e.g. employment,location,causal)",
|
|
185
|
+
)
|
|
181
186
|
.option("--resolve", "Resolve coreferences (group mentions of same entity)")
|
|
182
187
|
.option("--include-confidence", "Include confidence scores per entity")
|
|
183
188
|
.option("--detect-negation", "Detect negated/hypothetical entities")
|
|
@@ -293,6 +298,9 @@ if (opts.taxonomy) {
|
|
|
293
298
|
|
|
294
299
|
const enableRelations = opts.relations || !!schemaFile?.relations;
|
|
295
300
|
const relationTypes: string[] | undefined = schemaFile?.relations || undefined;
|
|
301
|
+
const relationClasses: string[] | undefined = opts.relationClasses
|
|
302
|
+
? opts.relationClasses.split(",").map((s: string) => s.trim())
|
|
303
|
+
: schemaFile?.relationClasses;
|
|
296
304
|
const enableResolve = !!opts.resolve;
|
|
297
305
|
const enableConfidence = !!opts.includeConfidence;
|
|
298
306
|
const enableNegation = !!opts.detectNegation;
|
|
@@ -444,6 +452,23 @@ function buildGrammarSchema() {
|
|
|
444
452
|
|
|
445
453
|
// === BUILD RELATIONS SCHEMA ===
|
|
446
454
|
function buildRelationsSchema() {
|
|
455
|
+
const relationProperties: any = {
|
|
456
|
+
source: { type: "string" },
|
|
457
|
+
target: { type: "string" },
|
|
458
|
+
relation: {
|
|
459
|
+
type: "string",
|
|
460
|
+
...(relationTypes && { enum: relationTypes }),
|
|
461
|
+
},
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// Add class field if relationClasses is specified
|
|
465
|
+
if (relationClasses) {
|
|
466
|
+
relationProperties.class = {
|
|
467
|
+
type: "string",
|
|
468
|
+
enum: relationClasses,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
447
472
|
const relSchema: any = {
|
|
448
473
|
type: "object",
|
|
449
474
|
properties: {
|
|
@@ -452,15 +477,10 @@ function buildRelationsSchema() {
|
|
|
452
477
|
type: "array",
|
|
453
478
|
items: {
|
|
454
479
|
type: "object",
|
|
455
|
-
properties:
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
type: "string",
|
|
460
|
-
...(relationTypes && { enum: relationTypes }),
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
required: ["source", "target", "relation"],
|
|
480
|
+
properties: relationProperties,
|
|
481
|
+
required: relationClasses
|
|
482
|
+
? ["source", "target", "relation", "class"]
|
|
483
|
+
: ["source", "target", "relation"],
|
|
464
484
|
additionalProperties: false,
|
|
465
485
|
},
|
|
466
486
|
},
|
|
@@ -500,10 +520,18 @@ function buildConstraints(): string {
|
|
|
500
520
|
constraints += `\nEvery entity has "entity_id" and "is_canonical" fields. Coreferent mentions share entity_id; exactly one per group has is_canonical:true (the most specific reference). Example: [{"class":"person","text":"Dr. Chen","entity_id":"e1","is_canonical":true,"attributes":{}},{"class":"person","text":"She","entity_id":"e1","is_canonical":false,"attributes":{}}]`;
|
|
501
521
|
}
|
|
502
522
|
if (enableRelations) {
|
|
503
|
-
|
|
523
|
+
let relDesc = `\nAlso extract relations between entities.`;
|
|
524
|
+
if (relationClasses) {
|
|
525
|
+
relDesc += ` Each relation must have a "class" field categorizing the relation type.`;
|
|
526
|
+
}
|
|
527
|
+
relDesc += ` Return {"entities": [...], "relations": [{"source": "entity text", "target": "entity text", "relation": "relation type"${relationClasses ? ', "class": "relation class"' : ""}}]}.`;
|
|
528
|
+
constraints += relDesc;
|
|
504
529
|
if (relationTypes) {
|
|
505
530
|
constraints += ` Allowed relation types: ${relationTypes.join(", ")}.`;
|
|
506
531
|
}
|
|
532
|
+
if (relationClasses) {
|
|
533
|
+
constraints += ` Allowed relation classes: ${relationClasses.join(", ")}.`;
|
|
534
|
+
}
|
|
507
535
|
}
|
|
508
536
|
|
|
509
537
|
return constraints;
|