<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Openai-Embeddings on Xainome Blog</title><link>https://xainome-blog.beeskynohito.workers.dev/tags/openai-embeddings/</link><description>Recent content in Openai-Embeddings on Xainome Blog</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Fri, 12 Apr 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://xainome-blog.beeskynohito.workers.dev/tags/openai-embeddings/index.xml" rel="self" type="application/rss+xml"/><item><title>RAGを開発してみたい！ので簡単なものでもいいので作ってみよう！part2</title><link>https://xainome-blog.beeskynohito.workers.dev/posts/2024/04/build-rag-app-part-2/</link><pubDate>Fri, 12 Apr 2024 00:00:00 +0000</pubDate><guid>https://xainome-blog.beeskynohito.workers.dev/posts/2024/04/build-rag-app-part-2/</guid><description>&lt;p>このpartで基本が8割がた作れました。内容としては簡単な質問をすると&amp;quot;タイトル&amp;quot;と&amp;quot;内容&amp;quot;が返ってくる程度です。まだまだ理想には遠いですね。&lt;/p>
&lt;p>前回やったのは&lt;/p>
&lt;ul>
&lt;li>
&lt;p>PDFファイル読み込み&lt;/p>
&lt;/li>
&lt;li>
&lt;p>ページ番号取得と削除&lt;/p>
&lt;/li>
&lt;li>
&lt;p>色んな空白を削除&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>今回行ったのは&lt;/p>
&lt;ul>
&lt;li>
&lt;p>特殊文字の削除&lt;/p>
&lt;/li>
&lt;li>
&lt;p>大文字小文字統一&lt;/p>
&lt;/li>
&lt;li>
&lt;p>ベクトル変換&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>この辺も全てChat-GPT任せでした。特殊文字に関してはURLとメールアドレス、特殊文字の削除になります。まあ私が扱ってるものの中にURLやメールアドレスはあまりなさそうですが、一般的には必要だと思います。&lt;/p>
&lt;pre tabindex="0">&lt;code>text = re.sub(r&amp;#39;http[s]?://\S+&amp;#39;, &amp;#39;&amp;#39;, text)
text = re.sub(r&amp;#39;\S*@\S*\s?&amp;#39;, &amp;#39;&amp;#39;, text)
text = re.sub(r&amp;#39;[!#\$%&amp;amp;\&amp;#39;()*+,\-./:;&amp;lt;=&amp;gt;?@\[\\\]^_`{|}~]&amp;#39;, &amp;#39;&amp;#39;, text)
&lt;/code>&lt;/pre>&lt;p>次は大文字小文字の統一ですね。これが少し特殊ですが例えば &amp;ldquo;１２３ａｂｃｱｲｳｴｵ①②③¹²³&amp;quot;という文字があった時に&amp;quot;123abcアイウエオ123123&amp;quot;となるように変換しています。これもあまり使われてないと思いますが、一応変換しています。&lt;/p>
&lt;pre tabindex="0">&lt;code>normalized_text = &amp;#39;&amp;#39;.join([unicodedata.normalize(&amp;#39;NFKC&amp;#39;, char) if not unicodedata.east_asian_width(char) in (&amp;#39;F&amp;#39;, &amp;#39;W&amp;#39;, &amp;#39;A&amp;#39;) else char for char in text])
&lt;/code>&lt;/pre>&lt;p>それからベクトル変換ですね。OpenAIの埋め込みベクトルに変換していきます。課金が必要なので他のやり方がないか考えたいところですが、簡単に実装するために使用します。いつかはTF-IDFかWord2Vecを使ってみたいです。&lt;/p>
&lt;pre tabindex="0">&lt;code>openai.api_key = os.environ[&amp;#39;OPENAI_API_KEY&amp;#39;]
vector_database.append({
&amp;#39;title&amp;#39;: filename,
&amp;#39;body&amp;#39;: text,
&amp;#39;embedding&amp;#39;: vector
})
&lt;/code>&lt;/pre>&lt;p>課金といっても10000字くらい埋め込みベクトルに使っても0.01$もかかりませんので数円くらいならお試しで触ってみてください。&lt;/p>
&lt;p>一つだけ注意点を話すと8192トークンまでしか入力として受け取れないので、もし文字数が多くなる場合は分割して、それぞれの平均を取るといいかと思います。私の場合はとりあえず7000文字くらいで分割しています。&lt;/p>
&lt;pre tabindex="0">&lt;code>for i in range(0, len(text), max_tokens): # max_tokens=7000
segment = text[i:i+max_tokens]
res = openai.embeddings.create(
model=&amp;#39;text-embedding-3-large&amp;#39;,
input=segment
)
vectors.append(res.data[0].embedding)
average_vector = np.mean(vectors, axis=0).tolist()
&lt;/code>&lt;/pre>&lt;p>そういえばいつからかはわかりませんが埋め込みベクトルの数値を取り出す方法が変わってたみたいで、&amp;lsquo;res[data][0][embedding]&amp;rsquo; から &amp;lsquo;res.data[0].embedding&amp;rsquo;に変わっています。前の方法が良ければバージョンを下げていただければ大丈夫です。&lt;/p></description></item></channel></rss>