Dela via


Detaljerat exempel på former och projektioner i ett kunskapslager

Den här artikeln innehåller ett detaljerat exempel som kompletterar övergripande begrepp och syntaxbaserade artiklar genom att gå igenom de formnings- och projektionssteg som krävs för att helt uttrycka utdata från en omfattande kompetensuppsättning i ett kunskapslager.

Om dina programkrav kräver flera kunskaper och projektioner kan det här exemplet ge dig en bättre uppfattning om hur former och projektioner korsar varandra.

Konfigurera exempeldata

Exempeldokument ingår inte i samlingen Projektioner, men ai-berikande demodatafiler innehåller text och bilder som fungerar med de projektioner som beskrivs i det här exemplet.

Skapa en blobcontainer i Azure Storage och ladda upp alla 14 objekt.

Kopiera en anslutningssträng i Azure Storage.

Du kan använda projections.rest filen för att köra exemplen i den här artikeln.

Exempel på kompetensuppsättning

Om du vill förstå beroendet mellan former och projektioner läser du följande kompetensuppsättning som skapar berikat innehåll. Den här kompetensuppsättningen bearbetar både råa bilder och text och producerar utdata som ska refereras i former och projektioner.

Var uppmärksam på kunskapsutdata (targetNames). Utdata som skrivs till det berikade dokumentträdet refereras till i projektioner och i former (via Shaper-kunskaper).

{
    "name": "projections-demo-ss",
    "description": "Skillset that enriches blob data found in "merged_content". The enrichment granularity is a document.",
    "skills": [
        {
            "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
            "name": "#1",
            "description": null,
            "context": "/document/merged_content",
            "categories": [
                "Person",
                "Quantity",
                "Organization",
                "URL",
                "Email",
                "Location",
                "DateTime"
            ],
            "defaultLanguageCode": "en",
            "minimumPrecision": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "persons",
                    "targetName": "people"
                },
                {
                    "name": "organizations",
                    "targetName": "organizations"
                },
                {
                    "name": "locations",
                    "targetName": "locations"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
            "name": "#2",
            "description": null,
            "context": "/document/merged_content",
            "defaultLanguageCode": "en",
            "maxKeyPhraseCount": null,
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                },
                {
                    "name": "languageCode",
                    "source": "/document/language"
                }
            ],
            "outputs": [
                {
                    "name": "keyPhrases",
                    "targetName": "keyphrases"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
            "name": "#3",
            "description": null,
            "context": "/document",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/merged_content"
                }
            ],
            "outputs": [
                {
                    "name": "languageCode",
                    "targetName": "language"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Text.MergeSkill",
            "name": "#4",
            "description": null,
            "context": "/document",
            "insertPreTag": " ",
            "insertPostTag": " ",
            "inputs": [
                {
                    "name": "text",
                    "source": "/document/content"
                },
                {
                    "name": "itemsToInsert",
                    "source": "/document/normalized_images/*/text"
                },
                {
                    "name": "offsets",
                    "source": "/document/normalized_images/*/contentOffset"
                }
            ],
            "outputs": [
                {
                    "name": "mergedText",
                    "targetName": "merged_content"
                }
            ]
        },
        {
            "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
            "name": "#5",
            "description": null,
            "context": "/document/normalized_images/*",
            "textExtractionAlgorithm": "printed",
            "lineEnding": "Space",
            "defaultLanguageCode": "en",
            "detectOrientation": true,
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                }
            ],
            "outputs": [
                {
                    "name": "text",
                    "targetName": "text"
                },
                {
                    "name": "layoutText",
                    "targetName": "layoutText"
                }
            ]
        }
    ],
    "cognitiveServices": {
        "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
        "description": "An Azure AI services resource in the same region as Search.",
        "key": "<Azure AI services All-in-ONE KEY>"
    },
    "knowledgeStore": null
}

Exempel på formningsfärdighet

En Formningsfärdighet är ett verktyg för att arbeta med befintligt berikat innehåll i stället för att skapa nytt berikat innehåll. Genom att lägga till en formare i en kompetensuppsättning kan du skapa en anpassad form som du kan projicera i tabell- eller bloblagring. Utan en anpassad form är projektioner begränsade till att referera till en enskild nod (en projektion per utdata), som inte är lämplig för tabeller. När du skapar en anpassad form aggregeras olika element till en ny logisk helhet som kan projiceras som en enda tabell, eller segmenteras och distribueras över en samling tabeller.

I det här exemplet kombinerar den anpassade formen blobmetadata och identifierade entiteter och nyckelfraser. Den anpassade formen heter projectionShape och är överordnad under /document.

Ett syfte med formningen är att se till att alla berikningsnoder uttrycks i välformulerad JSON, vilket krävs för att projicera in i kunskapsarkivet. Detta gäller särskilt när ett berikande träd innehåller noder som inte är välformulerade JSON (till exempel när en berikning är överordnad till en primitiv som en sträng).

Observera de två sista noderna KeyPhrases och Entities. Dessa omsluts till ett giltigt JSON-objekt med sourceContext. Detta krävs som keyphrases och entities är berikande för primitiver och måste konverteras till giltig JSON innan de kan projiceras.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForTables",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_content_type",
            "source": "/document/metadata_storage_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_storage_path",
            "source": "/document/metadata_storage_path",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "metadata_content_type",
            "source": "/document/metadata_content_type",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "Entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        }
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "projectionShape"
        }
    ]
}

Lägga till shapers i en kompetensuppsättning

Exempelkompetensuppsättningen som introducerades i början av den här artikeln innehöll inte Shaper-färdigheten, men Shaper-färdigheter hör hemma i en kompetensuppsättning och placeras ofta mot slutet.

Inom en kompetensuppsättning kan en Shaper-färdighet se ut så här:

{
    "name": "projections-demo-ss",
    "skills": [
        {
            <Shaper skill goes here>
            }
        ],
    "cognitiveServices":  "A key goes here",
    "knowledgeStore": []
}  

Projicera till tabeller

Med hjälp av exemplen ovan finns det en känd mängd berikanden och dataformer som kan refereras i tabellprojektioner. I tabellprojektionen nedan definieras tre tabeller genom att egenskaperna tableNameoch source generatedKeyName anges.

Alla tre tabellerna kommer att relateras via genererade nycklar och av den delade överordnade /document/projectionShape.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "tblDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "tblKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases/*"
                },
                {
                    "tableName": "tblEntities",
                    "generatedKeyName": "Entityid",
                    "source": "/document/projectionShape/Entities/*"
                }
            ],
            "objects": [],
            "files": []
        }
    ]
}

Testa ditt arbete

Du kan kontrollera projektionsdefinitioner genom att följa dessa steg:

  1. Ange egenskapen för kunskapsarkivet till ett giltigt V2-lagringskonto storageConnectionString för generell användning anslutningssträng.

  2. Uppdatera kompetensuppsättningen genom att utfärda PUT-begäran.

  3. När du har uppdaterat kunskapsuppsättningen kör du indexeraren.

Nu har du en fungerande projektion med tre tabeller. Om du importerar dessa tabeller till Power BI bör Power BI identifiera relationerna.

Innan vi går vidare till nästa exempel ska vi gå tillbaka till aspekter av tabellprojektionen för att förstå mekaniken för segmentering och relaterade data.

Dela in en tabell i flera underordnade tabeller

Segmentering är en teknik som delar upp en hel konsoliderad form i komponenter. Resultatet består av separata men relaterade tabeller som du kan arbeta med individuellt.

I exemplet projectionShape är den konsoliderade formen (eller berikande noden). I projektionsdefinitionen projectionShape delas in i ytterligare tabeller, vilket gör att du kan hämta delar av formen och keyPhrases Entities. I Power BI är detta användbart eftersom flera entiteter och keyPhrases är associerade med varje dokument, och du får fler insikter om du kan se entiteter och keyPhrases som kategoriserade data.

Segmentering genererar implicit en relation mellan de överordnade och underordnade tabellerna med hjälp av generatedKeyName i den överordnade tabellen för att skapa en kolumn med samma namn i den underordnade tabellen.

Namnge relationer

Egenskaperna generatedKeyName och referenceKeyName används för att relatera data mellan tabeller eller till och med mellan projektionstyper. Varje rad i den underordnade tabellen har en egenskap som pekar tillbaka till den överordnade tabellen. Namnet på kolumnen eller egenskapen i det underordnade objektet är referenceKeyName från den överordnade. När inte referenceKeyName tillhandahålls, standardinställningen för tjänsten från generatedKeyName den överordnade tjänsten.

Power BI förlitar sig på dessa genererade nycklar för att identifiera relationer i tabellerna. Om du behöver kolumnen i den underordnade tabellen med namnet annorlunda anger du egenskapen i referenceKeyName den överordnade tabellen. Ett exempel är att ange generatedKeyName som ID i tabellen tblDocument och referenceKeyName som DocumentID. Detta skulle resultera i kolumnen i tabellerna tblEntities och tblKeyPhrases som innehåller dokument-ID:t med namnet DocumentID.

Projicera blobdokument

Objektprojektioner är JSON-representationer av berikningsträdet som kan hämtas från valfri nod. Jämfört med tabellprojektioner är objektprojektioner enklare att definiera och används när hela dokument projiceras. Objektprojektioner är begränsade till en enda projektion i en container och kan inte segmenteras.

Om du vill definiera en objektprojektion använder du matrisen objects i projektionsegenskapen.

Källan är sökvägen till en nod i berikningsträdet som är projektionens rot. Även om det inte krävs är nodsökvägen vanligtvis utdata från en Shaper-färdighet. Det beror på att de flesta färdigheter inte matar ut giltiga JSON-objekt på egen hand, vilket innebär att någon form av formning är nödvändig. I många fall kan samma Shaper-färdighet som skapar en tabellprojektion användas för att generera en objektprojektion. Alternativt kan källan också ställas in på en nod med en infogad formning för att tillhandahålla strukturen.

Målet är alltid en blobcontainer.

I följande exempel projiceras enskilda hotelldokument, ett hotelldokument per blob, till en container med namnet hotels.

"knowledgeStore": {
  "storageConnectionString": "an Azure storage connection string",
  "projections" : [
    {
      "tables": [ ]
    },
    {
      "objects": [
        {
        "storageContainer": "hotels",
        "source": "/document/objectprojection",
        }
      ]
    },
    {
        "files": [ ]
    }
  ]
}

Källan är utdata från en Shaper-färdighet med namnet "objectprojection". Varje blob har en JSON-representation av varje fältindata.

    {
      "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
      "name": "#3",
      "description": null,
      "context": "/document",
      "inputs": [
        {
          "name": "HotelId",
          "source": "/document/HotelId"
        },
        {
          "name": "HotelName",
          "source": "/document/HotelName"
        },
        {
          "name": "Category",
          "source": "/document/Category"
        },
        {
          "name": "keyPhrases",
          "source": "/document/HotelId/keyphrases/*"
        },
      ],
      "outputs": [
        {
          "name": "output",
          "targetName": "objectprojection"
        }
      ]
    }

Projicera en bildfil

Filprojektioner är alltid binära, normaliserade bilder, där normalisering refererar till potentiell storleksändring och rotation för användning vid körning av kompetensuppsättningar. Filprojektioner, som liknar objektprojektioner, skapas som blobar i Azure Storage och innehåller avbildningen.

Om du vill definiera en filprojektion använder du matrisen files i projektionsegenskapen.

Källan är alltid /document/normalized_images/*. Filprojektioner fungerar bara på normalized_images samlingen. Varken indexerare eller en kompetensuppsättning passerar den ursprungliga icke-normaliserade avbildningen.

Målet är alltid en blobcontainer med ett mappprefix för det base64-kodade värdet för dokument-ID:t. Filprojektioner kan inte dela samma container som objektprojektioner och behöver projiceras i en annan container.

I följande exempel projiceras alla normaliserade bilder som extraherats från dokumentnoden i ett berikat dokument till en container med namnet myImages.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [ ],
            "objects": [ ],
            "files": [
                {
                    "storageContainer": "myImages",
                    "source": "/document/normalized_images/*"
                }
            ]
        }
    ]
}

Projicera till flera typer

Ett mer komplext scenario kan kräva att du projicerar innehåll mellan projektionstyper. Du kan till exempel projicera nyckelfraser och entiteter till tabeller, spara OCR-resultat av text och layouttext som objekt och sedan projicera bilderna som filer.

Steg för flera projektionstyper:

  1. Skapa en tabell med en rad för varje dokument.
  2. Skapa en tabell som är relaterad till dokumenttabellen med varje nyckelfras identifierad som en rad i den här tabellen.
  3. Skapa en tabell som är relaterad till dokumenttabellen med varje entitet identifierad som en rad i den här tabellen.
  4. Skapa en objektprojektion med layouttexten för varje bild.
  5. Skapa en filprojektion som projicerar varje extraherad bild.
  6. Skapa en korsreferenstabell som innehåller referenser till dokumenttabellen, objektprojektion med layouttexten och filprojektionen.

Formdata för korsprojektion

Om du vill hämta de former som behövs för dessa projektioner börjar du med att lägga till en ny Formningsfärdighet som skapar ett format objekt med namnet crossProjection.

{
    "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
    "name": "ShaperForCrossProjection",
    "description": null,
    "context": "/document",
    "inputs": [
        {
            "name": "metadata_storage_name",
            "source": "/document/metadata_storage_name",
            "sourceContext": null,
            "inputs": []
        },
        {
            "name": "keyPhrases",
            "source": null,
            "sourceContext": "/document/merged_content/keyphrases/*",
            "inputs": [
                {
                    "name": "KeyPhrases",
                    "source": "/document/merged_content/keyphrases/*"
                }

            ]
        },
        {
            "name": "entities",
            "source": null,
            "sourceContext": "/document/merged_content/entities/*",
            "inputs": [
                {
                    "name": "Entities",
                    "source": "/document/merged_content/entities/*/name"
                }

            ]
        },
        {
            "name": "images",
            "source": null,
            "sourceContext": "/document/normalized_images/*",
            "inputs": [
                {
                    "name": "image",
                    "source": "/document/normalized_images/*"
                },
                {
                    "name": "layoutText",
                    "source": "/document/normalized_images/*/layoutText"
                },
                {
                    "name": "ocrText",
                    "source": "/document/normalized_images/*/text"
                }
                ]
        }
 
    ],
    "outputs": [
        {
            "name": "output",
            "targetName": "crossProjection"
        }
    ]
}

Definiera tabell-, objekt- och filprojektioner

Från det konsoliderade korsprojektobjektet delar du upp objektet i flera tabeller, avbildar OCR-utdata som blobar och sparar sedan bilden som filer (även i Blob Storage).

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
            {
            "tables": [
                {
                    "tableName": "crossDocument",
                    "generatedKeyName": "Id",
                    "source": "/document/crossProjection"
                },
                {
                    "tableName": "crossEntities",
                    "generatedKeyName": "EntityId",
                    "source": "/document/crossProjection/entities/*"
                },
                {
                    "tableName": "crossKeyPhrases",
                    "generatedKeyName": "KeyPhraseId",
                    "source": "/document/crossProjection/keyPhrases/*"
                },
                {
                    "tableName": "crossReference",
                    "generatedKeyName": "CrossId",
                    "source": "/document/crossProjection/images/*"
                }
                    
            ],
            "objects": [
                {
                    "storageContainer": "crossobject",
                    "generatedKeyName": "crosslayout",
                    "source": null,
                    "sourceContext": "/document/crossProjection/images/*/layoutText",
                    "inputs": [
                        {
                            "name": "OcrLayoutText",
                            "source": "/document/crossProjection/images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": [
                {
                    "storageContainer": "crossimages",
                    "generatedKeyName": "crossimages",
                    "source": "/document/crossProjection/images/*/image"
                }
            ]
        }
    ]
}

Objektprojektioner kräver ett containernamn för varje projektion. Objektprojektioner och filprojektioner kan inte dela en container.

Relationer mellan tabell-, objekt- och filprojektioner

Det här exemplet visar också en annan funktion i projektioner. Genom att definiera flera typer av projektioner i samma projektionsobjekt, finns det en relation som uttrycks inom och över de olika typerna (tabeller, objekt, filer). På så sätt kan du börja med en tabellrad för ett dokument och hitta all OCR-text för bilderna i dokumentet i objektprojektionen.

Om du inte vill ha data relaterade definierar du projektionerna i olika projektionsgrupper. Följande kodfragment resulterar till exempel i att tabellerna är relaterade, men utan relationer mellan tabellerna och objektprojektionerna (OCR-text).

Projektionsgrupper är användbara när du vill projicera samma data i olika former för olika behov. Till exempel en projektionsgrupp för Power BI-instrumentpanelen och en annan projektionsgrupp för att samla in data som används för att träna en maskininlärningsmodell omsluten i en anpassad färdighet.

När du skapar projektioner av olika typer genereras fil- och objektprojektioner först och sökvägarna läggs till i tabellerna.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [
                {
                    "tableName": "unrelatedDocument",
                    "generatedKeyName": "Documentid",
                    "source": "/document/projectionShape"
                },
                {
                    "tableName": "unrelatedKeyPhrases",
                    "generatedKeyName": "KeyPhraseid",
                    "source": "/document/projectionShape/keyPhrases"
                }
            ],
            "objects": [
                
            ],
            "files": []
        }, 
        {
            "tables": [],
            "objects": [
                {
                    "storageContainer": "unrelatedocrtext",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/text",
                    "inputs": [
                        {
                            "name": "ocrText",
                            "source": "/document/normalized_images/*/text"
                        }
                    ]
                },
                {
                    "storageContainer": "unrelatedocrlayout",
                    "source": null,
                    "sourceContext": "/document/normalized_images/*/layoutText",
                    "inputs": [
                        {
                            "name": "ocrLayoutText",
                            "source": "/document/normalized_images/*/layoutText"
                        }
                    ]
                }
            ],
            "files": []
        }
    ]
}

Nästa steg

Exemplet i den här artikeln visar vanliga mönster för hur du skapar projektioner. Nu när du har en god förståelse för begreppen är du bättre rustad för att skapa prognoser för ditt specifika scenario.