我正在尝试创建一个多类混淆矩阵,但是,执行过程中出现错误“维度太大”,有什么办法可以解决这个问题吗?
\documentclass[tikz]{standalone}
\usepackage{ifthen}
\usetikzlibrary{matrix,calc}
\begin{document}
%The matrix in numbers
%Horizontal target class
%Vertical output class
\centering
\def\myConfMat{{
{5737,290,507,41,753,926,62}, %row 1
{3940,3411,5715,168,618,3692,829}, %row 2
{114,105,1392,5,159,377,352}, %row 3
{8,13,235,17448,1327,4138,269}, %row 4
{1467,37,456,790,39466,19298,312}, %row 5
{837,584 ,2817,5429,8891,36916,1737}, %row 6
{174,109,2289,959,1617,7091,2035}, %row 7
}}
\def\classNames{{"A","B","C","D","E","F","G"}} %class names. Adapt at will
\def\numClasses{7} %number of classes. Could be automatic, but you can change it for tests.
\def\myScale{1.2} % 1.5 is a good scale. Values under 1 may need smaller fonts!
\begin{tikzpicture}[
scale = \myScale,
%font={\scriptsize}, %for smaller scales, even \tiny may be useful
]
\tikzset{vertical label/.style={rotate=90,anchor=east}} % usable styles for below
\tikzset{diagonal label/.style={rotate=45,anchor=north east}}
\foreach \y in {1,...,\numClasses} %loop vertical starting on top
{
% Add class name on the left
\node [anchor=east] at (0.4,-\y) {\pgfmathparse{\classNames[\y-1]}\pgfmathresult};
\foreach \x in {1,...,\numClasses} %loop horizontal starting on left
{
%---- Start of automatic calculation of totSamples for the column ------------
\def\totSamples{0}
\foreach \ll in {1,...,\numClasses}
{
\pgfmathparse{\myConfMat[\ll-1][\x-1]} %fetch next element
\xdef\totSamples{\totSamples+\pgfmathresult} %accumulate it with previous sum
%must use \xdef fro global effect otherwise lost in foreach loop!
}
\pgfmathparse{\totSamples} \xdef\totSamples{\pgfmathresult} % put the final sum in variable
%---- End of automatic calculation of totSamples ----------------
\begin{scope}[shift={(\x,-\y)}]
\def\mVal{\myConfMat[\y-1][\x-1]} % The value at index y,x (-1 because of zero indexing)
\pgfmathtruncatemacro{\r}{\mVal} %
\pgfmathtruncatemacro{\p}{round(\r/\totSamples*100)}
\coordinate (C) at (0,0);
\ifthenelse{\p<50}{\def\txtcol{black}}{\def\txtcol{white}} %decide text color for contrast
\node[
draw, %draw lines
text=\txtcol, %text color (automatic for better contrast)
align=center, %align text inside cells (also for wrapping)
fill=black!\p, %intensity of fill (can change base color)
minimum size=\myScale*10mm, %cell size to fit the scale and integer dimensions (in cm)
inner sep=0, %remove all inner gaps to save space in small scales
] (C) {\r\\\p\%}; %text to put in cell (adapt at will)
%Now if last vertical class add its label at the bottom
\ifthenelse{\y=\numClasses}{
\node [] at ($(C)-(0,0.75)$) % can use vertical or diagonal label as option
{\pgfmathparse{\classNames[\x-1]}\pgfmathresult};}{}
\end{scope}
}
}
%Now add x and y labels on suitable coordinates
\coordinate (yaxis) at (-0.85,0.5-\numClasses/2); %must adapt if class labels are wider!
\coordinate (xaxis) at (0.5+\numClasses/2, -\numClasses-1.25); %id. for non horizontal labels!
\node [vertical label] at (yaxis) {Actual Class};
\node [] at (xaxis) {Predicted Class};
\end{tikzpicture}
\end{document}
答案1
由于 F. Pantigny 解释的原因,混淆矩阵不能按原样处理。
但是,在这种情况下,当数组中的所有元素都除以 10 时,每个元素和累计总数仍低于限制。
百分比的计算几乎是正确的。(由于截断,会出现一些精度损失)
对于最终结果,小数点被去掉了。
这种重正化(现在手工完成)应该预先对原始数据进行,并用适当的数字进行缩放。
\documentclass{article}
\usepackage{tikz}
\usepackage{ifthen}
\usetikzlibrary{matrix,calc}
\usepackage{xstring} % added to extract the . <<<<<
\begin{document}
%The matrix in numbers
%Horizontal target class
%Vertical output class
\centering
% \def\myConfMat{{
% {5737,290,507,41,753,926,62}, %row 1
% {3940,3411,5715,168,618,3692,829}, %row 2
% {114,105,1392,5,159,377,352}, %row 3
% {8,13,235,17448,1327,4138,269}, %row 4
% {1467,37,456,790,39466,19298,312}, %row 5
% {837,584 ,2817,5429,8891,36916,1737}, %row 6
% {174,109,2289,959,1617,7091,2035}, %row 7
% }}
\def\myConfMat{% divided by 10
{
{573.7,29.0,50.7,4.1,75.3,92.6,6.2}, %row 1
{394.0,341.1,571.5,16.8,61.8,369.2,82.9}, %row 2
{11.4,10.5,139.2,.5,15.9,37.7,35.2}, %row 3
{.8,1.3,23.5,1744.8,132.7,413.8,26.9}, %row 4
{146.7,3.7,45.6,79.0,946.6,1929.8,31.2}, %row 5
{83.7,58.4 ,281.7,542.9,889.1,3691.6,173.7}, %row 6
{17.4,10.9,228.9,95.9,161.7,709.1,203.5}, %row 7
}}
\def\classNames{{"A","B","C","D","E","F","G"}} %class names. Adapt at will
\def\numClasses{7} %number of classes. Could be automatic, but you can change it for tests.
\def\myScale{1.2} % 1.5 is a good scale. Values under 1 may need smaller fonts!
\begin{tikzpicture}[
scale = \myScale,
%font={\scriptsize}, %for smaller scales, even \tiny may be useful
]
\tikzset{vertical label/.style={rotate=90,anchor=east}} % usable styles for below
\tikzset{diagonal label/.style={rotate=45,anchor=north east}}
\foreach \y in {1,...,\numClasses} %loop vertical starting on top
{
% Add class name on the left
\node [anchor=east] at (0.4,-\y) {\pgfmathparse{\classNames[\y-1]}\pgfmathresult};
\foreach \x in {1,...,\numClasses} %loop horizontal starting on left
{
%---- Start of automatic calculation of totSamples for the column ------------
\pgfmathsetmacro{\totSamples}{0}
\foreach \ll in {1,...,\numClasses}
{
\pgfmathsetmacro{\tmp}{\totSamples+ \myConfMat[\ll-1][\x-1]} %accumulate it with previous
\global\let\totSamples\tmp% put the final sum in variable
}
%---- End of automatic calculation of totSamples ----------------
\begin{scope}[shift={(\x,-\y)}]
\pgfmathsetmacro{\r}{\myConfMat[\y-1][\x-1]} %
\pgfmathtruncatemacro{\p}{round(\r/\totSamples*100)}
\coordinate (C) at (0,0);
\ifthenelse{\p<50}{\def\txtcol{black}}{\def\txtcol{white}} %decide text color for contrast
\node[
draw, %draw lines
text=\txtcol, %text color (automatic for better contrast)
align=center, %align text inside cells (also for wrapping)
fill=black!\p, %intensity of fill (can change base color)
minimum size=\myScale*10mm, %cell size to fit the scale and integer dimensions (in cm)
inner sep=0, %remove all inner gaps to save space in small scales
] (C) {\StrSubstitute{\r}{.}{}\\\p\%}; %text to put in cell (adapt at will)
%Now if last vertical class add its label at the bottom
\ifthenelse{\y=\numClasses}{
\node [] at ($(C)-(0,0.75)$) % can use vertical or diagonal label as option
{\pgfmathparse{\classNames[\x-1]}\pgfmathresult};}{}
\end{scope}
}
}
%Now add x and y labels on suitable coordinates
\coordinate (yaxis) at (-0.85,0.5-\numClasses/2); %must adapt if class labels are wider!
\coordinate (xaxis) at (0.5+\numClasses/2, -\numClasses-1.25); %id. for non horizontal labels!
\node [vertical label] at (yaxis) {Actual Class};
\node [] at (xaxis) {Predicted Class};
\end{tikzpicture}
\end{document}
答案2
pgfmanual.pdf
在 PGF/Tikz ( ) 版本 3.1.4b 第 1011 页的文档中,我们读到:
需要注意的是,所有计算在任何时候都不能超过±16383.99999,因为底层计算依赖于 TEX 维度。
数组第四列的数字总和大于该值......
也许你应该尝试使用fpu
PGF/Tikz 文档中描述的或者使用expl3
(LaTeX3 的编程层)的浮点。