지식 그래프의 개념은 보다 지능적인 검색 엔진 구현을 목표로 2012년 Google에서 처음 제안되었으며, 2013년 이후 학계와 업계에서 대중화되기 시작했습니다. 현재 인공 지능 기술의 급속한 발전으로 지식 그래프는 검색, 추천, 광고, 위험 제어, 지능형 일정 관리, 음성 인식, 로봇 및 기타 분야에서 널리 사용되고 있습니다.
인공지능의 핵심 기술로, 지식 그래프는 방대한 학습 데이터와 대규모 컴퓨팅 능력에 의존하여 딥러닝의 문제를 완화할 수 있으며 다양한 다운스트림 작업에 광범위하게 적용할 수 있습니다. 그래서 전 세계의 대형 인터넷 기업들은 자체 지식 그래프를 적극적으로 전개하고 있습니다.
예를 들어, Facebook은 2014년에 소셜 네트워크에서 지능형 검색에 사용된 Open Graph를 출시했으며, Baidu는 2015년에 검색, 보조 및 toB 비즈니스 시나리오에 주로 사용된 지식 그래프를 출시했습니다. 프런트엔드 쇼핑 가이드에 사용된 제품 지식 그래프를 출시했습니다. 플랫폼 거버넌스 및 지능형 질문 및 답변 서비스에서 핵심 역할을 합니다. Tencent가 2017년 출시한 Tencent Cloud 지식 그래프는 금융 검색, 기업 위험 예측 및 기타 시나리오: Meituan이 2018년에 출시한 Meituan Brain Knowledge Graph는 이미 지능형 검색 추천, 지능형 판매자 운영 등 여러 비즈니스에서 구현되었습니다.
현재 도메인 맵은 주로 전자상거래, 의료, 금융 등의 비즈니스 분야에 집중되어 있으나 의미 네트워크 구축 및 구축에 대한 체계적인 지침이 부족합니다. 자동차 지식에 대한 지식 지도입니다. 이 기사에서는 자동차 분야의 지식을 예로 들어 자동차 시리즈, 모델, 딜러, 제조업체, 브랜드 등과 같은 엔터티 및 관계에 중점을 두고 처음부터 도메인 맵을 구축하기 위한 아이디어를 제공하고 단계 및 세부 사항을 자세히 설명합니다. 지식 맵을 구축하는 방법에 대해 설명하고 이 맵을 기반으로 하는 몇 가지 일반적인 응용 프로그램을 소개합니다.
그 중 데이터 소스는 오토홈 웹사이트입니다. 오토홈은 쇼핑 가이드, 정보, 평가, 입소문 등 여러 섹션으로 구성된 자동차 서비스 플랫폼입니다. 보기, 구매, 사용 차원에서 지식 그래프를 구축하여 자동차 중심의 콘텐츠를 구성 및 마이닝하고, 풍부한 지식 정보를 제공하고 관심분야를 구조화하여 정확하게 기술하며, 콜드 스타트, 리콜, 정렬, 표시 등 다차원을 지원합니다. 추천 사용자 수로 비즈니스 개선 효과를 가져옵니다.
지식 그래프는 현실 세계를 의미론적으로 표현한 것으로, 기본 단위는 [엔티티-관계-엔티티]와 [엔티티-속성-속성 값]의 삼중항입니다( Triplet), 개체들은 관계를 통해 서로 연결되어 의미 네트워크를 형성합니다. 그래프 구축에는 더 큰 어려움이 따르겠지만 구축 후에는 데이터 분석, 추천 계산, 해석 가능성 등 다양한 시나리오에서 풍부한 활용 가치를 보여줄 수 있습니다.
구성 과제:
지식 그래프의 통일된 지식 표현: 다중 소스 이종 데이터를 통합하여 통일된 보기를 형성합니다.
아키텍처 다이어그램에 따르면 구체적인 구축 프로세스는 온톨로지 설계, 지식 습득, 지식 웨어하우징, 애플리케이션 서비스 설계 및 사용의 네 단계로 나눌 수 있습니다.
온톨로지는 개념의 집합체로 인정받고 있습니다. 온톨로지 구축은 온톨로지의 정의를 기반으로 지식 그래프의 온톨로지 구조와 지식 프레임워크를 구축하는 것을 의미합니다.
온톨로지를 기반으로 그래프를 작성하는 주요 이유는 다음과 같습니다.
지식 범위에 따라 지식 그래프는 일반 지식 그래프와 도메인 지식 그래프로 나눌 수 있으며, 현재 Google의 Knowledge Graph, Microsoft의 Satori 및 Probase 등 일반 지식 그래프의 사례가 많이 있습니다. 도메인 그래프는 금융, 전자상거래 등 특정 산업의 지도입니다. 일반 그래프는 폭에 더 많은 관심을 기울이고 더 많은 엔터티의 통합을 강조하지만, 도메인 그래프의 지식 범위를 다루는 동안 온톨로지 라이브러리의 도움으로 공리, 규칙 및 제약 조건을 추론하고 사용하는 것은 어렵습니다. 더 작지만 지식의 깊이는 더 깊고 특정 전문 분야에서 구축되는 경우가 많습니다.
정확도 요구 사항을 고려할 때 대표적인 7단계 방법, IDEF5 방법 등 도메인 온톨로지 구성이 수동으로 수행되는 경향이 있습니다. [1] 이러한 유형의 방법의 핵심 아이디어는 기존을 기반으로 한다는 것입니다. 구조화된 데이터, 온톨로지 분석을 수행하고 응용 목적과 범위에 맞는 온톨로지를 요약 및 구성한 후 온톨로지를 최적화 및 검증하여 온톨로지 정의의 첫 번째 버전을 얻습니다. 더 큰 도메인 온톨로지를 얻으려면 비정형 코퍼스에서 이를 보완할 수 있습니다. 수동 구성 프로세스가 상대적으로 크다는 점을 고려하여 이 기사에서는 자동차 분야를 예로 들어 반자동 온톨로지 구성 방법을 제공합니다.
위 방법은 BERT와 같은 딥러닝 기술을 효과적으로 활용하여 말뭉치 간의 내부 관계를 더 잘 포착하고, 클러스터링을 사용하여 온톨로지의 각 모듈을 계층적으로 구성하고, 이를 수동 개입으로 보완하여 빠르고 정확하게 예비 작업을 완료할 수 있습니다. 온톨로지. 아래 그림은 반자동 온톨로지 구성의 개략도입니다.
Protégé 온톨로지 구성 도구 [2]를 사용하여 온톨로지 개념 클래스, 관계, 속성 및 인스턴스를 구성할 수 있습니다. :
이 기사는 자동차 분야의 최상위 온톨로지 개념을 엔터티, 이벤트 및 라벨 시스템의 세 가지 범주로 나눕니다.
1) 엔터티 클래스는 어휘 엔터티 및 자동차 엔터티를 포함하여 특정 의미를 가진 개념적 엔터티를 나타냅니다. 자동차 엔터티에는 조직 및 자동차 개념과 같은 하위 엔터티 유형도 포함됩니다.
2) 라벨 시스템은 각 차원의 라벨 시스템을 나타냅니다. , 콘텐츠 분류, 개념 태그, 관심 태그 및 재료 차원에 설명된 기타 태그를 포함합니다.
3) 이벤트 클래스는 하나 이상의 역할에 대한 객관적인 사실을 나타내며 다양한 유형의 이벤트 간에 진화적인 관계가 있습니다.
Protégé는 다양한 유형의 스키마 구성 파일을 내보낼 수 있으며, 그 중 owl.xml 구조 구성 파일은 아래 그림과 같습니다. 이 구성 파일은 MYSQL 및 JanusGraph에서 직접 로드하여 사용하여 스키마 자동 생성을 실현할 수 있습니다.
지식 그래프의 데이터 소스에는 일반적으로 세 가지 유형의 데이터 구조, 즉 구조화된 데이터, 반구조화된 데이터 및 비구조화된 데이터가 포함됩니다. 다양한 유형의 데이터 소스에 대해 지식 추출과 관련된 핵심 기술과 해결해야 할 기술적 어려움이 다릅니다.
구조화된 데이터는 그래프에 대한 가장 직접적인 지식의 원천입니다. 기본적으로 다른 유형의 데이터에 비해 비용이 가장 저렴하므로 일반적으로 구조화된 데이터는 다음과 같습니다. 그래프 데이터에 우선순위를 부여합니다. 구조화된 데이터에는 여러 데이터베이스 소스가 포함될 수 있으며 일반적으로 모델을 변환하기 위해 ETL 방법을 사용해야 합니다. ETL은 추출(추출), 변환(변환) 및 로드(로드)를 의미합니다. , 이는 모든 작업의 전제이며, 변환은 원래 이질적인 데이터 형식이 통일될 수 있도록 미리 설계된 규칙에 따라 추출된 데이터를 변환하는 것이며, 로딩은 변환된 데이터를 계획대로 데이터로 점진적으로 또는 전체적으로 가져오는 것입니다. 창고.
위의 ETL 프로세스를 통해 다양한 소스의 데이터를 중간 테이블에 넣을 수 있으므로 후속 지식 저장이 용이해집니다. 다음 그림은 자동차 시리즈 엔터티 속성 및 관계 테이블의 예시 다이어그램입니다.
자동차 시리즈 및 브랜드 관계 테이블:
구조적 지식 외에도 데이터, 비정형 데이터에도 엄청난 양의 지식(트리플) 정보가 존재합니다. 일반적으로 기업 내 비정형 데이터의 양은 정형 데이터보다 훨씬 많습니다. 비정형 지식을 채굴하면 지식 그래프가 크게 확장되고 풍부해질 수 있습니다.
삼중 추출 알고리즘의 문제점
문제 1: 단일 도메인 내에서 파일 내용과 형식이 다양하여 주석이 달린 대량의 데이터가 필요하고 비용이 높음
문제 2: 단일 도메인 간의 마이그레이션 효과 도메인 간 확장은 비용이 많이 듭니다. 모델은 기본적으로 특정 산업의 특정 시나리오에 맞게 설계되었습니다.
솔루션 아이디어, Pre-train + Finetune의 패러다임, 사전 훈련: 헤비급 베이스를 통해 모델은 "더 많이 볼 수 있으며" 대규모 및 다중 산업 라벨이 지정되지 않은 문서를 최대한 활용하여 통합된 사전 훈련을 훈련할 수 있습니다. 다양한 유형의 문서를 표현하고 이해하는 모델의 능력을 향상시킵니다.
미세 조정: 가벼운 문서 구조화 알고리즘. Pre-training을 기반으로 경량 문서 중심의 구조화된 알고리즘을 구축하여 라벨링 비용을 절감합니다.
문서에 대한 사전 학습 방법텍스트가 짧으면 Bert는 전체 문서를 완전히 인코딩할 수 있지만 실제 문서는 대부분 더 길다. 추출해야 하는 문자가 1024자를 초과하고 Bert의 인코딩으로 인해 속성 값이 잘립니다.
긴 텍스트 사전 학습 방법의 장단점을 목표로Sparse Attention 방법은 Self-Attention을 최적화하여 O(n2)에서 O(n)까지의 계산을 최적화하여 입력 텍스트 길이를 크게 향상시킵니다. . 일반 모델의 텍스트 길이를 512에서 4096으로 늘렸지만 여전히 잘린 텍스트의 조각화 문제를 완전히 해결할 수는 없습니다. Baidu는 이론적으로 무제한 텍스트를 모델링할 수 있는 Recurrence Transformer 방법을 사용하는 ERNIE-DOC[3]를 제안했습니다. 모델링을 하려면 모든 텍스트 정보를 입력해야 하므로 시간이 많이 소요됩니다.
긴 텍스트를 기반으로 한 위의 두 가지 사전 학습 방법은 공간(Spartial), 시각적(Visual) 및 기타 정보와 같은 문서 특성을 고려하지 않습니다. 또한, 텍스트를 기반으로 디자인된 PretrainTask는 전체적으로 순수 텍스트를 대상으로 디자인되었으며, 문서에 대한 논리적인 구조 디자인을 가지고 있지 않습니다.
위의 단점을 고려하여 문서 사전 학습 모델 DocBert [4], DocBert 모델 디자인은 다음과 같습니다.
사전 학습을 위해 레이블이 지정되지 않은 대규모(수백만 레벨) 문서 데이터를 사용하고 문서의 텍스트 의미(Text), 레이아웃 정보(Layout) 및 시각적 특징(Visual)을 기반으로 자기 지도 학습 작업을 구축하여 활성화 모델은 문서 의미와 구조적 정보를 더 잘 이해합니다.
1.레이아웃 인식 MLM: 마스크 언어 모델에서 텍스트의 위치 및 글꼴 크기 정보를 고려하여 문서 레이아웃 인식 의미론적 이해를 달성합니다.
2.텍스트-이미지 정렬: 문서의 시각적 기능을 융합하고 이미지에서 마스크된 텍스트를 재구성하여 모델이 다양한 텍스트, 레이아웃 및 이미지 모드 간의 정렬 관계를 학습하도록 돕습니다.
3.제목 순열: 문서의 논리적 구조를 이해하는 모델의 능력을 향상시키기 위해 자기 지도 방식으로 제목 재구성 작업을 구성합니다.
4.Sparse Transformer Layers: Sparse Attention 방법을 사용하여 모델의 긴 문서 처리 능력을 향상시킵니다.
구조화된 텍스트와 구조화되지 않은 텍스트에서 트리플을 얻는 것 외에도 Autohome은 자료 및 관심 키워드 태그에 포함된 분류 및 개념 태그도 마이닝합니다. 재료와 차량 엔터티 간의 연관성을 구축하여 자동차 지식 그래프에 새로운 지식을 제공합니다. 다음은 오토홈이 하는 콘텐츠 이해 작업과 사고를 분류, 개념 태그, 관심 단어 태그 관점에서 소개합니다.
분류 시스템은 콘텐츠 설명과 자료의 대략적인 분류의 기초 역할을 합니다. 구축된 통합 콘텐츠 시스템은 수동 정의를 기반으로 하며 AI 모델을 통해 구분됩니다. 분류 방법으로는 분류하기 어려운 데이터에 대한 라벨링을 위해 능동 학습을 사용하며, 분류 효과를 높이기 위해 데이터 강화, 적대적 훈련, 키워드 융합도 사용합니다.
개념 태그의 세분성은 분류 세분성과 관심 단어 태그 사이에 있으며 관심 지점을 설명하는 데 있어 분류 세분성보다 세밀하고 관심 단어보다 완벽합니다. 비전. 라벨 차원이 강화되고 라벨 세분성이 개선되었습니다. 풍부하고 구체적인 자료 태그를 사용하면 태그 기반 모델 최적화를 더 쉽게 검색하고 추천할 수 있으며, 사용자 및 2차 트래픽을 유치하기 위한 태그 홍보에 사용할 수 있습니다. 개념 태그 마이닝은 쿼리와 같은 중요한 데이터에 대한 기계 마이닝 방법과 일반화 분석을 결합하여 수동 검토를 통해 개념 태그 세트를 얻고 분류를 위해 다중 레이블 모델을 사용합니다.
관심 단어 태그는 사용자의 관심 분야에 매핑된 가장 세분화된 태그이며, 다양한 사용자 관심 분야 선호도에 따라 더 나은 개인화 추천을 제공할 수 있습니다. 키워드 마이닝은 Keybert를 포함한 다중 관심 단어 마이닝 방법을 조합하여 키 하위 문자열을 추출하고, TextRank, positionRank, Singlerank, TopicRank, MultipartiteRank 등 + 구문 분석 방법을 결합하여 관심 단어 후보를 생성합니다.
마이닝된 단어는 상대적으로 유사도가 높기 때문에 동의어 식별이 필요하고 수동 효율성도 향상되어야 합니다. 따라서 클러스터링을 통해 자동 의미 유사성 식별도 수행합니다. 클러스터링에 사용되는 기능에는 word2vec, bert emding 및 기타 인공 기능이 포함됩니다. 그런 다음 클러스터링 방법을 사용하고 마지막으로 수동 수정을 통해 오프라인에서 고품질 키워드 배치를 생성했습니다.
세분성이 다르거나 재료 수준에 있는 태그의 경우 먼저 태그를 자동차와 연결해야 합니다. 먼저 제목 기사의 태그를 계산한 다음 제목 기사에서 엔터티를 식별하고 여러 태그(엔티티 의사)를 가져와야 합니다. Tags 를 생성하고, 최종적으로 대량의 말뭉치(corpus)를 기반으로 동시 발생 확률이 높은 레이블을 해당 개체의 레이블로 표시합니다. 위의 세 가지 작업을 통해 우리는 풍부하고 방대한 라벨을 획득했습니다. 이러한 태그를 자동차 시리즈 및 엔터티와 연결하면 자동차 지도가 크게 향상되고 미디어와 사용자의 관심을 끄는 자동차 태그가 구축됩니다.
대규모 훈련 샘플을 사용하면 더 나은 모델 품질을 얻는 방법, 높은 라벨링 비용을 해결하는 방법, 긴 라벨링 주기가 해결해야 할 시급한 문제가 되었습니다. 첫째, 사전 훈련을 위해 레이블이 지정되지 않은 대규모 데이터를 사용하기 위해 준지도 학습을 사용할 수 있습니다. 그런 다음 능동 학습 방법을 사용하여 주석이 달린 데이터의 가치를 극대화하고 주석을 위한 고정보 샘플을 반복적으로 선택합니다. 마지막으로 원격 감독을 사용하여 기존 지식의 가치를 활용하고 작업 간의 상관 관계를 발견할 수 있습니다. 예를 들어, 지도와 제목이 있으면 원격 감독 방법을 사용하여 지도를 기반으로 NER 훈련 데이터를 구성할 수 있습니다.
지식 그래프의 지식은 RDF 구조로 표현되며, 기본 단위는 팩트입니다. 각 사실은 삼중항(S, P, O)이다. 실제 시스템에서는 다양한 저장 방식에 따라 지식 그래프의 저장은 RDF 테이블 구조에 따른 저장과 속성 그래프 구조에 따른 저장으로 나눌 수 있다. 사진 갤러리는 대부분 속성 그래프 구조를 사용하여 저장됩니다. 일반적인 저장 시스템에는 Neo4j, JanusGraph, OritentDB, InfoGrid 등이 있습니다.
JanusGraph를 Neo4J, ArangoDB, OrientDB와 같은 주류 그래프 데이터베이스와 비교하여 마침내 JanusGraph를 프로젝트의 그래프 데이터베이스로 선택했습니다.
JanusGraph[5]는 그래프 데이터베이스 엔진입니다. 컴팩트한 그래프 직렬화, 풍부한 그래프 데이터 모델링 및 효율적인 쿼리 실행에 중점을 둡니다. 갤러리 스키마의 구성은 다음 공식으로 표현할 수 있습니다.
janusgraph 스키마 = 정점 레이블 + 가장자리 레이블 + 속성 키
여기서 속성 키는 일반적으로 그래프 인덱스에 사용된다는 점에 주목할 가치가 있습니다.
더 나은 그래프 쿼리 성능을 달성하기 위해 janusgraph는 인덱스를 그래프 인덱스와 정점 중심 인덱스로 구분합니다. 그래프 인덱스에는 복합 인덱스와 혼합 인덱스가 있습니다.
결합 인덱스는 동일 검색으로 제한됩니다. (결합 인덱스는 외부 인덱스 백엔드를 구성할 필요가 없으며 메인 스토리지 백엔드에서 지원됩니다(물론 hbase, Cassandra, Berkeley도 구성 가능))
예:
<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">mgmt</span>.<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">buildIndex</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'byNameAndAgeComposite'</span>, <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">Vertex</span>.<span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">class</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">addKey</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">name</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">addKey</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">age</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">buildCompositeIndex</span>() <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">#构建一个组合索引“name</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">-</span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">age”</span><br><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">g</span>.<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">V</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'age'</span>, <span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">30</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'name'</span>, <span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'小明'</span>)<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">#查找</span> <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">名字为小明年龄30的节点</span>
하이브리드 인덱스에는 백엔드로 ES가 필요합니다 동일 다중 조건 쿼리 이외의 지원을 위한 인덱스(동일 쿼리도 지원되지만 동일 쿼리와 결합 인덱스가 더 빠릅니다). 단어 분할 필요 여부에 따라 전체 텍스트 검색과 문자열 검색으로 구분됩니다
야누스그래프가 데이터를 저장하는 방식을 이해하면 라이브러리를 더 잘 활용하는 데 도움이 됩니다. JanusGraph는 그래프를 인접 목록 형식으로 저장합니다. 즉, 그래프는 정점과 해당 인접 목록의 모음으로 저장됩니다.
꼭짓점의 인접 목록에는 꼭짓점의 모든 입사 가장자리(및 속성)가 포함됩니다.
JanusGraph는 각 인접 목록을 기본 스토리지 백엔드에 행으로 저장합니다. (64비트) 정점 ID(JanusGraph에 의해 각 정점에 고유하게 할당됨)는 정점의 인접 목록이 포함된 행을 가리키는 키입니다.
각 모서리와 속성은 행에서 별도의 셀로 저장되므로 효율적인 삽입과 삭제가 가능합니다. 따라서 특정 스토리지 백엔드에서 행당 허용되는 최대 셀 수는 JanusGraph가 해당 백엔드에 대해 지원할 수 있는 최대 정점 수준이기도 합니다.
스토리지 백엔드가 키 순서를 지원하는 경우 인접 목록은 정점 ID별로 정렬되며 JanusGraph는 정점 ID를 할당하여 그래프를 효과적으로 분할할 수 있습니다. 자주 방문하는 정점이 절대차가 작은 ID를 갖도록 ID를 할당합니다.
Janusgraph는 그래프 검색에 gremlin 언어를 사용합니다. 우리는 통합 그래프 쿼리 서비스를 제공합니다. 외부 사용자는 Gremlin 언어의 특정 구현에 신경 쓸 필요가 없으며 쿼리를 위해 공통 인터페이스를 사용합니다. 조건 검색 인터페이스, 노드 중심 외부 쿼리 인터페이스, 노드 간 경로 쿼리 인터페이스의 세 가지 인터페이스로 나눕니다. 다음은 그렘린 구현의 몇 가지 예입니다.
<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">g</span>.<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">V</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'price'</span>,<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">gt</span>(<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">8</span>)).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'price'</span>,<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">lt</span>(<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">12</span>)).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">order</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">by</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'sales'</span>,<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">desc</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">valueMap</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">limit</span>(<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">1</span>)
출력:
<span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">==></span>{<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">name</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span>[<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xuanyi</span>], <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">price</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span>[<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">10</span>], <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">sales</span><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">=</span>[<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">45767</span>]}
Sylphy의 판매량이 가장 높은 45767
<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">g</span>.<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">V</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xiaoming</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">repeat</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">out</span>()).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">times</span>(<span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">2</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">valueMap</span>()
<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">g</span>.<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">V</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xiaoming</span>).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">repeat</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">out</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">simplePath</span>()).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">until</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">or</span>(<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">"car"</span>,<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'name'</span>, <span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'kaluola'</span>),<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">has</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">"car"</span>, <span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'name'</span>,<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">'xuanyi'</span>))).<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">path</span>().<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">by</span>(<span style="color: rgb(102, 153, 0); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">"name"</span>)
Output
<span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">==></span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">path</span>[<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xiaoming</span>, <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">around</span> <span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">10</span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">w</span>, <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">kaluola</span>]<br><span style="color: rgb(215, 58, 73); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">==></span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">path</span>[<span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xiaoming</span>, <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">around</span> <span style="color: rgb(0, 92, 197); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">10</span><span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">w</span>, <span style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">xuanyi</span>]
Xiao Ming과 이 두 기사 사이에 "약 100,000"개의 노드가 있는 것으로 확인되었습니다
지식 그래프에는 많은 양의 비유럽 데이터가 있습니다. KG 기반 추천 애플리케이션은 비유럽 데이터를 효과적으로 사용하여 추천 시스템의 정확성을 향상시킵니다. 기존 시스템이 달성할 수 없는 효과를 달성하기 위한 추천 시스템입니다. KG 기반 추천은 KG 표현 기술(KGE), 경로 기반 방법, 그래프 신경망을 기반으로 하는 세 가지 범주로 나눌 수 있습니다. 이 장에서는 콜드 스타트, 이유, 추천 시스템 순위 등 세 가지 측면에서 KG의 애플리케이션과 논문을 소개합니다.
지식 그래프는 사용자-항목 상호 작용에서 KG에 숨겨진 고차 관계를 모델링할 수 있으며, 이는 사용자가 제한된 수의 행동 속성을 호출하여 발생하는 데이터 희소성을 잘 해결할 수 있습니다. , 콜드 스타트 문제를 해결하기 위해 적용될 수 있습니다. 업계에서도 이 문제에 관한 관련 연구들이 있습니다.
Sang et al.은 KG 컨텍스트와 사용자 항목 상호 작용 권장 사항의 장기적인 관계 종속성을 활용하는 Knowledge Graph Enhanced Residual Recurrent Neural Collaborative Filtering(KGNCF-RRN)이라는 이중 채널 신경 상호 작용 방법을 제안했습니다. .
(1) KG 상황별 상호작용 채널의 경우 상황 기반 경로 임베딩을 구성하기 위해 RRN(Residual Recurrent Network)을 제안하고, 잔여 학습은 기존 RNN(Recurrent Neural Network)에 통합되어 장기적으로 효과적으로 인코딩합니다. KG 관계 의존성. 그런 다음 Self-attention 네트워크를 경로 임베딩에 적용하여 다양한 사용자 상호 작용 동작의 모호성을 포착합니다.
(2) 사용자-항목 상호작용 채널의 경우 사용자 및 항목 임베딩이 새로 설계된 2D 상호작용 그래프에 입력됩니다.
(3) 마지막으로 이중 채널 신경 상호 작용 매트릭스 위에 컨벌루션 신경망을 사용하여 사용자와 항목 간의 복잡한 상관 관계를 학습합니다. 이 방법은 풍부한 의미 정보를 캡처할 수 있으며 사용자와 추천 항목 간의 복잡한 암시적 관계도 캡처할 수 있습니다.
Du Y et al. [7]은 협업 인식 메타 학습자와 지식 인식 메타 학습자를 포함하여 사용자 선호도와 엔터티 콜드 스타트 지식을 포착하는 메타 학습 프레임워크 MetaKG를 기반으로 콜드 스타트 문제에 대한 새로운 솔루션을 제안했습니다. . 협업 인식 메타 학습자 학습 작업은 각 사용자가 선호하는 지식 표현을 집계하는 것을 목표로 합니다. 대조적으로, 지식 인식 메타 학습자 학습 작업은 사용자가 선호하는 다양한 지식 표현을 전체적으로 일반화하는 것입니다. 두 명의 학습자의 지도하에 MetaKG는 고차원적인 협력 관계와 의미론적 표현을 효과적으로 포착할 수 있으며 콜드 스타트 시나리오에 쉽게 적응할 수 있습니다. 또한, 저자는 모델이 노이즈 정보에 의해 간섭되는 것을 방지하기 위해 학습을 위한 KG 정보를 적응적으로 선택할 수 있는 적응형 작업도 설계했습니다. MetaKG 아키텍처는 아래 그림에 나와 있습니다.
추천 이유는 추천 시스템의 해석성을 향상시켜 사용자가 추천 결과 생성 계산 과정을 이해할 수 있도록 하며, 추천 이유를 설명할 수도 있습니다. 아이템의 인기. 사용자는 추천 이유를 통해 추천 결과를 생성하는 원리를 이해하며, 이를 통해 시스템의 추천 결과에 대한 사용자의 신뢰도를 높이고 추천 오류가 발생한 경우 잘못된 결과에 대한 관용을 높일 수 있습니다.
최초의 해석 가능한 추천은 템플릿을 기반으로 했습니다. 템플릿의 장점은 가독성과 높은 정확성을 보장한다는 것입니다. 그러나 템플릿을 수동으로 정렬해야 하고 그다지 일반적이지 않아 사람들에게 반복적인 느낌을 줍니다. 나중에 사전 설정이 필요하지 않은 자유 형식이 개발되고 경로 중 하나를 설명으로 사용하여 지식 그래프가 추가되었으며 주석을 사용하여 선택된 각 점 또는 모서리와 결합된 몇 가지 생성 방법이 있었습니다. 모델에는 사용자에게 보여줄 수 있는 추론 프로세스가 있습니다. 최근 Chen Z [8] 등은 추천 예측, 설명 생성 및 사용자 피드백 통합 간의 긴밀한 협력을 달성할 수 있는 점진적 다중 작업 학습 프레임워크 ECR을 제안했습니다. 두 부분으로 구성됩니다. 첫 번째 부분인 Incremental Cross Knowledge Modeling에서는 추천과제와 설명과제에서 전달된 교차지식을 학습하고, 증분학습을 통해 업데이트할 교차지식을 활용하는 방법을 설명한다. 두 번째 부분인 증분 다중 작업 예측에서는 교차 지식을 기반으로 설명을 생성하는 방법과 교차 지식 및 사용자 피드백을 기반으로 추천 점수를 예측하는 방법을 설명합니다.
KG는 서로 다른 속성을 가진 항목을 연결하여 사용자 항목 간의 상호 작용을 설정하고 uesr 항목 그래프와 KG를 하나의 큰 그림으로 결합할 수 있습니다. 항목 간의 관계. 전통적인 추천 방법은 지도 학습 작업으로 문제를 모델링하는 것입니다. 이 방법은 항목 간의 본질적인 관계(예: Camry와 Accord 간의 경쟁 제품 관계)를 무시하고 사용자 행동에서 시너지 신호를 얻을 수 없습니다. 추천순위에 KG를 적용한 논문 2편을 소개합니다.
Wang[9] 등은 먼저 GNN을 사용하여 임베딩을 반복적으로 전파하고 업데이트하여 고차 연결을 빠르게 캡처할 수 있습니다. 두 번째로 집계 중에 주의 메커니즘을 사용하여 특성을 학습합니다. 전파 프로세스 중 각 이웃의 가중치는 고차 연결의 중요성을 반영합니다. 마지막으로 N차 전파 업데이트를 통해 사용자 항목의 암시적 표현이 얻어지며, 서로 다른 계층은 서로 다른 연결 정보 순서를 나타냅니다. KGAT는 더욱 풍부하고 불특정한 고차 연결을 포착할 수 있습니다.
Zhang[20] 등은 관심 전파라는 핵심 아이디어인 RippleNet 모델을 제안했습니다. RippleNet은 사용자의 역사적 관심을 KG의 시드 세트로 사용한 다음 연결을 따라 사용자의 관심을 외부로 확장합니다. KG에 대한 사용자의 관심 분포를 형성합니다. RippleNet의 가장 큰 장점은 메타 경로나 메타 그래프를 수동으로 설계하지 않고도 사용자가 히스토리에서 클릭한 항목부터 후보 항목까지 가능한 경로를 자동으로 마이닝할 수 있다는 점입니다.
RippleNet은 사용자 U와 항목 V를 입력으로 사용하고 사용자 U가 항목 V를 클릭할 예측 확률을 출력합니다. 사용자 U의 경우 역사적 관심도 V_{u}를 시드(seed)로 하여 초기 시작점이 2이고 이후 주변으로 계속 확산되는 것을 그림에서 볼 수 있다. itemV와 사용자 U의 1-홉 리플 집합 V_{u_{}^{1}}의 각 트리플 left(h_{i},r_{i},t_{i}right)가 주어지면 V를 비교하여 관련 확률 할당 노드 h_{i} 및 관계 r_{i}에 트리플로 적용됩니다.
관련 확률을 얻은 후 V_{u_{}^{1}}에 있는 트리플의 꼬리에 가중 합계에 대한 해당 관련 확률을 곱하여 사용자 U의 1차 역사적 관심도를 얻습니다. to V 이에 대한 응답으로 사용자의 관심은 V_{u}에서 o_{u}^{1}로 이동하며 이는 o_{u}^{2}, o_{u}^{3}...로 계산할 수 있습니다. o_{u}^{n }, 그러면 품목 V에 대한 U의 특성을 계산하여 그의 모든 주문 응답을 융합할 수 있습니다.
결론적으로는 추천 중심으로 그래프 구성의 세부 과정을 소개하고, 그에 따른 어려움과 과제를 분석했습니다. 동시에 많은 중요한 작업을 요약하고 구체적인 솔루션, 아이디어 및 제안을 제공합니다. 마지막으로 지식 그래프를 포함한 애플리케이션을 소개하며, 특히 콜드 스타트, 해석성, 회상 순위 등 추천 분야에서 지식 그래프의 역할과 활용을 소개한다.
인용:
[1] 김S, 오SG. 온톨로지 품질 평가를 위한 평가 기준 추출 및 적용[J]. Library Hi Tech, 2019.
[2]Protege: https://www.php.cn/link/9d405c24be657bbf7a5244815a908922
[3] Ding S , Shang J , Wang S , 외 . ERNIE-DOC: 회고적 장기 문서 모델링 변환기[J]. 2020.
[4]DocBert,[1] Adhikari A, Ram A, Tang R,et al. 2019.
[5]JanusGraph,https://www.php.cn/link/fc0de4e0396fff257ea362983c2dda5a
[6] Sang L, Xu M, Qian S, et al. 잔여 순환 네트워크를 사용한 신경 협업 필터링[J]. Neurocomputing, 2021, 454: 417-429.
[7] Du Y, Zhu X, Chen L, et al. MetaKG: Cold-start를 위한 지식 그래프에 대한 메타 학습 Recommendation[J]. arXiv e-prints, 2022.
[8] Chen Z , Wang X , Xie X 등 Rim International Conference on Artificial Intelligence {IJCAI-PRICAI-20.2020.
[9] Wang X , He X , Cao Y , et al.: Knowledge Graph Attention Network for Recommendation[J], 2019.
[10]Wang H, Zhang F, Wang J 등 RippleNet: 추천 시스템에 대한 지식 그래프에 사용자 선호도 전파[J], 2018.
위 내용은 추천을 위한 자동차 지식 그래프 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!