Во-первых, чтобы обеспечить полное раскрытие, я хочу отметить, что это связано с домашней работой в классе машинного обучения. Этот вопрос не является вопросом домашней работы, и мне нужно разобраться с ним, чтобы решить более сложную задачу создания алгоритма дерева решений ID3.
Мне нужно сгенерировать дерево, похожее на следующее, когда дана таблица истинности
let learnedTree = Node(0,"A0", Node(2,"A2", Leaf(0), Leaf(1)), Node(1,"A1", Node(2,"A2", Leaf(0), Leaf(1)), Leaf(0)))
learnTree имеет тип BinaryTree, который я определил следующим образом:
type BinaryTree =
| Leaf of int
| Node of int * string * BinaryTree * BinaryTree
Алгоритмы ID3 учитывают различные уравнения, чтобы определить, где разбить дерево, и я понял все, что у меня возникло, просто у меня возникают проблемы при создании изученного дерева из моей таблицы истинности. Например, если у меня есть следующая таблица
A1 | A2 | A3 | Class
1 0 0 1
0 1 0 1
0 0 0 0
1 0 1 0
0 0 0 0
1 1 0 1
0 1 1 0
И я решу разделить атрибут A1, в результате я получу следующее:
(A1 = 1) A1 (A1 = 0)
A2 | A3 | Class A2 | A3 | Class
0 0 1 1 0 1
0 1 0 0 0 0
1 0 1 0 0 0
0 1 1
Затем я разделил бы левую сторону и разделил правую сторону и продолжил рекурсивный шаблон, пока узлы листа не стали бы чистыми, и в результате я получил дерево, похожее на следующее, основанное на разбиении.
let learnedTree = Node(0,"A0", Node(2,"A2", Leaf(0), Leaf(1)), Node(1,"A1", Node(2,"A2", Leaf(0), Leaf(1)), Leaf(0)))
Вот то, что я вроде как "взломал" вместе до сих пор, но я думаю, что я могу быть далеко:
let rec createTree (listToSplit : list<list<float>>) index =
let leftSideSplit =
listToSplit |> List.choose (fun x -> if x.Item(index) = 1. then Some(x) else None)
let rightSideSplit =
listToSplit |> List.choose (fun x -> if x.Item(index) = 0. then Some(x) else None)
if leftSideSplit.Length > 0 then
let pureCheck = isListPure leftSideSplit
if pureCheck = 0 then
printfn "%s" "Pure left node class 0"
createTree leftSideSplit (index + 1)
else if pureCheck = 1 then
printfn "%s" "Pure left node class 1"
createTree leftSideSplit (index + 1)
else
printfn "%s - %A" "Recursing Left" leftSideSplit
createTree leftSideSplit (index + 1)
else printfn "%s" "Pure left node class 0"
Должен ли я вместо этого использовать сопоставление с образцом? Любые советы / идеи / помощь? Спасибо большое!