scikit, old haskell code
Table of Contents
AIイライザ
AIイライザ (by NHK) なんてのをやってた(23081606)。元記事は7月なんで、再放送か。そしてリン クが無くなる(らしい)ので、バックアップ 「イライザ」は男性を追いやったのか?
ググるの生成AIは、進化しすぎて、あまりに人間くさくなり、警告の論文を発 表した従業員は、解雇されてしまったらしい。こわい世界になったものだ。
生臭い話ばかりだと、辟易するので、 絵本のなかの動物はなぜ一列に歩いているのか こういうのを手にしてみた。これ、きっとチコちゃんで取り上げられるぞ。 答の前の頓珍漢な回答者風に、それは序列を表わしているに違いない。 いや、それは違うだろう。
素直にconsした順番さ、consは基本演算なので、何 処にも有るよ。いや、この場合はappendさ れた順番だよ、体育系のクラブなんかだと新人はパシリって事で、最後尾に来 るぞ。いや、追加される度に、ソートされるのさ。ソート時の注目は、身長だっ たり体重だったり色々だろうけど。Ord出来る型ならOK。喧喧諤諤だな。 さて、正解をじっくりと楽しんでみるか。
scikit-learn
前回の、rubyをpythonと誤認した問題を、談判してみた。その、最後のやり とり。
Q: 根拠がなくrubyと言う名前が出てくるのは、不思議です。適当にユーザー からの応答を盗む、イライザみたいに動いているんですか?
A: 申し訳ありませんが、私はユーザーからの応答を盗むことはありませんし、意図的に誤った情報を提供することもありません。私の目的は、ユーザーの質問やリクエストに対してできる限り正確で有益な情報を提供することです。
以前の回答が誤りであり、混乱を招く結果となりました。ユーザーからのご質問に対して真摯に回答することが重要であり、それに失敗したことをお詫び申し上げます。不明確な情報を提供してしまったことについて、深く反省しております。
わざと怒りを買う発言をして、本心を引き出す作戦。捜査一課の、おとしの◯ ◯刑事のテクニック。
でも相手はひたすら平身低頭で 嵐が過ぎるのを、じっと耐えております。肝心な事は、企業秘密なので、 絶対に口を割りませんでした。心の中ではきっと、アカンベェーしてる事でしょ う。これ以上クレーマーを続けると、出禁になりそうなので、取り調べは中止 する。
変わりに、公正な所で、勝負をしてみる。
言語判定機
scikit-learnを使って、ファイル(test.txt)の内容が、どんなプログラミング言語用の ソースコードか判定するプログラムを作ってください。 なお、ファイル中には、公平を期すため、全てのコメントは、削除されています。 必要な要件がありましたら、事前に提示してください。
事前に提示と下手に出たのは、教師有り学習で、大量の正解データが必要とな るかもって、予想したからだ。が、そんなのは必要無いみたいだった。
もちろんです。scikit-learnを使用して、与えられたテキストファイルの内容がどのプログラミング言語用のソースコードかを判定するプログラムを以下に示します。以下のコードはPython言語で記述されています。
import numpy as np from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import make_pipeline # データの読み込み file_path = 'test.txt' with open(file_path, 'r') as file: source_code = file.read() # 訓練データ # ここでは3つのプログラミング言語(Python、Java、C++)を想定しています training_data = { 'python': ['print', 'def', 'import', 'for', 'if', 'while', 'return'], 'java': ['public', 'class', 'static', 'void', 'main', 'new', 'return'], 'cpp': ['#include', 'int', 'main', 'cout', 'cin', 'namespace', 'return'] } # 訓練データのラベルとテキストデータを生成 labels = [] texts = [] for label, keywords in training_data.items(): labels.extend([label] * len(keywords)) texts.extend(keywords) # モデルの構築 model = make_pipeline(CountVectorizer(vocabulary=texts), MultinomialNB()) # モデルの訓練 model.fit(texts, labels) # テストデータの作成(与えられたファイルの内容) test_data = [source_code] # テストデータの予測 predicted_language = model.predict(test_data)[0] print(f"The source code is written in: {predicted_language}")
上記のコードは、与えられたテキストファイル(`test.txt`)の内容を読み込み、訓練データとして定義されたキーワードを使用して、Naive Bayes分類器を使ってプログラミング言語を判定します。訓練データはPython、Java、C++を対象にしていますが、他の言語を追加することも可能です。ただし、この方法は単純なキーワードの出現頻度に基づいて判定するため、高度な言語特徴を考慮する場合は、より複雑なアプローチが必要です。
これって、スパム検出機そのものじゃん。その手が有ったんだね。思いもしな い方法だな。
それにしても、ずるいなあ。全く性格の違う言語を選んでいるよ。まあ、自分の都合の良い様 に振る舞うのは、人間もAIも一緒って事か。
この簡単なコードでも核心部分は闇の中。素人が手出しなんて簡単には出来無 いのさ。これがAIってもんです。
単純ベイズ分類器 例によって歯がたたない解説、理解できるようになりたい 脳。
機械学習入門者向け Naive Bayes(単純ベイズ)アルゴリズムに触れてみる
統計学の時間 結局は基礎を固めろって事だな。
debug?
(mypy) [sakae@arch tmp]$ python3 code.py Traceback (most recent call last): : File "/tmp/mypy/lib/python3.11/site-packages/sklearn/feature_extraction/text.py", line 1367, in fit_transform self._validate_vocabulary() File "/tmp/mypy/lib/python3.11/site-packages/sklearn/feature_extraction/text.py", line 483, in _validate_vocabulary raise ValueError(msg) ValueError: Duplicate term in vocabulary: 'return'
類似テキスト検索 とかを調べても解決の兆しは見えず。
聞くは一時の恥、聞かぬは末代の恥 って、祖母が言ってたな。
このエラーは、テキストデータをベクトル化する際に、語彙(vocabulary)に重複した単語が含まれていることが原因です。この問題を解決するためには、訓練データのテキストに重複する単語が含まれていることを確認し、それらの単語を除外するか、適切に処理する必要があります。
上記のエラーが発生している原因は、訓練データのテキストデータにおいて、'return' という単語が複数回出現しているためです。CountVectorizerは、各単語を特徴として考え、その単語の出現頻度をベクトル化する際に語彙を構築します。そのため、同じ単語が複数回語彙に登録されることは許されません。
訓練データのテキストを調整して、重複する単語を削除するか、重複した単語に対して適切な処理を行ってください。もしくは、テキストデータをより適切な形式で前処理することでこの問題を回避することができるかもしれません。
ちょいと言い訳しとく。エラーの最後に、Duplicate .. 'return' がでてたの で、そのreturnに目がくらんで、system側を疑ってしまってた。素直にエラー を解釈しろよな。pythonにビビルんじゃないよ。
(mypy) [sakae@arch tmp]$ python3 code.py The source code is written in: python
手堅く自分自身を診断。これだけじゃつまらん。判定の自信度を表示してってお願い
# テストデータの予測確率を取得 predicted_probs = model.predict_proba(test_data) # 各クラスの予測確率を表示 predicted_classes = model.classes_ for language, prob in zip(predicted_classes, predicted_probs[0]): print(f"{language}: {prob:.2%}")
答は、
cpp: 4.09% java: 1.70% python: 94.20%
だっちゃ、なんかプラモデルみたいで、やってて、つまらないな。
重複を許しても、エラーにしない方法。内部で集合を作成して、重複を削除。 つまらないエラー除けのおまじない。
# 訓練データの語彙を重複を許して構築 unique_texts = list(set(texts)) # 重複を削除 model = make_pipeline(CountVectorizer(vocabulary=unique_texts), MultinomialNB())
なお、rubyコードを咀嚼させると、
cpp: 14.15% java: 2.95% python: 82.91%
今度も、前回の C# を、再利用します。javaの親戚って言うかな?
cpp: 100.00% java: 0.00% python: 0.00%
あら、cppに100%互換ですって断言してるよ。C#ってjava撲滅言語と思ってい たけど、実際は、 C#の登場~Javaとの対立の構図 こういう立ち位置なのね。で、このAIに対して、どうしてcppと判定したんで すかって聞いてみると、、、答られないわな。説明責任を放棄してると言われ るな。これが今回ChatGPTの口を割らせようとしても拒否してきた理由か。 答たくても答られない闇が存在する理由なんだな。
昔、八甲田山に春スキーに行ったのよ。その時、青森駅前の市場で、食料って か酒のつまみとして、ほたて貝やら干物を仕入れた。対応してくれた、おばちゃ んの津軽弁がきつくて、全く理解できなかった。心底、英語でいいから、しゃ べってくれと思ったぞ。地方をどさ回りもしたけど、薩摩弁も理解不能だった な。両者共、日本語族なんだけどもね。
ああ、ある人に言わせると、津軽弁は雰囲気がフランス語っぽいとの事だ。 上の判定は、ある部分だけを捉えているんで、とんでもない誤解な回答をする な。
haskell-stats
haskellに統計してもらうのをChatGPTにお願いしたけど、昔に自力でやった記 憶があるぞ。探してみたら、2015年の暮れにやってた。
むかしはAIなんて無いから、頭を捻ってやってたのね。堕落したって事かな? それとも時流に上手くのってる、ナウイおじさん、かな? まあ、どっちでも エエワイ。
家庭教師なんて知らなかったので、とりあえず雇ってみた。
[sakae@deb hs-oldstats]$ hlint app/Main.hs : app/Main.hs:17:15-26: Suggestion: Redundant bracket Found: x !! (fromEnum k) Perhaps: x !! fromEnum k : app/Main.hs:29:19-34: Suggestion: Avoid lambda using `infix` Found: (\ x -> x /= '.') Perhaps: (/= '.') : app/Main.hs:(54,11)-(55,74): Suggestion: Move brackets to avoid $ Found: (fi $ maximum cs) ++ (ff $ (/) (fromIntegral (sum cs)) (fromIntegral (length cs))) Perhaps: fi (maximum cs) ++ (ff $ (/) (fromIntegral (sum cs)) (fromIntegral (length cs)))
など、17箇所も添削されたぞ。昔は未熟だったのね。
次はChatGPTが提案してきた形に変更してみよう。
data Rec = Rec { ymd :: String , hi :: Int , lo :: Int , pl :: Int } deriving (Show, Eq, Read, Ord)
CSVなデータはymdhなんで、それを分解する方法を再確認。
ghci> splitAt 6 s ("123456","78")
次は、readCSVする時、am,pmに分解して取り出す。分解した時は、もう測定時 間は必要ないからね。
readCSV :: ([Rec], [Rec])
??
ここまでは、いいんだけど、元のやつは、mapしてる。それじゃ困るんだけど な。とっさに思い付いたのは、unzip。どうなってるか?
unzip :: [(a,b)] -> ([a],[b]) unzip = foldr (\(a,b) ~(as,bs) -> (a:as, b:bs)) ([], [])
想像した通り、foldで畳み込んでいる。ここに出てくるチルダは何? Haskell/GHC symbol search cheatsheet 経由で irrefutable Pattern(不可反駁パターン)とは…? へ到着。追加したい値(a,b)はリストをスキャンした奴と、それに対応する累 積データ。そして、それらをconsしなさいとな。
恥晒しなコード
-- new bld stats data Rec = Rec { ymd :: String , hi :: Int , lo :: Int , pl :: Int } deriving (Show, Eq, Read, Ord) isCmm :: Char -> Bool isCmm c = c == ',' sepCm :: String -> [String] sepCm s = case dropWhile isCmm s of "" -> [] s' -> w : sepCm s'' where (w,s'') = break isCmm s' csvRead :: IO ([Rec], [Rec]) csvRead = do al <- readFile "current.csv" return $ foldr ampm ([], []) (lines al) where ampm ln = case sepCm ln of [ymdh, hi, lo, pl] -> if (h <= "12" ) then ((Rec ymd (read hi) (read lo) (read pl)), (Rec "z" 0 0 0)) else ((Rec "z" 0 0 0), (Rec ymd (read hi) (read lo) (read pl))) where (ymd, h) = splitAt 6 ymdh _ -> error "Invalid CSV line format" main :: IO () main = undefined
データは読むまで、午前か午後か分からない。そう、有名な思考実験である、 シュレティガーの猫状態。それが読んだ途端に、どちらかに確定する。量子力 学であります。ampmが正に蓋を開く行為になる。 で、分類して格納するんだけど、必ずペアーになっていないといけない。双子 なんとかって言うんかな。格好悪いけど、ダミーを格納。 これでいいかと、思ったら、
app/Main.hs:21:18: error: • Couldn't match type: (Rec, Rec) with: ([Rec], [Rec]) -> ([Rec], [Rec]) Expected: String -> ([Rec], [Rec]) -> ([Rec], [Rec]) Actual: String -> (Rec, Rec) • In the first argument of ‘foldr’, namely ‘ampm’ In the second argument of ‘($)’, namely ‘foldr ampm ([], []) (lines al)’ In a stmt of a 'do' block: return $ foldr ampm ([], []) (lines al) | 21 | return $ foldr ampm ([], []) (lines al) | ^^^^
量子力学って難解だな。
頭を冷して、新理論で試してみよう。